blob: 3bc2d0c226efa36a684fbbb82253ef891ee2958e [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Jeff Johnson295189b2012-06-20 16:38:30 -0700462static struct cfg80211_ops wlan_hdd_cfg80211_ops;
463
464/* Data rate 100KBPS based on IE Index */
465struct index_data_rate_type
466{
467 v_U8_t beacon_rate_index;
468 v_U16_t supported_rate[4];
469};
470
471/* 11B, 11G Rate table include Basic rate and Extended rate
472 The IDX field is the rate index
473 The HI field is the rate when RSSI is strong or being ignored
474 (in this case we report actual rate)
475 The MID field is the rate when RSSI is moderate
476 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
477 The LO field is the rate when RSSI is low
478 (in this case we don't report rates, actual current rate used)
479 */
480static const struct
481{
482 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700484} supported_data_rate[] =
485{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700486/* IDX HI HM LM LO (RSSI-based index */
487 {2, { 10, 10, 10, 0}},
488 {4, { 20, 20, 10, 0}},
489 {11, { 55, 20, 10, 0}},
490 {12, { 60, 55, 20, 0}},
491 {18, { 90, 55, 20, 0}},
492 {22, {110, 55, 20, 0}},
493 {24, {120, 90, 60, 0}},
494 {36, {180, 120, 60, 0}},
495 {44, {220, 180, 60, 0}},
496 {48, {240, 180, 90, 0}},
497 {66, {330, 180, 90, 0}},
498 {72, {360, 240, 90, 0}},
499 {96, {480, 240, 120, 0}},
500 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700501};
502
503/* MCS Based rate table */
504static struct index_data_rate_type supported_mcs_rate[] =
505{
506/* MCS L20 L40 S20 S40 */
507 {0, {65, 135, 72, 150}},
508 {1, {130, 270, 144, 300}},
509 {2, {195, 405, 217, 450}},
510 {3, {260, 540, 289, 600}},
511 {4, {390, 810, 433, 900}},
512 {5, {520, 1080, 578, 1200}},
513 {6, {585, 1215, 650, 1350}},
514 {7, {650, 1350, 722, 1500}}
515};
516
Leo Chang6f8870f2013-03-26 18:11:36 -0700517#ifdef WLAN_FEATURE_11AC
518
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530519#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700520
521struct index_vht_data_rate_type
522{
523 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524 v_U16_t supported_VHT80_rate[2];
525 v_U16_t supported_VHT40_rate[2];
526 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700527};
528
529typedef enum
530{
531 DATA_RATE_11AC_MAX_MCS_7,
532 DATA_RATE_11AC_MAX_MCS_8,
533 DATA_RATE_11AC_MAX_MCS_9,
534 DATA_RATE_11AC_MAX_MCS_NA
535} eDataRate11ACMaxMcs;
536
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530537/* SSID broadcast type */
538typedef enum eSSIDBcastType
539{
540 eBCAST_UNKNOWN = 0,
541 eBCAST_NORMAL = 1,
542 eBCAST_HIDDEN = 2,
543} tSSIDBcastType;
544
Leo Chang6f8870f2013-03-26 18:11:36 -0700545/* MCS Based VHT rate table */
546static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
547{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530548/* MCS L80 S80 L40 S40 L20 S40*/
549 {0, {293, 325}, {135, 150}, {65, 72}},
550 {1, {585, 650}, {270, 300}, {130, 144}},
551 {2, {878, 975}, {405, 450}, {195, 217}},
552 {3, {1170, 1300}, {540, 600}, {260, 289}},
553 {4, {1755, 1950}, {810, 900}, {390, 433}},
554 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
555 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
556 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
557 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
558 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700559};
560#endif /* WLAN_FEATURE_11AC */
561
c_hpothu79aab322014-07-14 21:11:01 +0530562/*array index points to MCS and array value points respective rssi*/
563static int rssiMcsTbl[][10] =
564{
565/*MCS 0 1 2 3 4 5 6 7 8 9*/
566 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
567 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
568 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
569};
570
Jeff Johnson295189b2012-06-20 16:38:30 -0700571extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530572#ifdef FEATURE_WLAN_SCAN_PNO
573static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
Leo Chang9056f462013-08-01 19:21:11 -0700576#ifdef WLAN_NL80211_TESTMODE
577enum wlan_hdd_tm_attr
578{
579 WLAN_HDD_TM_ATTR_INVALID = 0,
580 WLAN_HDD_TM_ATTR_CMD = 1,
581 WLAN_HDD_TM_ATTR_DATA = 2,
582 WLAN_HDD_TM_ATTR_TYPE = 3,
583 /* keep last */
584 WLAN_HDD_TM_ATTR_AFTER_LAST,
585 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
586};
587
588enum wlan_hdd_tm_cmd
589{
590 WLAN_HDD_TM_CMD_WLAN_HB = 1,
591};
592
593#define WLAN_HDD_TM_DATA_MAX_LEN 5000
594
595static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
596{
597 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
598 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
599 .len = WLAN_HDD_TM_DATA_MAX_LEN },
600};
601#endif /* WLAN_NL80211_TESTMODE */
602
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800603#ifdef FEATURE_WLAN_CH_AVOID
604/*
605 * FUNCTION: wlan_hdd_send_avoid_freq_event
606 * This is called when wlan driver needs to send vendor specific
607 * avoid frequency range event to userspace
608 */
609int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
610 tHddAvoidFreqList *pAvoidFreqList)
611{
612 struct sk_buff *vendor_event;
613
614 ENTER();
615
616 if (!pHddCtx)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: HDD context is null", __func__);
620 return -1;
621 }
622
623 if (!pAvoidFreqList)
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
626 "%s: pAvoidFreqList is null", __func__);
627 return -1;
628 }
629
630 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
632 NULL,
633#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800634 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 GFP_KERNEL);
637 if (!vendor_event)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
640 "%s: cfg80211_vendor_event_alloc failed", __func__);
641 return -1;
642 }
643
644 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
645 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
646
647 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
648
649 EXIT();
650 return 0;
651}
652#endif /* FEATURE_WLAN_CH_AVOID */
653
Srinivas Dasari030bad32015-02-18 23:23:54 +0530654/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530655 * define short names for the global vendor params
656 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
657 */
658#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
659
660/**
661 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
662 * hang reason
663 * @reason: cds recovery reason
664 *
665 * Return: Vendor specific reason code
666 */
667static enum qca_wlan_vendor_hang_reason
668hdd_convert_hang_reason(enum vos_hang_reason reason)
669{
670 unsigned int ret_val;
671
672 switch (reason) {
673 case VOS_GET_MSG_BUFF_FAILURE:
674 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
675 break;
676 case VOS_ACTIVE_LIST_TIMEOUT:
677 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
678 break;
679 case VOS_SCAN_REQ_EXPIRED:
680 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
681 break;
682 case VOS_TRANSMISSIONS_TIMEOUT:
683 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
684 break;
685 case VOS_DXE_FAILURE:
686 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
687 break;
688 case VOS_WDI_FAILURE:
689 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
690 break;
691 case VOS_REASON_UNSPECIFIED:
692 default:
693 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
694 }
695 return ret_val;
696}
697
698/**
699 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
700 * @hdd_ctx: Pointer to hdd context
701 * @reason: cds recovery reason
702 *
703 * Return: 0 on success or failure reason
704 */
705int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
706 enum vos_hang_reason reason)
707{
708 struct sk_buff *vendor_event;
709 enum qca_wlan_vendor_hang_reason hang_reason;
710
711 ENTER();
712
713 if (!hdd_ctx) {
714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
715 "HDD context is null");
716 return -EINVAL;
717 }
718
719 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
721 NULL,
722#endif
723 sizeof(unsigned int),
724 HANG_REASON_INDEX,
725 GFP_KERNEL);
726 if (!vendor_event) {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "cfg80211_vendor_event_alloc failed");
729 return -ENOMEM;
730 }
731
732 hang_reason = hdd_convert_hang_reason(reason);
733
734 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
735 (unsigned int) hang_reason)) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
738 kfree_skb(vendor_event);
739 return -EINVAL;
740 }
741
742 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
743
744 EXIT();
745 return 0;
746}
747#undef HANG_REASON_INDEX
748
749/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530750 * FUNCTION: __wlan_hdd_cfg80211_nan_request
751 * This is called when wlan driver needs to send vendor specific
752 * nan request event.
753 */
754static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
755 struct wireless_dev *wdev,
756 const void *data, int data_len)
757{
758 tNanRequestReq nan_req;
759 VOS_STATUS status;
760 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530761 struct net_device *dev = wdev->netdev;
762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
763 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
765
766 if (0 == data_len)
767 {
768 hddLog(VOS_TRACE_LEVEL_ERROR,
769 FL("NAN - Invalid Request, length = 0"));
770 return ret_val;
771 }
772
773 if (NULL == data)
774 {
775 hddLog(VOS_TRACE_LEVEL_ERROR,
776 FL("NAN - Invalid Request, data is NULL"));
777 return ret_val;
778 }
779
780 status = wlan_hdd_validate_context(pHddCtx);
781 if (0 != status)
782 {
783 hddLog(VOS_TRACE_LEVEL_ERROR,
784 FL("HDD context is not valid"));
785 return -EINVAL;
786 }
787
788 hddLog(LOG1, FL("Received NAN command"));
789 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
790 (tANI_U8 *)data, data_len);
791
792 /* check the NAN Capability */
793 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
794 {
795 hddLog(VOS_TRACE_LEVEL_ERROR,
796 FL("NAN is not supported by Firmware"));
797 return -EINVAL;
798 }
799
800 nan_req.request_data_len = data_len;
801 nan_req.request_data = data;
802
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530803 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530804 if (VOS_STATUS_SUCCESS == status)
805 {
806 ret_val = 0;
807 }
808 return ret_val;
809}
810
811/*
812 * FUNCTION: wlan_hdd_cfg80211_nan_request
813 * Wrapper to protect the nan vendor command from ssr
814 */
815static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
816 struct wireless_dev *wdev,
817 const void *data, int data_len)
818{
819 int ret;
820
821 vos_ssr_protect(__func__);
822 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
823 vos_ssr_unprotect(__func__);
824
825 return ret;
826}
827
828/*
829 * FUNCTION: wlan_hdd_cfg80211_nan_callback
830 * This is a callback function and it gets called
831 * when we need to report nan response event to
832 * upper layers.
833 */
834static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
835{
836 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
837 struct sk_buff *vendor_event;
838 int status;
839 tSirNanEvent *data;
840
841 ENTER();
842 if (NULL == msg)
843 {
844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
845 FL(" msg received here is null"));
846 return;
847 }
848 data = msg;
849
850 status = wlan_hdd_validate_context(pHddCtx);
851
852 if (0 != status)
853 {
854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
855 FL("HDD context is not valid"));
856 return;
857 }
858
859 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
861 NULL,
862#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530863 data->event_data_len +
864 NLMSG_HDRLEN,
865 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
866 GFP_KERNEL);
867
868 if (!vendor_event)
869 {
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
871 FL("cfg80211_vendor_event_alloc failed"));
872 return;
873 }
874 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
875 data->event_data_len, data->event_data))
876 {
877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
878 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
879 kfree_skb(vendor_event);
880 return;
881 }
882 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
883 EXIT();
884}
885
886/*
887 * FUNCTION: wlan_hdd_cfg80211_nan_init
888 * This function is called to register the callback to sme layer
889 */
890inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
891{
892 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
893}
894
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530895/*
896 * define short names for the global vendor params
897 * used by __wlan_hdd_cfg80211_get_station_cmd()
898 */
899#define STATION_INVALID \
900 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
901#define STATION_INFO \
902 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
903#define STATION_ASSOC_FAIL_REASON \
904 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530905#define STATION_REMOTE \
906 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530907#define STATION_MAX \
908 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
909
910static const struct nla_policy
911hdd_get_station_policy[STATION_MAX + 1] = {
912 [STATION_INFO] = {.type = NLA_FLAG},
913 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
914};
915
916/**
917 * hdd_get_station_assoc_fail() - Handle get station assoc fail
918 * @hdd_ctx: HDD context within host driver
919 * @wdev: wireless device
920 *
921 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
922 * Validate cmd attributes and send the station info to upper layers.
923 *
924 * Return: Success(0) or reason code for failure
925 */
926static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
927 hdd_adapter_t *adapter)
928{
929 struct sk_buff *skb = NULL;
930 uint32_t nl_buf_len;
931 hdd_station_ctx_t *hdd_sta_ctx;
932
933 nl_buf_len = NLMSG_HDRLEN;
934 nl_buf_len += sizeof(uint32_t);
935 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
936
937 if (!skb) {
938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
939 return -ENOMEM;
940 }
941
942 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
943
944 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
945 hdd_sta_ctx->conn_info.assoc_status_code)) {
946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
947 goto fail;
948 }
949 return cfg80211_vendor_cmd_reply(skb);
950fail:
951 if (skb)
952 kfree_skb(skb);
953 return -EINVAL;
954}
955
956/**
957 * hdd_map_auth_type() - transform auth type specific to
958 * vendor command
959 * @auth_type: csr auth type
960 *
961 * Return: Success(0) or reason code for failure
962 */
963static int hdd_convert_auth_type(uint32_t auth_type)
964{
965 uint32_t ret_val;
966
967 switch (auth_type) {
968 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
969 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
970 break;
971 case eCSR_AUTH_TYPE_SHARED_KEY:
972 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
973 break;
974 case eCSR_AUTH_TYPE_WPA:
975 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
976 break;
977 case eCSR_AUTH_TYPE_WPA_PSK:
978 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
979 break;
980 case eCSR_AUTH_TYPE_AUTOSWITCH:
981 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
982 break;
983 case eCSR_AUTH_TYPE_WPA_NONE:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
985 break;
986 case eCSR_AUTH_TYPE_RSN:
987 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
988 break;
989 case eCSR_AUTH_TYPE_RSN_PSK:
990 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
991 break;
992 case eCSR_AUTH_TYPE_FT_RSN:
993 ret_val = QCA_WLAN_AUTH_TYPE_FT;
994 break;
995 case eCSR_AUTH_TYPE_FT_RSN_PSK:
996 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
997 break;
998 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
999 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1000 break;
1001 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1002 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1003 break;
1004#ifdef FEATURE_WLAN_ESE
1005 case eCSR_AUTH_TYPE_CCKM_WPA:
1006 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1007 break;
1008 case eCSR_AUTH_TYPE_CCKM_RSN:
1009 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1010 break;
1011#endif
1012 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1013 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1014 break;
1015 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1016 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1017 break;
1018 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1019 case eCSR_AUTH_TYPE_FAILED:
1020 case eCSR_AUTH_TYPE_NONE:
1021 default:
1022 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1023 break;
1024 }
1025 return ret_val;
1026}
1027
1028/**
1029 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1030 * vendor command
1031 * @dot11mode: dot11mode
1032 *
1033 * Return: Success(0) or reason code for failure
1034 */
1035static int hdd_convert_dot11mode(uint32_t dot11mode)
1036{
1037 uint32_t ret_val;
1038
1039 switch (dot11mode) {
1040 case eCSR_CFG_DOT11_MODE_11A:
1041 ret_val = QCA_WLAN_802_11_MODE_11A;
1042 break;
1043 case eCSR_CFG_DOT11_MODE_11B:
1044 ret_val = QCA_WLAN_802_11_MODE_11B;
1045 break;
1046 case eCSR_CFG_DOT11_MODE_11G:
1047 ret_val = QCA_WLAN_802_11_MODE_11G;
1048 break;
1049 case eCSR_CFG_DOT11_MODE_11N:
1050 ret_val = QCA_WLAN_802_11_MODE_11N;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11AC:
1053 ret_val = QCA_WLAN_802_11_MODE_11AC;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_AUTO:
1056 case eCSR_CFG_DOT11_MODE_ABG:
1057 default:
1058 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1059 }
1060 return ret_val;
1061}
1062
1063/**
1064 * hdd_add_tx_bitrate() - add tx bitrate attribute
1065 * @skb: pointer to sk buff
1066 * @hdd_sta_ctx: pointer to hdd station context
1067 * @idx: attribute index
1068 *
1069 * Return: Success(0) or reason code for failure
1070 */
1071static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1072 hdd_station_ctx_t *hdd_sta_ctx,
1073 int idx)
1074{
1075 struct nlattr *nla_attr;
1076 uint32_t bitrate, bitrate_compat;
1077
1078 nla_attr = nla_nest_start(skb, idx);
1079 if (!nla_attr)
1080 goto fail;
1081 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301082 bitrate = cfg80211_calculate_bitrate(
1083 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301084
1085 /* report 16-bit bitrate only if we can */
1086 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1087 if (bitrate > 0 &&
1088 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1090 goto fail;
1091 }
1092 if (bitrate_compat > 0 &&
1093 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1095 goto fail;
1096 }
1097 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301098 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1100 goto fail;
1101 }
1102 nla_nest_end(skb, nla_attr);
1103 return 0;
1104fail:
1105 return -EINVAL;
1106}
1107
1108/**
1109 * hdd_add_sta_info() - add station info attribute
1110 * @skb: pointer to sk buff
1111 * @hdd_sta_ctx: pointer to hdd station context
1112 * @idx: attribute index
1113 *
1114 * Return: Success(0) or reason code for failure
1115 */
1116static int32_t hdd_add_sta_info(struct sk_buff *skb,
1117 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1118{
1119 struct nlattr *nla_attr;
1120
1121 nla_attr = nla_nest_start(skb, idx);
1122 if (!nla_attr)
1123 goto fail;
1124 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301125 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1127 goto fail;
1128 }
1129 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1130 goto fail;
1131 nla_nest_end(skb, nla_attr);
1132 return 0;
1133fail:
1134 return -EINVAL;
1135}
1136
1137/**
1138 * hdd_add_survey_info() - add survey info attribute
1139 * @skb: pointer to sk buff
1140 * @hdd_sta_ctx: pointer to hdd station context
1141 * @idx: attribute index
1142 *
1143 * Return: Success(0) or reason code for failure
1144 */
1145static int32_t hdd_add_survey_info(struct sk_buff *skb,
1146 hdd_station_ctx_t *hdd_sta_ctx,
1147 int idx)
1148{
1149 struct nlattr *nla_attr;
1150
1151 nla_attr = nla_nest_start(skb, idx);
1152 if (!nla_attr)
1153 goto fail;
1154 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301155 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301156 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301157 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1159 goto fail;
1160 }
1161 nla_nest_end(skb, nla_attr);
1162 return 0;
1163fail:
1164 return -EINVAL;
1165}
1166
1167/**
1168 * hdd_add_link_standard_info() - add link info attribute
1169 * @skb: pointer to sk buff
1170 * @hdd_sta_ctx: pointer to hdd station context
1171 * @idx: attribute index
1172 *
1173 * Return: Success(0) or reason code for failure
1174 */
1175static int32_t
1176hdd_add_link_standard_info(struct sk_buff *skb,
1177 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1178{
1179 struct nlattr *nla_attr;
1180
1181 nla_attr = nla_nest_start(skb, idx);
1182 if (!nla_attr)
1183 goto fail;
1184 if (nla_put(skb,
1185 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301186 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1187 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1189 goto fail;
1190 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301191 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1192 hdd_sta_ctx->cache_conn_info.bssId))
1193 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301194 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1195 goto fail;
1196 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1197 goto fail;
1198 nla_nest_end(skb, nla_attr);
1199 return 0;
1200fail:
1201 return -EINVAL;
1202}
1203
1204/**
1205 * hdd_add_ap_standard_info() - add ap info attribute
1206 * @skb: pointer to sk buff
1207 * @hdd_sta_ctx: pointer to hdd station context
1208 * @idx: attribute index
1209 *
1210 * Return: Success(0) or reason code for failure
1211 */
1212static int32_t
1213hdd_add_ap_standard_info(struct sk_buff *skb,
1214 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1215{
1216 struct nlattr *nla_attr;
1217
1218 nla_attr = nla_nest_start(skb, idx);
1219 if (!nla_attr)
1220 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301221 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301222 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301223 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1224 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1226 goto fail;
1227 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301228 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301229 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1231 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1233 goto fail;
1234 }
1235 nla_nest_end(skb, nla_attr);
1236 return 0;
1237fail:
1238 return -EINVAL;
1239}
1240
1241/**
1242 * hdd_get_station_info() - send BSS information to supplicant
1243 * @hdd_ctx: pointer to hdd context
1244 * @adapter: pointer to adapter
1245 *
1246 * Return: 0 if success else error status
1247 */
1248static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1249 hdd_adapter_t *adapter)
1250{
1251 struct sk_buff *skb = NULL;
1252 uint8_t *tmp_hs20 = NULL;
1253 uint32_t nl_buf_len;
1254 hdd_station_ctx_t *hdd_sta_ctx;
1255
1256 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1257
1258 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301259
1260 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1261 VOS_MAC_ADDR_SIZE +
1262 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1263 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1264 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301265 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301266 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1267 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1268 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1269 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1270 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1271 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1272 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1273 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1274 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1275 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1276 cache_conn_info.hs20vendor_ie);
1277 nl_buf_len +=
1278 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301279 1);
1280 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1284 nl_buf_len +=
1285 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301286
1287
1288 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1289 if (!skb) {
1290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1291 __func__, __LINE__);
1292 return -ENOMEM;
1293 }
1294
1295 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1296 LINK_INFO_STANDARD_NL80211_ATTR)) {
1297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1298 goto fail;
1299 }
1300 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1301 AP_INFO_STANDARD_NL80211_ATTR)) {
1302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1303 goto fail;
1304 }
1305 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301306 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301307 nla_put_u32(skb, INFO_AKM,
1308 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301309 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301310 nla_put_u32(skb, WLAN802_11_MODE,
1311 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301312 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1314 goto fail;
1315 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301316 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301317 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1319 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1321 goto fail;
1322 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 (sizeof(hdd_sta_ctx->
1326 cache_conn_info.vht_operation)),
1327 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1329 goto fail;
1330 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301331 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301332 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301333 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1334 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1336 goto fail;
1337 }
1338
1339 return cfg80211_vendor_cmd_reply(skb);
1340fail:
1341 if (skb)
1342 kfree_skb(skb);
1343 return -EINVAL;
1344}
1345
1346/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301347 * hdd_add_survey_info_sap_get_len - get data length used in
1348 * hdd_add_survey_info_sap()
1349 *
1350 * This function calculates the data length used in hdd_add_survey_info_sap()
1351 *
1352 * Return: total data length used in hdd_add_survey_info_sap()
1353 */
1354static uint32_t hdd_add_survey_info_sap_get_len(void)
1355{
1356 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1357}
1358
1359/**
1360 * hdd_add_survey_info - add survey info attribute
1361 * @skb: pointer to response skb buffer
1362 * @stainfo: station information
1363 * @idx: attribute type index for nla_next_start()
1364 *
1365 * This function adds survey info attribute to response skb buffer
1366 *
1367 * Return : 0 on success and errno on failure
1368 */
1369static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1370 struct hdd_cache_sta_info *stainfo,
1371 int idx)
1372{
1373 struct nlattr *nla_attr;
1374
1375 nla_attr = nla_nest_start(skb, idx);
1376 if (!nla_attr)
1377 goto fail;
1378 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1379 stainfo->freq)) {
1380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1381 FL("put fail"));
1382 goto fail;
1383 }
1384 nla_nest_end(skb, nla_attr);
1385 return 0;
1386fail:
1387 return -EINVAL;
1388}
1389
1390/**
1391 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1392 * hdd_add_tx_bitrate_sap()
1393 *
1394 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1395 *
1396 * Return: total data length used in hdd_add_tx_bitrate_sap()
1397 */
1398static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1399{
1400 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1401}
1402
1403/**
1404 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1405 * @skb: pointer to response skb buffer
1406 * @stainfo: station information
1407 * @idx: attribute type index for nla_next_start()
1408 *
1409 * This function adds vht nss attribute to response skb buffer
1410 *
1411 * Return : 0 on success and errno on failure
1412 */
1413static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1414 struct hdd_cache_sta_info *stainfo,
1415 int idx)
1416{
1417 struct nlattr *nla_attr;
1418
1419 nla_attr = nla_nest_start(skb, idx);
1420 if (!nla_attr)
1421 goto fail;
1422
1423 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1424 stainfo->nss)) {
1425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1426 FL("put fail"));
1427 goto fail;
1428 }
1429 nla_nest_end(skb, nla_attr);
1430 return 0;
1431fail:
1432 return -EINVAL;
1433}
1434
1435/**
1436 * hdd_add_sta_info_sap_get_len - get data length used in
1437 * hdd_add_sta_info_sap()
1438 *
1439 * This function calculates the data length used in hdd_add_sta_info_sap()
1440 *
1441 * Return: total data length used in hdd_add_sta_info_sap()
1442 */
1443static uint32_t hdd_add_sta_info_sap_get_len(void)
1444{
1445 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1446 hdd_add_tx_bitrate_sap_get_len());
1447}
1448
1449/**
1450 * hdd_add_sta_info_sap - add sta signal info attribute
1451 * @skb: pointer to response skb buffer
1452 * @rssi: peer rssi value
1453 * @stainfo: station information
1454 * @idx: attribute type index for nla_next_start()
1455 *
1456 * This function adds sta signal attribute to response skb buffer
1457 *
1458 * Return : 0 on success and errno on failure
1459 */
1460static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1461 struct hdd_cache_sta_info *stainfo, int idx)
1462{
1463 struct nlattr *nla_attr;
1464
1465 nla_attr = nla_nest_start(skb, idx);
1466 if (!nla_attr)
1467 goto fail;
1468
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301469 /* upperlayer expects positive rssi value */
1470 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1472 FL("put fail"));
1473 goto fail;
1474 }
1475 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1477 FL("put fail"));
1478 goto fail;
1479 }
1480
1481 nla_nest_end(skb, nla_attr);
1482 return 0;
1483fail:
1484 return -EINVAL;
1485}
1486
1487/**
1488 * hdd_add_link_standard_info_sap_get_len - get data length used in
1489 * hdd_add_link_standard_info_sap()
1490 *
1491 * This function calculates the data length used in
1492 * hdd_add_link_standard_info_sap()
1493 *
1494 * Return: total data length used in hdd_add_link_standard_info_sap()
1495 */
1496static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1497{
1498 return ((NLA_HDRLEN) +
1499 hdd_add_survey_info_sap_get_len() +
1500 hdd_add_sta_info_sap_get_len() +
1501 (sizeof(uint32_t) + NLA_HDRLEN));
1502}
1503
1504/**
1505 * hdd_add_link_standard_info_sap - add add link info attribut
1506 * @skb: pointer to response skb buffer
1507 * @stainfo: station information
1508 * @idx: attribute type index for nla_next_start()
1509 *
1510 * This function adds link info attribut to response skb buffer
1511 *
1512 * Return : 0 on success and errno on failure
1513 */
1514static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1515 struct hdd_cache_sta_info *stainfo,
1516 int idx)
1517{
1518 struct nlattr *nla_attr;
1519
1520 nla_attr = nla_nest_start(skb, idx);
1521 if (!nla_attr)
1522 goto fail;
1523 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1524 goto fail;
1525 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1526 goto fail;
1527
1528 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1530 FL("put fail"));
1531 goto fail;
1532 }
1533
1534 nla_nest_end(skb, nla_attr);
1535 return 0;
1536fail:
1537 return -EINVAL;
1538}
1539
1540/**
1541 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1542 * hdd_add_ap_standard_info_sap()
1543 * @stainfo: station information
1544 *
1545 * This function calculates the data length used in
1546 * hdd_add_ap_standard_info_sap()
1547 *
1548 * Return: total data length used in hdd_add_ap_standard_info_sap()
1549 */
1550static uint32_t hdd_add_ap_standard_info_sap_get_len(
1551 struct hdd_cache_sta_info *stainfo)
1552{
1553 uint32_t len;
1554
1555 len = NLA_HDRLEN;
1556 if (stainfo->vht_present)
1557 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1558 if (stainfo->ht_present)
1559 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1560
1561 return len;
1562}
1563
1564/**
1565 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1566 * @skb: pointer to response skb buffer
1567 * @stainfo: station information
1568 * @idx: attribute type index for nla_next_start()
1569 *
1570 * This function adds HT and VHT info attributes to response skb buffer
1571 *
1572 * Return : 0 on success and errno on failure
1573 */
1574static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1575 struct hdd_cache_sta_info *stainfo,
1576 int idx)
1577{
1578 struct nlattr *nla_attr;
1579
1580 nla_attr = nla_nest_start(skb, idx);
1581 if (!nla_attr)
1582 goto fail;
1583
1584 if (stainfo->vht_present) {
1585 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1586 sizeof(stainfo->vht_caps),
1587 &stainfo->vht_caps)) {
1588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1589 FL("put fail"));
1590 goto fail;
1591 }
1592 }
1593 if (stainfo->ht_present) {
1594 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1595 sizeof(stainfo->ht_caps),
1596 &stainfo->ht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 nla_nest_end(skb, nla_attr);
1603 return 0;
1604fail:
1605 return -EINVAL;
1606}
1607
1608/**
1609 * hdd_decode_ch_width - decode channel band width based
1610 * @ch_width: encoded enum value holding channel band width
1611 *
1612 * This function decodes channel band width from the given encoded enum value.
1613 *
1614 * Returns: decoded channel band width.
1615 */
1616static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1617{
1618 switch (ch_width) {
1619 case 0:
1620 return 20;
1621 case 1:
1622 return 40;
1623 case 2:
1624 return 80;
1625 default:
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1627 "invalid enum: %d", ch_width);
1628 return 20;
1629 }
1630}
1631
1632/**
1633 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1634 * @hdd_ctx: hdd context
1635 * @adapter: hostapd interface
1636 * @mac_addr: mac address of requested peer
1637 *
1638 * This function collect and indicate the cached(deleted) peer's info
1639 *
1640 * Return: 0 on success, otherwise error value
1641 */
1642static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1643 hdd_adapter_t *adapter,
1644 v_MACADDR_t mac_addr)
1645{
1646 struct hdd_cache_sta_info *stainfo;
1647 struct sk_buff *skb = NULL;
1648 uint32_t nl_buf_len;
1649 uint8_t cw;
1650 ptSapContext sap_ctx;
1651 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1652
1653 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1654 if(sap_ctx == NULL){
1655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1656 FL("psapCtx is NULL"));
1657 return -ENOENT;
1658 }
1659
1660 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1661 mac_addr.bytes);
1662 if (!stainfo) {
1663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1664 "peer " MAC_ADDRESS_STR " not found",
1665 MAC_ADDR_ARRAY(mac_addr.bytes));
1666 return -EINVAL;
1667 }
1668 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1670 "peer " MAC_ADDRESS_STR " is in connected state",
1671 MAC_ADDR_ARRAY(mac_addr.bytes));
1672 return -EINVAL;
1673 }
1674
1675
1676 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1677 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1678 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1679 (sizeof(cw) + NLA_HDRLEN) +
1680 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1681
1682 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1683 if (!skb) {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1685 return -ENOMEM;
1686 }
1687
1688 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1689 LINK_INFO_STANDARD_NL80211_ATTR)) {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1691 goto fail;
1692 }
1693
1694 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1695 AP_INFO_STANDARD_NL80211_ATTR)) {
1696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1697 goto fail;
1698 }
1699
1700 /* upper layer expects decoded channel BW */
1701 cw = hdd_decode_ch_width(stainfo->ch_width);
1702 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1703 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1705 goto fail;
1706 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301707 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1709 goto fail;
1710 }
1711
1712 vos_mem_zero(stainfo, sizeof(*stainfo));
1713
1714 return cfg80211_vendor_cmd_reply(skb);
1715fail:
1716 if (skb)
1717 kfree_skb(skb);
1718
1719 return -EINVAL;
1720}
1721
1722/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301723 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1724 * @wiphy: corestack handler
1725 * @wdev: wireless device
1726 * @data: data
1727 * @data_len: data length
1728 *
1729 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1730 * Validate cmd attributes and send the station info to upper layers.
1731 *
1732 * Return: Success(0) or reason code for failure
1733 */
1734static int32_t
1735__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1736 struct wireless_dev *wdev,
1737 const void *data,
1738 int data_len)
1739{
1740 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1741 struct net_device *dev = wdev->netdev;
1742 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1743 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1744 int32_t status;
1745
1746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1747 if (VOS_FTM_MODE == hdd_get_conparam()) {
1748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1749 status = -EPERM;
1750 goto out;
1751 }
1752
1753 status = wlan_hdd_validate_context(hdd_ctx);
1754 if (0 != status)
1755 goto out;
1756
1757
1758 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1759 data, data_len, NULL);
1760 if (status) {
1761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1762 goto out;
1763 }
1764
1765 /* Parse and fetch Command Type*/
1766 if (tb[STATION_INFO]) {
1767 status = hdd_get_station_info(hdd_ctx, adapter);
1768 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1769 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301770 } else if (tb[STATION_REMOTE]) {
1771 v_MACADDR_t mac_addr;
1772
1773 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1774 adapter->device_mode != WLAN_HDD_P2P_GO) {
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1776 adapter->device_mode);
1777 status = -EINVAL;
1778 goto out;
1779 }
1780
1781 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1782 VOS_MAC_ADDRESS_LEN);
1783
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1785 MAC_ADDR_ARRAY(mac_addr.bytes));
1786
1787 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1788 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301789 } else {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1791 status = -EINVAL;
1792 goto out;
1793 }
1794 EXIT();
1795out:
1796 return status;
1797}
1798
1799/**
1800 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1801 * @wiphy: corestack handler
1802 * @wdev: wireless device
1803 * @data: data
1804 * @data_len: data length
1805 *
1806 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1807 * Validate cmd attributes and send the station info to upper layers.
1808 *
1809 * Return: Success(0) or reason code for failure
1810 */
1811static int32_t
1812hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1813 struct wireless_dev *wdev,
1814 const void *data,
1815 int data_len)
1816{
1817 int ret;
1818
1819 vos_ssr_protect(__func__);
1820 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1821 vos_ssr_unprotect(__func__);
1822
1823 return ret;
1824}
1825
1826/*
1827 * undef short names defined for get station command
1828 * used by __wlan_hdd_cfg80211_get_station_cmd()
1829 */
1830#undef STATION_INVALID
1831#undef STATION_INFO
1832#undef STATION_ASSOC_FAIL_REASON
1833#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1836
1837static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1838 struct sk_buff *vendor_event)
1839{
1840 if (nla_put_u8(vendor_event,
1841 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1842 stats->rate.preamble) ||
1843 nla_put_u8(vendor_event,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1845 stats->rate.nss) ||
1846 nla_put_u8(vendor_event,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1848 stats->rate.bw) ||
1849 nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1851 stats->rate.rateMcsIdx) ||
1852 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1853 stats->rate.bitrate ) ||
1854 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1855 stats->txMpdu ) ||
1856 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1857 stats->rxMpdu ) ||
1858 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1859 stats->mpduLost ) ||
1860 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1861 stats->retries) ||
1862 nla_put_u32(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1864 stats->retriesShort ) ||
1865 nla_put_u32(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1867 stats->retriesLong))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1871 return FALSE;
1872 }
1873 return TRUE;
1874}
1875
1876static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1877 struct sk_buff *vendor_event)
1878{
1879 u32 i = 0;
1880 struct nlattr *rateInfo;
1881 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1882 stats->type) ||
1883 nla_put(vendor_event,
1884 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1885 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1886 nla_put_u32(vendor_event,
1887 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1888 stats->capabilities) ||
1889 nla_put_u32(vendor_event,
1890 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1891 stats->numRate))
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR,
1894 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1895 goto error;
1896 }
1897
1898 rateInfo = nla_nest_start(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301900 if(!rateInfo)
1901 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 for (i = 0; i < stats->numRate; i++)
1903 {
1904 struct nlattr *rates;
1905 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1906 stats->rateStats +
1907 (i * sizeof(tSirWifiRateStat)));
1908 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rates)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911
1912 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1913 {
1914 hddLog(VOS_TRACE_LEVEL_ERROR,
1915 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1916 return FALSE;
1917 }
1918 nla_nest_end(vendor_event, rates);
1919 }
1920 nla_nest_end(vendor_event, rateInfo);
1921
1922 return TRUE;
1923error:
1924 return FALSE;
1925}
1926
1927static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1928 struct sk_buff *vendor_event)
1929{
1930 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1931 stats->ac ) ||
1932 nla_put_u32(vendor_event,
1933 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1934 stats->txMpdu ) ||
1935 nla_put_u32(vendor_event,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1937 stats->rxMpdu ) ||
1938 nla_put_u32(vendor_event,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1940 stats->txMcast ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1943 stats->rxMcast ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1946 stats->rxAmpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1949 stats->txAmpdu ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1952 stats->mpduLost )||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1955 stats->retries ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1958 stats->retriesShort ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1961 stats->retriesLong ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1964 stats->contentionTimeMin ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1967 stats->contentionTimeMax ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1970 stats->contentionTimeAvg ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1973 stats->contentionNumSamples ))
1974 {
1975 hddLog(VOS_TRACE_LEVEL_ERROR,
1976 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1977 return FALSE;
1978 }
1979 return TRUE;
1980}
1981
1982static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1983 struct sk_buff *vendor_event)
1984{
Dino Myclec8f3f332014-07-21 16:48:27 +05301985 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301986 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1987 nla_put(vendor_event,
1988 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1989 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1990 nla_put_u32(vendor_event,
1991 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1992 stats->state ) ||
1993 nla_put_u32(vendor_event,
1994 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1995 stats->roaming ) ||
1996 nla_put_u32(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1998 stats->capabilities ) ||
1999 nla_put(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2001 strlen(stats->ssid), stats->ssid) ||
2002 nla_put(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2004 WNI_CFG_BSSID_LEN, stats->bssid) ||
2005 nla_put(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2007 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2010 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2011 )
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2015 return FALSE;
2016 }
2017 return TRUE;
2018}
2019
Dino Mycle3b9536d2014-07-09 22:05:24 +05302020static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2021 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022 struct sk_buff *vendor_event)
2023{
2024 int i = 0;
2025 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302026 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2027 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302028 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 if (FALSE == put_wifi_interface_info(
2031 &pWifiIfaceStat->info,
2032 vendor_event))
2033 {
2034 hddLog(VOS_TRACE_LEVEL_ERROR,
2035 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2036 return FALSE;
2037
2038 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2040 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2041 if (NULL == pWifiIfaceStatTL)
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2044 return FALSE;
2045 }
2046
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302047 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2048 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2049 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2051
2052 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302056
2057 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2058 {
2059 if (VOS_STATUS_SUCCESS ==
2060 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2061 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2062 {
2063 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2064 * obtained from TL structure
2065 */
2066
2067 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2068 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302069 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2070
Srinivas Dasari98947432014-11-07 19:41:24 +05302071 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2072 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2073 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2074 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2076 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2077 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2078 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097 }
2098 else
2099 {
2100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2101 }
2102
Dino Mycle3b9536d2014-07-09 22:05:24 +05302103 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2104 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2106 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2107 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2108 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2109 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2110 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2111 }
2112 else
2113 {
2114 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2115 }
2116
2117
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118
2119 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302120 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2121 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2122 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302123 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2124 pWifiIfaceStat->beaconRx) ||
2125 nla_put_u32(vendor_event,
2126 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2127 pWifiIfaceStat->mgmtRx) ||
2128 nla_put_u32(vendor_event,
2129 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2130 pWifiIfaceStat->mgmtActionRx) ||
2131 nla_put_u32(vendor_event,
2132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2133 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302134 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2136 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302137 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2139 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302140 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2142 pWifiIfaceStat->rssiAck))
2143 {
2144 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302145 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2146 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 return FALSE;
2148 }
2149
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302150#ifdef FEATURE_EXT_LL_STAT
2151 /*
2152 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2153 * then host should send Leaky AP stats to upper layer,
2154 * otherwise no need to send these stats.
2155 */
2156 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2157 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2158 )
2159 {
2160 hddLog(VOS_TRACE_LEVEL_INFO,
2161 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2162 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2163 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2164 pWifiIfaceStat->leakyApStat.rx_leak_window,
2165 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2166 if (nla_put_u32(vendor_event,
2167 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2168 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2169 nla_put_u32(vendor_event,
2170 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2171 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2172 nla_put_u32(vendor_event,
2173 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2174 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302175 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2177 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2178 {
2179 hddLog(VOS_TRACE_LEVEL_ERROR,
2180 FL("EXT_LL_STAT put fail"));
2181 vos_mem_free(pWifiIfaceStatTL);
2182 return FALSE;
2183 }
2184 }
2185#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302186 wmmInfo = nla_nest_start(vendor_event,
2187 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302188 if(!wmmInfo)
2189 {
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302193 for (i = 0; i < WIFI_AC_MAX; i++)
2194 {
2195 struct nlattr *wmmStats;
2196 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmStats)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 if (FALSE == put_wifi_wmm_ac_stat(
2203 &pWifiIfaceStat->AccessclassStats[i],
2204 vendor_event))
2205 {
2206 hddLog(VOS_TRACE_LEVEL_ERROR,
2207 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302208 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 return FALSE;
2210 }
2211
2212 nla_nest_end(vendor_event, wmmStats);
2213 }
2214 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302215 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302216 return TRUE;
2217}
2218
2219static tSirWifiInterfaceMode
2220 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2221{
2222 switch (deviceMode)
2223 {
2224 case WLAN_HDD_INFRA_STATION:
2225 return WIFI_INTERFACE_STA;
2226 case WLAN_HDD_SOFTAP:
2227 return WIFI_INTERFACE_SOFTAP;
2228 case WLAN_HDD_P2P_CLIENT:
2229 return WIFI_INTERFACE_P2P_CLIENT;
2230 case WLAN_HDD_P2P_GO:
2231 return WIFI_INTERFACE_P2P_GO;
2232 case WLAN_HDD_IBSS:
2233 return WIFI_INTERFACE_IBSS;
2234 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302235 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 }
2237}
2238
2239static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2240 tpSirWifiInterfaceInfo pInfo)
2241{
2242 v_U8_t *staMac = NULL;
2243 hdd_station_ctx_t *pHddStaCtx;
2244 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2245 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2246
2247 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2248
2249 vos_mem_copy(pInfo->macAddr,
2250 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2251
2252 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2253 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2254 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2255 {
2256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2257 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2258 {
2259 pInfo->state = WIFI_DISCONNECTED;
2260 }
2261 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR,
2264 "%s: Session ID %d, Connection is in progress", __func__,
2265 pAdapter->sessionId);
2266 pInfo->state = WIFI_ASSOCIATING;
2267 }
2268 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2269 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2270 {
2271 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: client " MAC_ADDRESS_STR
2274 " is in the middle of WPS/EAPOL exchange.", __func__,
2275 MAC_ADDR_ARRAY(staMac));
2276 pInfo->state = WIFI_AUTHENTICATING;
2277 }
2278 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2279 {
2280 pInfo->state = WIFI_ASSOCIATED;
2281 vos_mem_copy(pInfo->bssid,
2282 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2283 vos_mem_copy(pInfo->ssid,
2284 pHddStaCtx->conn_info.SSID.SSID.ssId,
2285 pHddStaCtx->conn_info.SSID.SSID.length);
2286 //NULL Terminate the string.
2287 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2288 }
2289 }
2290 vos_mem_copy(pInfo->countryStr,
2291 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2292
2293 vos_mem_copy(pInfo->apCountryStr,
2294 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2295
2296 return TRUE;
2297}
2298
2299/*
2300 * hdd_link_layer_process_peer_stats () - This function is called after
2301 * receiving Link Layer Peer statistics from FW.This function converts
2302 * the firmware data to the NL data and sends the same to the kernel/upper
2303 * layers.
2304 */
2305static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2306 v_VOID_t *pData)
2307{
2308 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309 tpSirWifiPeerStat pWifiPeerStat;
2310 tpSirWifiPeerInfo pWifiPeerInfo;
2311 struct nlattr *peerInfo;
2312 struct sk_buff *vendor_event;
2313 int status, i;
2314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302315 ENTER();
2316
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317 status = wlan_hdd_validate_context(pHddCtx);
2318 if (0 != status)
2319 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302320 return;
2321 }
2322
2323 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2324
2325 hddLog(VOS_TRACE_LEVEL_INFO,
2326 "LL_STATS_PEER_ALL : numPeers %u",
2327 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 /*
2329 * Allocate a size of 4096 for the peer stats comprising
2330 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2331 * sizeof (tSirWifiRateStat).Each field is put with an
2332 * NL attribute.The size of 4096 is considered assuming
2333 * that number of rates shall not exceed beyond 50 with
2334 * the sizeof (tSirWifiRateStat) being 32.
2335 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302336 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2337 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 if (!vendor_event)
2339 {
2340 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302341 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302342 __func__);
2343 return;
2344 }
2345 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302346 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2347 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2348 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302349 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2350 pWifiPeerStat->numPeers))
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
2353 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2354 kfree_skb(vendor_event);
2355 return;
2356 }
2357
2358 peerInfo = nla_nest_start(vendor_event,
2359 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302360 if(!peerInfo)
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2364 __func__);
2365 kfree_skb(vendor_event);
2366 return;
2367 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302368
2369 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2370 pWifiPeerStat->peerInfo);
2371
2372 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2373 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302374 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302375 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302377 if(!peers)
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR,
2380 "%s: peer stats put fail",
2381 __func__);
2382 kfree_skb(vendor_event);
2383 return;
2384 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 if (FALSE == put_wifi_peer_info(
2386 pWifiPeerInfo, vendor_event))
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: put_wifi_peer_info put fail", __func__);
2390 kfree_skb(vendor_event);
2391 return;
2392 }
2393
2394 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2395 pWifiPeerStat->peerInfo +
2396 (i * sizeof(tSirWifiPeerInfo)) +
2397 (numRate * sizeof (tSirWifiRateStat)));
2398 nla_nest_end(vendor_event, peers);
2399 }
2400 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302401 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403}
2404
2405/*
2406 * hdd_link_layer_process_iface_stats () - This function is called after
2407 * receiving Link Layer Interface statistics from FW.This function converts
2408 * the firmware data to the NL data and sends the same to the kernel/upper
2409 * layers.
2410 */
2411static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2412 v_VOID_t *pData)
2413{
2414 tpSirWifiIfaceStat pWifiIfaceStat;
2415 struct sk_buff *vendor_event;
2416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2417 int status;
2418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302419 ENTER();
2420
Sunil Duttc69bccb2014-05-26 21:30:20 +05302421 status = wlan_hdd_validate_context(pHddCtx);
2422 if (0 != status)
2423 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302424 return;
2425 }
2426 /*
2427 * Allocate a size of 4096 for the interface stats comprising
2428 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2429 * assuming that all these fit with in the limit.Please take
2430 * a call on the limit based on the data requirements on
2431 * interface statistics.
2432 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2434 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302435 if (!vendor_event)
2436 {
2437 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302438 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302439 return;
2440 }
2441
2442 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2443
Dino Mycle3b9536d2014-07-09 22:05:24 +05302444
2445 if (FALSE == hdd_get_interface_info( pAdapter,
2446 &pWifiIfaceStat->info))
2447 {
2448 hddLog(VOS_TRACE_LEVEL_ERROR,
2449 FL("hdd_get_interface_info get fail") );
2450 kfree_skb(vendor_event);
2451 return;
2452 }
2453
2454 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2455 vendor_event))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("put_wifi_iface_stats fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
Sunil Duttc69bccb2014-05-26 21:30:20 +05302463 hddLog(VOS_TRACE_LEVEL_INFO,
2464 "WMI_LINK_STATS_IFACE Data");
2465
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302466 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467
2468 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302469}
2470
2471/*
2472 * hdd_link_layer_process_radio_stats () - This function is called after
2473 * receiving Link Layer Radio statistics from FW.This function converts
2474 * the firmware data to the NL data and sends the same to the kernel/upper
2475 * layers.
2476 */
2477static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2478 v_VOID_t *pData)
2479{
2480 int status, i;
2481 tpSirWifiRadioStat pWifiRadioStat;
2482 tpSirWifiChannelStats pWifiChannelStats;
2483 struct sk_buff *vendor_event;
2484 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2485 struct nlattr *chList;
2486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302487 ENTER();
2488
Sunil Duttc69bccb2014-05-26 21:30:20 +05302489 status = wlan_hdd_validate_context(pHddCtx);
2490 if (0 != status)
2491 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302492 return;
2493 }
2494 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2495
2496 hddLog(VOS_TRACE_LEVEL_INFO,
2497 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302498 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302499 " radio is %d onTime is %u "
2500 " txTime is %u rxTime is %u "
2501 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302503 " onTimePnoScan is %u onTimeHs20 is %u "
2504 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302505 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302506 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2507 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2508 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302509 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510 pWifiRadioStat->onTimeRoamScan,
2511 pWifiRadioStat->onTimePnoScan,
2512 pWifiRadioStat->onTimeHs20,
2513 pWifiRadioStat->numChannels);
2514 /*
2515 * Allocate a size of 4096 for the Radio stats comprising
2516 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2517 * (tSirWifiChannelStats).Each channel data is put with an
2518 * NL attribute.The size of 4096 is considered assuming that
2519 * number of channels shall not exceed beyond 60 with the
2520 * sizeof (tSirWifiChannelStats) being 24 bytes.
2521 */
2522
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302523 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2524 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302525 if (!vendor_event)
2526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302528 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529 return;
2530 }
2531
2532 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2534 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2535 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302536 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2537 pWifiRadioStat->radio) ||
2538 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302539 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2540 NUM_RADIOS) ||
2541 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2543 pWifiRadioStat->onTime) ||
2544 nla_put_u32(vendor_event,
2545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2546 pWifiRadioStat->txTime) ||
2547 nla_put_u32(vendor_event,
2548 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2549 pWifiRadioStat->rxTime) ||
2550 nla_put_u32(vendor_event,
2551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2552 pWifiRadioStat->onTimeScan) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2555 pWifiRadioStat->onTimeNbd) ||
2556 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2558 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2561 pWifiRadioStat->onTimeRoamScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2564 pWifiRadioStat->onTimePnoScan) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2567 pWifiRadioStat->onTimeHs20) ||
2568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2570 pWifiRadioStat->numChannels))
2571 {
2572 hddLog(VOS_TRACE_LEVEL_ERROR,
2573 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2574 kfree_skb(vendor_event);
2575 return ;
2576 }
2577
2578 chList = nla_nest_start(vendor_event,
2579 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302580 if(!chList)
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2584 __func__);
2585 kfree_skb(vendor_event);
2586 return;
2587 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302588 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2589 {
2590 struct nlattr *chInfo;
2591
2592 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2593 pWifiRadioStat->channels +
2594 (i * sizeof(tSirWifiChannelStats)));
2595
Sunil Duttc69bccb2014-05-26 21:30:20 +05302596 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302597 if(!chInfo)
2598 {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 "%s: failed to put chInfo",
2601 __func__);
2602 kfree_skb(vendor_event);
2603 return;
2604 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605
2606 if (nla_put_u32(vendor_event,
2607 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2608 pWifiChannelStats->channel.width) ||
2609 nla_put_u32(vendor_event,
2610 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2611 pWifiChannelStats->channel.centerFreq) ||
2612 nla_put_u32(vendor_event,
2613 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2614 pWifiChannelStats->channel.centerFreq0) ||
2615 nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2617 pWifiChannelStats->channel.centerFreq1) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2620 pWifiChannelStats->onTime) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2623 pWifiChannelStats->ccaBusyTime))
2624 {
2625 hddLog(VOS_TRACE_LEVEL_ERROR,
2626 FL("cfg80211_vendor_event_alloc failed") );
2627 kfree_skb(vendor_event);
2628 return ;
2629 }
2630 nla_nest_end(vendor_event, chInfo);
2631 }
2632 nla_nest_end(vendor_event, chList);
2633
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302634 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635
2636 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302637 return;
2638}
2639
2640/*
2641 * hdd_link_layer_stats_ind_callback () - This function is called after
2642 * receiving Link Layer indications from FW.This callback converts the firmware
2643 * data to the NL data and send the same to the kernel/upper layers.
2644 */
2645static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2646 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302647 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648{
Dino Mycled3d50022014-07-07 12:58:25 +05302649 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2650 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302651 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302652 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302653 int status;
2654
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302655 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302657 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302658 if (0 != status)
2659 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660 return;
2661 }
2662
Dino Mycled3d50022014-07-07 12:58:25 +05302663 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2664 if (NULL == pAdapter)
2665 {
2666 hddLog(VOS_TRACE_LEVEL_ERROR,
2667 FL(" MAC address %pM does not exist with host"),
2668 macAddr);
2669 return;
2670 }
2671
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302673 "%s: Interface: %s LLStats indType: %d", __func__,
2674 pAdapter->dev->name, indType);
2675
Sunil Duttc69bccb2014-05-26 21:30:20 +05302676 switch (indType)
2677 {
2678 case SIR_HAL_LL_STATS_RESULTS_RSP:
2679 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302680 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302681 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2682 "respId = %u, moreResultToFollow = %u",
2683 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2684 macAddr, linkLayerStatsResults->respId,
2685 linkLayerStatsResults->moreResultToFollow);
2686
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302687 spin_lock(&hdd_context_lock);
2688 context = &pHddCtx->ll_stats_context;
2689 /* validate response received from target */
2690 if ((context->request_id != linkLayerStatsResults->respId) ||
2691 !(context->request_bitmap & linkLayerStatsResults->paramId))
2692 {
2693 spin_unlock(&hdd_context_lock);
2694 hddLog(LOGE,
2695 FL("Error : Request id %d response id %d request bitmap 0x%x"
2696 "response bitmap 0x%x"),
2697 context->request_id, linkLayerStatsResults->respId,
2698 context->request_bitmap, linkLayerStatsResults->paramId);
2699 return;
2700 }
2701 spin_unlock(&hdd_context_lock);
2702
Sunil Duttc69bccb2014-05-26 21:30:20 +05302703 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2704 {
2705 hdd_link_layer_process_radio_stats(pAdapter,
2706 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302707 spin_lock(&hdd_context_lock);
2708 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2709 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302710 }
2711 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2712 {
2713 hdd_link_layer_process_iface_stats(pAdapter,
2714 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302715 spin_lock(&hdd_context_lock);
2716 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2717 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302718 }
2719 else if ( linkLayerStatsResults->paramId &
2720 WMI_LINK_STATS_ALL_PEER )
2721 {
2722 hdd_link_layer_process_peer_stats(pAdapter,
2723 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302724 spin_lock(&hdd_context_lock);
2725 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 } /* WMI_LINK_STATS_ALL_PEER */
2728 else
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR,
2731 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2732 }
2733
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302734 spin_lock(&hdd_context_lock);
2735 /* complete response event if all requests are completed */
2736 if (0 == context->request_bitmap)
2737 complete(&context->response_event);
2738 spin_unlock(&hdd_context_lock);
2739
Sunil Duttc69bccb2014-05-26 21:30:20 +05302740 break;
2741 }
2742 default:
2743 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2744 break;
2745 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302746
2747 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302748 return;
2749}
2750
2751const struct
2752nla_policy
2753qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2754{
2755 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2756 { .type = NLA_U32 },
2757 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2758 { .type = NLA_U32 },
2759};
2760
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302761static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2762 struct wireless_dev *wdev,
2763 const void *data,
2764 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302765{
2766 int status;
2767 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302768 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302769 struct net_device *dev = wdev->netdev;
2770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302773 ENTER();
2774
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775 status = wlan_hdd_validate_context(pHddCtx);
2776 if (0 != status)
2777 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 return -EINVAL;
2779 }
2780
2781 if (NULL == pAdapter)
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR,
2784 FL("HDD adapter is Null"));
2785 return -ENODEV;
2786 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302787 /* check the LLStats Capability */
2788 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2789 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2790 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302791 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302792 FL("Link Layer Statistics not supported by Firmware"));
2793 return -EINVAL;
2794 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795
2796 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2797 (struct nlattr *)data,
2798 data_len, qca_wlan_vendor_ll_set_policy))
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2801 return -EINVAL;
2802 }
2803 if (!tb_vendor
2804 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2805 {
2806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2807 return -EINVAL;
2808 }
2809 if (!tb_vendor[
2810 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2813 return -EINVAL;
2814 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302815 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302816 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302817
Dino Mycledf0a5d92014-07-04 09:41:55 +05302818 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302819 nla_get_u32(
2820 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2821
Dino Mycledf0a5d92014-07-04 09:41:55 +05302822 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302823 nla_get_u32(
2824 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2825
Dino Mycled3d50022014-07-07 12:58:25 +05302826 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2827 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828
2829
2830 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302831 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2832 "Statistics Gathering = %d ",
2833 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2834 linkLayerStatsSetReq.mpduSizeThreshold,
2835 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302836
2837 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2838 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302839 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2842 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302843 return -EINVAL;
2844
2845 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302846
Sunil Duttc69bccb2014-05-26 21:30:20 +05302847 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302848 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853 }
2854
2855 pAdapter->isLinkLayerStatsSet = 1;
2856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 return 0;
2859}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302860static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2861 struct wireless_dev *wdev,
2862 const void *data,
2863 int data_len)
2864{
2865 int ret = 0;
2866
2867 vos_ssr_protect(__func__);
2868 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2869 vos_ssr_unprotect(__func__);
2870
2871 return ret;
2872}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302873
2874const struct
2875nla_policy
2876qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2877{
2878 /* Unsigned 32bit value provided by the caller issuing the GET stats
2879 * command. When reporting
2880 * the stats results, the driver uses the same value to indicate
2881 * which GET request the results
2882 * correspond to.
2883 */
2884 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2885
2886 /* Unsigned 32bit value . bit mask to identify what statistics are
2887 requested for retrieval */
2888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2889};
2890
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302891static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2892 struct wireless_dev *wdev,
2893 const void *data,
2894 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302895{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302896 unsigned long rc;
2897 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2899 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302900 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302901 struct net_device *dev = wdev->netdev;
2902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904 int status;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 status = wlan_hdd_validate_context(pHddCtx);
2909 if (0 != status)
2910 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911 return -EINVAL ;
2912 }
2913
2914 if (NULL == pAdapter)
2915 {
2916 hddLog(VOS_TRACE_LEVEL_FATAL,
2917 "%s: HDD adapter is Null", __func__);
2918 return -ENODEV;
2919 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302920
2921 if (pHddStaCtx == NULL)
2922 {
2923 hddLog(VOS_TRACE_LEVEL_FATAL,
2924 "%s: HddStaCtx is Null", __func__);
2925 return -ENODEV;
2926 }
2927
Dino Mycledf0a5d92014-07-04 09:41:55 +05302928 /* check the LLStats Capability */
2929 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2930 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2931 {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("Link Layer Statistics not supported by Firmware"));
2934 return -EINVAL;
2935 }
2936
Sunil Duttc69bccb2014-05-26 21:30:20 +05302937
2938 if (!pAdapter->isLinkLayerStatsSet)
2939 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302940 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302941 "%s: isLinkLayerStatsSet : %d",
2942 __func__, pAdapter->isLinkLayerStatsSet);
2943 return -EINVAL;
2944 }
2945
Mukul Sharma10313ba2015-07-29 19:14:39 +05302946 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2947 {
2948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2949 "%s: Roaming in progress, so unable to proceed this request", __func__);
2950 return -EBUSY;
2951 }
2952
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2954 (struct nlattr *)data,
2955 data_len, qca_wlan_vendor_ll_get_policy))
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2958 return -EINVAL;
2959 }
2960
2961 if (!tb_vendor
2962 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2963 {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2965 return -EINVAL;
2966 }
2967
2968 if (!tb_vendor
2969 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2970 {
2971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2972 return -EINVAL;
2973 }
2974
Sunil Duttc69bccb2014-05-26 21:30:20 +05302975
Dino Mycledf0a5d92014-07-04 09:41:55 +05302976 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302977 nla_get_u32( tb_vendor[
2978 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302979 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302980 nla_get_u32( tb_vendor[
2981 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2982
Dino Mycled3d50022014-07-07 12:58:25 +05302983 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2984 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
2986 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302987 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2988 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302989 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302990
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302991 spin_lock(&hdd_context_lock);
2992 context = &pHddCtx->ll_stats_context;
2993 context->request_id = linkLayerStatsGetReq.reqId;
2994 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2995 INIT_COMPLETION(context->response_event);
2996 spin_unlock(&hdd_context_lock);
2997
Sunil Duttc69bccb2014-05-26 21:30:20 +05302998 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302999 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303000 {
3001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3002 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003 return -EINVAL;
3004 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303005
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303006 rc = wait_for_completion_timeout(&context->response_event,
3007 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3008 if (!rc)
3009 {
3010 hddLog(LOGE,
3011 FL("Target response timed out request id %d request bitmap 0x%x"),
3012 context->request_id, context->request_bitmap);
3013 return -ETIMEDOUT;
3014 }
3015
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303016 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017 return 0;
3018}
3019
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303020static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3021 struct wireless_dev *wdev,
3022 const void *data,
3023 int data_len)
3024{
3025 int ret = 0;
3026
3027 vos_ssr_protect(__func__);
3028 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3029 vos_ssr_unprotect(__func__);
3030
3031 return ret;
3032}
3033
Sunil Duttc69bccb2014-05-26 21:30:20 +05303034const struct
3035nla_policy
3036qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3037{
3038 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3039 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3040 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3041 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3042};
3043
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303044static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3045 struct wireless_dev *wdev,
3046 const void *data,
3047 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303048{
3049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3050 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303051 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 struct net_device *dev = wdev->netdev;
3053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3054 u32 statsClearReqMask;
3055 u8 stopReq;
3056 int status;
3057
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303058 ENTER();
3059
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060 status = wlan_hdd_validate_context(pHddCtx);
3061 if (0 != status)
3062 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303063 return -EINVAL;
3064 }
3065
3066 if (NULL == pAdapter)
3067 {
3068 hddLog(VOS_TRACE_LEVEL_FATAL,
3069 "%s: HDD adapter is Null", __func__);
3070 return -ENODEV;
3071 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303072 /* check the LLStats Capability */
3073 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3074 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3075 {
3076 hddLog(VOS_TRACE_LEVEL_ERROR,
3077 FL("Enable LLStats Capability"));
3078 return -EINVAL;
3079 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080
3081 if (!pAdapter->isLinkLayerStatsSet)
3082 {
3083 hddLog(VOS_TRACE_LEVEL_FATAL,
3084 "%s: isLinkLayerStatsSet : %d",
3085 __func__, pAdapter->isLinkLayerStatsSet);
3086 return -EINVAL;
3087 }
3088
3089 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3090 (struct nlattr *)data,
3091 data_len, qca_wlan_vendor_ll_clr_policy))
3092 {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3094 return -EINVAL;
3095 }
3096
3097 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3098
3099 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3100 {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3102 return -EINVAL;
3103
3104 }
3105
Sunil Duttc69bccb2014-05-26 21:30:20 +05303106
Dino Mycledf0a5d92014-07-04 09:41:55 +05303107 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303108 nla_get_u32(
3109 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3110
Dino Mycledf0a5d92014-07-04 09:41:55 +05303111 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303112 nla_get_u8(
3113 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3114
3115 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117
Dino Mycled3d50022014-07-07 12:58:25 +05303118 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3119 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303120
3121 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303122 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3123 "statsClearReqMask = 0x%X, stopReq = %d",
3124 linkLayerStatsClearReq.reqId,
3125 linkLayerStatsClearReq.macAddr,
3126 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303127 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303128
3129 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303130 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303131 {
3132 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303133 hdd_station_ctx_t *pHddStaCtx;
3134
3135 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3136 if (VOS_STATUS_SUCCESS !=
3137 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3138 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3139 {
3140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3141 "WLANTL_ClearInterfaceStats Failed", __func__);
3142 return -EINVAL;
3143 }
3144 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3145 (statsClearReqMask & WIFI_STATS_IFACE)) {
3146 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3147 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3148 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3149 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3150 }
3151
Sunil Duttc69bccb2014-05-26 21:30:20 +05303152 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3153 2 * sizeof(u32) +
3154 NLMSG_HDRLEN);
3155
3156 if (temp_skbuff != NULL)
3157 {
3158
3159 if (nla_put_u32(temp_skbuff,
3160 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3161 statsClearReqMask) ||
3162 nla_put_u32(temp_skbuff,
3163 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3164 stopReq))
3165 {
3166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3167 kfree_skb(temp_skbuff);
3168 return -EINVAL;
3169 }
3170 /* If the ask is to stop the stats collection as part of clear
3171 * (stopReq = 1) , ensure that no further requests of get
3172 * go to the firmware by having isLinkLayerStatsSet set to 0.
3173 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303174 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303175 * case the firmware is just asked to clear the statistics.
3176 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303177 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303178 pAdapter->isLinkLayerStatsSet = 0;
3179 return cfg80211_vendor_cmd_reply(temp_skbuff);
3180 }
3181 return -ENOMEM;
3182 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303183
3184 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303185 return -EINVAL;
3186}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303187static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3188 struct wireless_dev *wdev,
3189 const void *data,
3190 int data_len)
3191{
3192 int ret = 0;
3193
3194 vos_ssr_protect(__func__);
3195 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3196 vos_ssr_unprotect(__func__);
3197
3198 return ret;
3199
3200
3201}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303202#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204#ifdef WLAN_FEATURE_EXTSCAN
3205static const struct nla_policy
3206wlan_hdd_extscan_config_policy
3207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3208{
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3210 { .type = NLA_U32 },
3211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3212 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3214 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3217 { .type = NLA_U32 },
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3220
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3225 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3227 { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3229 { .type = NLA_U32 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3231 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3233 { .type = NLA_U32 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3235 { .type = NLA_U32 },
3236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3237 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3239 { .type = NLA_U8 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 { .type = NLA_U8 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3243 { .type = NLA_U8 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3245 { .type = NLA_U8 },
3246
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3248 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3250 .type = NLA_UNSPEC,
3251 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3253 { .type = NLA_S32 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3255 { .type = NLA_S32 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3257 { .type = NLA_U32 },
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3259 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3261 { .type = NLA_U32 },
3262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3263 { .type = NLA_BINARY,
3264 .len = IEEE80211_MAX_SSID_LEN + 1 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3268 { .type = NLA_U32 },
3269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3270 { .type = NLA_U8 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3272 { .type = NLA_S32 },
3273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3274 { .type = NLA_S32 },
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3276 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277};
3278
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303279/**
3280 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3281 * @ctx: hdd global context
3282 * @data: capabilities data
3283 *
3284 * Return: none
3285 */
3286static void
3287wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303289 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303290 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303291 tSirEXTScanCapabilitiesEvent *data =
3292 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303294 ENTER();
3295
3296 if (wlan_hdd_validate_context(pHddCtx))
3297 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 return;
3299 }
3300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 if (!pMsg)
3302 {
3303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3304 return;
3305 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303307 vos_spin_lock_acquire(&hdd_context_lock);
3308
3309 context = &pHddCtx->ext_scan_context;
3310 /* validate response received from target*/
3311 if (context->request_id != data->requestId)
3312 {
3313 vos_spin_lock_release(&hdd_context_lock);
3314 hddLog(LOGE,
3315 FL("Target response id did not match: request_id %d resposne_id %d"),
3316 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 return;
3318 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 else
3320 {
3321 context->capability_response = *data;
3322 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 }
3324
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303325 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return;
3328}
3329
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303330/*
3331 * define short names for the global vendor params
3332 * used by wlan_hdd_send_ext_scan_capability()
3333 */
3334#define PARAM_REQUEST_ID \
3335 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3336#define PARAM_STATUS \
3337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3338#define MAX_SCAN_CACHE_SIZE \
3339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3340#define MAX_SCAN_BUCKETS \
3341 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3342#define MAX_AP_CACHE_PER_SCAN \
3343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3344#define MAX_RSSI_SAMPLE_SIZE \
3345 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3346#define MAX_SCAN_RPT_THRHOLD \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3348#define MAX_HOTLIST_BSSIDS \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3350#define MAX_BSSID_HISTORY_ENTRIES \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3352#define MAX_HOTLIST_SSIDS \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303354#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303356
3357static int wlan_hdd_send_ext_scan_capability(void *ctx)
3358{
3359 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3360 struct sk_buff *skb = NULL;
3361 int ret;
3362 tSirEXTScanCapabilitiesEvent *data;
3363 tANI_U32 nl_buf_len;
3364
3365 ret = wlan_hdd_validate_context(pHddCtx);
3366 if (0 != ret)
3367 {
3368 return ret;
3369 }
3370
3371 data = &(pHddCtx->ext_scan_context.capability_response);
3372
3373 nl_buf_len = NLMSG_HDRLEN;
3374 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3375 (sizeof(data->status) + NLA_HDRLEN) +
3376 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3377 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3378 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3379 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3380 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3381 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3382 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3383 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3384
3385 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3386
3387 if (!skb)
3388 {
3389 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3390 return -ENOMEM;
3391 }
3392
3393 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3394 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3395 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3396 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3397 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3398 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3399 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3400 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3401
3402 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3403 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3404 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3405 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3406 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3407 data->maxApPerScan) ||
3408 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3409 data->maxRssiSampleSize) ||
3410 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3411 data->maxScanReportingThreshold) ||
3412 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3413 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3414 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303415 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3416 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303417 {
3418 hddLog(LOGE, FL("nla put fail"));
3419 goto nla_put_failure;
3420 }
3421
3422 cfg80211_vendor_cmd_reply(skb);
3423 return 0;
3424
3425nla_put_failure:
3426 kfree_skb(skb);
3427 return -EINVAL;;
3428}
3429
3430/*
3431 * done with short names for the global vendor params
3432 * used by wlan_hdd_send_ext_scan_capability()
3433 */
3434#undef PARAM_REQUEST_ID
3435#undef PARAM_STATUS
3436#undef MAX_SCAN_CACHE_SIZE
3437#undef MAX_SCAN_BUCKETS
3438#undef MAX_AP_CACHE_PER_SCAN
3439#undef MAX_RSSI_SAMPLE_SIZE
3440#undef MAX_SCAN_RPT_THRHOLD
3441#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303442#undef MAX_BSSID_HISTORY_ENTRIES
3443#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444
3445static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3446{
3447 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3448 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303450 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303452 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303454 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303457 if (!pMsg)
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 return;
3461 }
3462
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3464 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3465
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466 context = &pHddCtx->ext_scan_context;
3467 spin_lock(&hdd_context_lock);
3468 if (context->request_id == pData->requestId) {
3469 context->response_status = pData->status ? -EINVAL : 0;
3470 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303472 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473
3474 /*
3475 * Store the Request ID for comparing with the requestID obtained
3476 * in other requests.HDD shall return a failure is the extscan_stop
3477 * request is issued with a different requestId as that of the
3478 * extscan_start request. Also, This requestId shall be used while
3479 * indicating the full scan results to the upper layers.
3480 * The requestId is stored with the assumption that the firmware
3481 * shall return the ext scan start request's requestId in ext scan
3482 * start response.
3483 */
3484 if (pData->status == 0)
3485 pMac->sme.extScanStartReqId = pData->requestId;
3486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489}
3490
3491
3492static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3493{
3494 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3495 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303496 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303498 ENTER();
3499
3500 if (wlan_hdd_validate_context(pHddCtx)){
3501 return;
3502 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303504 if (!pMsg)
3505 {
3506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507 return;
3508 }
3509
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303510 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3511 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303513 context = &pHddCtx->ext_scan_context;
3514 spin_lock(&hdd_context_lock);
3515 if (context->request_id == pData->requestId) {
3516 context->response_status = pData->status ? -EINVAL : 0;
3517 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303521 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523}
3524
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3526 void *pMsg)
3527{
3528 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 tpSirEXTScanSetBssidHotListRspParams pData =
3530 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303531 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303533 ENTER();
3534
3535 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 return;
3537 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303539 if (!pMsg)
3540 {
3541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3542 return;
3543 }
3544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303545 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3546 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303548 context = &pHddCtx->ext_scan_context;
3549 spin_lock(&hdd_context_lock);
3550 if (context->request_id == pData->requestId) {
3551 context->response_status = pData->status ? -EINVAL : 0;
3552 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303556 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558}
3559
3560static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3561 void *pMsg)
3562{
3563 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 tpSirEXTScanResetBssidHotlistRspParams pData =
3565 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303566 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303568 ENTER();
3569
3570 if (wlan_hdd_validate_context(pHddCtx)) {
3571 return;
3572 }
3573 if (!pMsg)
3574 {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 return;
3577 }
3578
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3580 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303582 context = &pHddCtx->ext_scan_context;
3583 spin_lock(&hdd_context_lock);
3584 if (context->request_id == pData->requestId) {
3585 context->response_status = pData->status ? -EINVAL : 0;
3586 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303590 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592}
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3595 void *pMsg)
3596{
3597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 tANI_S32 totalResults;
3601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3603 struct hdd_ext_scan_context *context;
3604 bool ignore_cached_results = false;
3605 tExtscanCachedScanResult *result;
3606 struct nlattr *nla_results;
3607 tANI_U16 ieLength= 0;
3608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303610 ENTER();
3611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303615 if (!pMsg)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3618 return;
3619 }
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 spin_lock(&hdd_context_lock);
3622 context = &pHddCtx->ext_scan_context;
3623 ignore_cached_results = context->ignore_cached_results;
3624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 if (ignore_cached_results) {
3627 hddLog(LOGE,
3628 FL("Ignore the cached results received after timeout"));
3629 return;
3630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3638 scan_id_index++) {
3639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 totalResults = result->num_results;
3642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3643 result->scan_id, result->flags, totalResults);
3644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 do{
3647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3653
3654 if (!skb) {
3655 hddLog(VOS_TRACE_LEVEL_ERROR,
3656 FL("cfg80211_vendor_event_alloc failed"));
3657 return;
3658 }
3659
3660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3661
3662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3663 pData->requestId) ||
3664 nla_put_u32(skb,
3665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3666 resultsPerEvent)) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put_u8(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3675 goto fail;
3676 }
3677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303678 if (nla_put_u32(skb,
3679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3680 result->scan_id)) {
3681 hddLog(LOGE, FL("put fail"));
3682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303685 nla_results = nla_nest_start(skb,
3686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3687 if (!nla_results)
3688 goto fail;
3689
3690 if (resultsPerEvent) {
3691 struct nlattr *aps;
3692 struct nlattr *nla_result;
3693
3694 nla_result = nla_nest_start(skb, scan_id_index);
3695 if(!nla_result)
3696 goto fail;
3697
3698 if (nla_put_u32(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3700 result->scan_id) ||
3701 nla_put_u32(skb,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3703 result->flags) ||
3704 nla_put_u32(skb,
3705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3706 totalResults)) {
3707 hddLog(LOGE, FL("put fail"));
3708 goto fail;
3709 }
3710
3711 aps = nla_nest_start(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3713 if (!aps)
3714 {
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3716 goto fail;
3717 }
3718
3719 head_ptr = (tpSirWifiScanResult) &(result->ap);
3720
3721 for (j = 0; j < resultsPerEvent; j++, i++) {
3722 struct nlattr *ap;
3723 pSirWifiScanResult = head_ptr + i;
3724
3725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303726 * Firmware returns timestamp from extscan_start till
3727 * BSSID was cached (in micro seconds). Add this with
3728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303729 * to derive the time since boot when the
3730 * BSSID was cached.
3731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303732 pSirWifiScanResult->ts +=
3733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3735 "Ssid (%s)"
3736 "Bssid: %pM "
3737 "Channel (%u)"
3738 "Rssi (%d)"
3739 "RTT (%u)"
3740 "RTT_SD (%u)"
3741 "Beacon Period %u"
3742 "Capability 0x%x "
3743 "Ie length %d",
3744 i,
3745 pSirWifiScanResult->ts,
3746 pSirWifiScanResult->ssid,
3747 pSirWifiScanResult->bssid,
3748 pSirWifiScanResult->channel,
3749 pSirWifiScanResult->rssi,
3750 pSirWifiScanResult->rtt,
3751 pSirWifiScanResult->rtt_sd,
3752 pSirWifiScanResult->beaconPeriod,
3753 pSirWifiScanResult->capability,
3754 ieLength);
3755
3756 ap = nla_nest_start(skb, j + 1);
3757 if (!ap)
3758 {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3760 goto fail;
3761 }
3762
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303763 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3765 pSirWifiScanResult->ts) )
3766 {
3767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3768 goto fail;
3769 }
3770 if (nla_put(skb,
3771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3772 sizeof(pSirWifiScanResult->ssid),
3773 pSirWifiScanResult->ssid) )
3774 {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3776 goto fail;
3777 }
3778 if (nla_put(skb,
3779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3780 sizeof(pSirWifiScanResult->bssid),
3781 pSirWifiScanResult->bssid) )
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3784 goto fail;
3785 }
3786 if (nla_put_u32(skb,
3787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3788 pSirWifiScanResult->channel) )
3789 {
3790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3791 goto fail;
3792 }
3793 if (nla_put_s32(skb,
3794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3795 pSirWifiScanResult->rssi) )
3796 {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3798 goto fail;
3799 }
3800 if (nla_put_u32(skb,
3801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3802 pSirWifiScanResult->rtt) )
3803 {
3804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3805 goto fail;
3806 }
3807 if (nla_put_u32(skb,
3808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3809 pSirWifiScanResult->rtt_sd))
3810 {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3812 goto fail;
3813 }
3814 if (nla_put_u32(skb,
3815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3816 pSirWifiScanResult->beaconPeriod))
3817 {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3819 goto fail;
3820 }
3821 if (nla_put_u32(skb,
3822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3823 pSirWifiScanResult->capability))
3824 {
3825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3826 goto fail;
3827 }
3828 if (nla_put_u32(skb,
3829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3830 ieLength))
3831 {
3832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3833 goto fail;
3834 }
3835
3836 if (ieLength)
3837 if (nla_put(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3839 ieLength, ie)) {
3840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3841 goto fail;
3842 }
3843
3844 nla_nest_end(skb, ap);
3845 }
3846 nla_nest_end(skb, aps);
3847 nla_nest_end(skb, nla_result);
3848 }
3849
3850 nla_nest_end(skb, nla_results);
3851
3852 cfg80211_vendor_cmd_reply(skb);
3853
3854 } while (totalResults > 0);
3855 }
3856
3857 if (!pData->moreData) {
3858 spin_lock(&hdd_context_lock);
3859 context->response_status = 0;
3860 complete(&context->response_event);
3861 spin_unlock(&hdd_context_lock);
3862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303865 return;
3866fail:
3867 kfree_skb(skb);
3868 return;
3869}
3870
3871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3872 void *pMsg)
3873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 ENTER();
3880
3881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303882 hddLog(LOGE,
3883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303884 return;
3885 }
3886 if (!pMsg)
3887 {
3888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889 return;
3890 }
3891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303892 if (pData->bss_found)
3893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3894 else
3895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3899 NULL,
3900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303903
3904 if (!skb) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR,
3906 FL("cfg80211_vendor_event_alloc failed"));
3907 return;
3908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3914
3915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3917 "Ssid (%s) "
3918 "Bssid (" MAC_ADDRESS_STR ") "
3919 "Channel (%u) "
3920 "Rssi (%d) "
3921 "RTT (%u) "
3922 "RTT_SD (%u) ",
3923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303924 pData->bssHotlist[i].ts,
3925 pData->bssHotlist[i].ssid,
3926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3927 pData->bssHotlist[i].channel,
3928 pData->bssHotlist[i].rssi,
3929 pData->bssHotlist[i].rtt,
3930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931 }
3932
3933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3934 pData->requestId) ||
3935 nla_put_u32(skb,
3936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3939 goto fail;
3940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 struct nlattr *aps;
3943
3944 aps = nla_nest_start(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3946 if (!aps)
3947 goto fail;
3948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 struct nlattr *ap;
3951
3952 ap = nla_nest_start(skb, i + 1);
3953 if (!ap)
3954 goto fail;
3955
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303956 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 nla_put(skb,
3960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303961 sizeof(pData->bssHotlist[i].ssid),
3962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303963 nla_put(skb,
3964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303965 sizeof(pData->bssHotlist[i].bssid),
3966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 nla_put_u32(skb,
3968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 nla_put_s32(skb,
3971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 nla_put_u32(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 goto fail;
3980
3981 nla_nest_end(skb, ap);
3982 }
3983 nla_nest_end(skb, aps);
3984
3985 if (nla_put_u8(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3987 pData->moreData))
3988 goto fail;
3989 }
3990
3991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303993 return;
3994
3995fail:
3996 kfree_skb(skb);
3997 return;
3998
3999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304000
4001static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4002 void *pMsg)
4003{
4004 struct sk_buff *skb;
4005 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4006 tpSirWifiFullScanResultEvent pData =
4007 (tpSirWifiFullScanResultEvent) (pMsg);
4008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304009 ENTER();
4010
4011 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304012 hddLog(LOGE,
4013 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 return;
4015 }
4016 if (!pMsg)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 return;
4020 }
4021
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304022 /*
4023 * If the full scan result including IE data exceeds NL 4K size
4024 * limitation, drop that beacon/probe rsp frame.
4025 */
4026 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4027 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4028 return;
4029 }
4030
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4033 NULL,
4034#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304035 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4036 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4037 GFP_KERNEL);
4038
4039 if (!skb) {
4040 hddLog(VOS_TRACE_LEVEL_ERROR,
4041 FL("cfg80211_vendor_event_alloc failed"));
4042 return;
4043 }
4044
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4046 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4047 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4048 "Ssid (%s)"
4049 "Bssid (" MAC_ADDRESS_STR ")"
4050 "Channel (%u)"
4051 "Rssi (%d)"
4052 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304053 "RTT_SD (%u)"
4054 "Bcn Period %d"
4055 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pData->ap.ts,
4057 pData->ap.ssid,
4058 MAC_ADDR_ARRAY(pData->ap.bssid),
4059 pData->ap.channel,
4060 pData->ap.rssi,
4061 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 pData->ap.rtt_sd,
4063 pData->ap.beaconPeriod,
4064 pData->ap.capability);
4065
Dino Mycle6fb96c12014-06-10 11:52:40 +05304066 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4067 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4068 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304069 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4071 pData->ap.ts) ||
4072 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4073 sizeof(pData->ap.ssid),
4074 pData->ap.ssid) ||
4075 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4076 WNI_CFG_BSSID_LEN,
4077 pData->ap.bssid) ||
4078 nla_put_u32(skb,
4079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4080 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304081 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 pData->ap.rssi) ||
4083 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4084 pData->ap.rtt) ||
4085 nla_put_u32(skb,
4086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4087 pData->ap.rtt_sd) ||
4088 nla_put_u16(skb,
4089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4090 pData->ap.beaconPeriod) ||
4091 nla_put_u16(skb,
4092 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4093 pData->ap.capability) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304096 pData->ieLength) ||
4097 nla_put_u8(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4099 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100 {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4102 goto nla_put_failure;
4103 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304104
4105 if (pData->ieLength) {
4106 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4107 pData->ieLength,
4108 pData->ie))
4109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304113 }
4114
4115 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304116 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 return;
4118
4119nla_put_failure:
4120 kfree_skb(skb);
4121 return;
4122}
4123
4124static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4125 void *pMsg)
4126{
4127 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4128 struct sk_buff *skb = NULL;
4129 tpSirEXTScanResultsAvailableIndParams pData =
4130 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4131
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304132 ENTER();
4133
4134 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304135 hddLog(LOGE,
4136 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304137 return;
4138 }
4139 if (!pMsg)
4140 {
4141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 return;
4143 }
4144
4145 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4147 NULL,
4148#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4150 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4151 GFP_KERNEL);
4152
4153 if (!skb) {
4154 hddLog(VOS_TRACE_LEVEL_ERROR,
4155 FL("cfg80211_vendor_event_alloc failed"));
4156 return;
4157 }
4158
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4160 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4161 pData->numResultsAvailable);
4162 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4163 pData->requestId) ||
4164 nla_put_u32(skb,
4165 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4166 pData->numResultsAvailable)) {
4167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4168 goto nla_put_failure;
4169 }
4170
4171 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304172 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173 return;
4174
4175nla_put_failure:
4176 kfree_skb(skb);
4177 return;
4178}
4179
4180static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4181{
4182 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4183 struct sk_buff *skb = NULL;
4184 tpSirEXTScanProgressIndParams pData =
4185 (tpSirEXTScanProgressIndParams) pMsg;
4186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304187 ENTER();
4188
4189 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304190 hddLog(LOGE,
4191 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304192 return;
4193 }
4194 if (!pMsg)
4195 {
4196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304197 return;
4198 }
4199
4200 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4202 NULL,
4203#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4205 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4206 GFP_KERNEL);
4207
4208 if (!skb) {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,
4210 FL("cfg80211_vendor_event_alloc failed"));
4211 return;
4212 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4215 pData->extScanEventType);
4216 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4217 pData->status);
4218
4219 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4220 pData->extScanEventType) ||
4221 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4223 pData->requestId) ||
4224 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4226 pData->status)) {
4227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4228 goto nla_put_failure;
4229 }
4230
4231 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304232 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 return;
4234
4235nla_put_failure:
4236 kfree_skb(skb);
4237 return;
4238}
4239
4240void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4241 void *pMsg)
4242{
4243 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304245 ENTER();
4246
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 return;
4249 }
4250
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4252
4253
4254 switch(evType) {
4255 case SIR_HAL_EXTSCAN_START_RSP:
4256 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4257 break;
4258
4259 case SIR_HAL_EXTSCAN_STOP_RSP:
4260 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4261 break;
4262 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4263 /* There is no need to send this response to upper layer
4264 Just log the message */
4265 hddLog(VOS_TRACE_LEVEL_INFO,
4266 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4267 break;
4268 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4269 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4270 break;
4271
4272 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4273 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4274 break;
4275
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304277 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 break;
4279 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4280 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4281 break;
4282 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4283 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4284 break;
4285 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4286 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4287 break;
4288 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4289 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4290 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4292 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4293 break;
4294 default:
4295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4296 break;
4297 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304298 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299}
4300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304301static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4302 struct wireless_dev *wdev,
4303 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304{
Dino Myclee8843b32014-07-04 14:21:45 +05304305 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304306 struct net_device *dev = wdev->netdev;
4307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4309 struct nlattr
4310 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4311 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304312 struct hdd_ext_scan_context *context;
4313 unsigned long rc;
4314 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304316 ENTER();
4317
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 status = wlan_hdd_validate_context(pHddCtx);
4319 if (0 != status)
4320 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
Dino Myclee8843b32014-07-04 14:21:45 +05304323 /* check the EXTScan Capability */
4324 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304325 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4326 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("EXTScan not enabled/supported by Firmware"));
4330 return -EINVAL;
4331 }
4332
Dino Mycle6fb96c12014-06-10 11:52:40 +05304333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4334 data, dataLen,
4335 wlan_hdd_extscan_config_policy)) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4337 return -EINVAL;
4338 }
4339
4340 /* Parse and fetch request Id */
4341 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4343 return -EINVAL;
4344 }
4345
Dino Myclee8843b32014-07-04 14:21:45 +05304346 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304347 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.sessionId = pAdapter->sessionId;
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304353 vos_spin_lock_acquire(&hdd_context_lock);
4354 context = &pHddCtx->ext_scan_context;
4355 context->request_id = reqMsg.requestId;
4356 INIT_COMPLETION(context->response_event);
4357 vos_spin_lock_release(&hdd_context_lock);
4358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360 if (!HAL_STATUS_SUCCESS(status)) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR,
4362 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363 return -EINVAL;
4364 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304365
4366 rc = wait_for_completion_timeout(&context->response_event,
4367 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4368 if (!rc) {
4369 hddLog(LOGE, FL("Target response timed out"));
4370 return -ETIMEDOUT;
4371 }
4372
4373 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4374 if (ret)
4375 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4376
4377 return ret;
4378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304379 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304380 return 0;
4381}
4382
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304383static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4384 struct wireless_dev *wdev,
4385 const void *data, int dataLen)
4386{
4387 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304389 vos_ssr_protect(__func__);
4390 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4391 vos_ssr_unprotect(__func__);
4392
4393 return ret;
4394}
4395
4396static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
4398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr
4405 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4406 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304407 struct hdd_ext_scan_context *context;
4408 unsigned long rc;
4409 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304411 ENTER();
4412
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304413 if (VOS_FTM_MODE == hdd_get_conparam()) {
4414 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4415 return -EINVAL;
4416 }
4417
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 status = wlan_hdd_validate_context(pHddCtx);
4419 if (0 != status)
4420 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304421 return -EINVAL;
4422 }
Dino Myclee8843b32014-07-04 14:21:45 +05304423 /* check the EXTScan Capability */
4424 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304425 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4426 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304427 {
4428 hddLog(VOS_TRACE_LEVEL_ERROR,
4429 FL("EXTScan not enabled/supported by Firmware"));
4430 return -EINVAL;
4431 }
4432
Dino Mycle6fb96c12014-06-10 11:52:40 +05304433 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4434 data, dataLen,
4435 wlan_hdd_extscan_config_policy)) {
4436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4437 return -EINVAL;
4438 }
4439 /* Parse and fetch request Id */
4440 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4442 return -EINVAL;
4443 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304444
Dino Myclee8843b32014-07-04 14:21:45 +05304445 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4447
Dino Myclee8843b32014-07-04 14:21:45 +05304448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304449
Dino Myclee8843b32014-07-04 14:21:45 +05304450 reqMsg.sessionId = pAdapter->sessionId;
4451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452
4453 /* Parse and fetch flush parameter */
4454 if (!tb
4455 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4456 {
4457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4458 goto failed;
4459 }
Dino Myclee8843b32014-07-04 14:21:45 +05304460 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4462
Dino Myclee8843b32014-07-04 14:21:45 +05304463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304464
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304465 spin_lock(&hdd_context_lock);
4466 context = &pHddCtx->ext_scan_context;
4467 context->request_id = reqMsg.requestId;
4468 context->ignore_cached_results = false;
4469 INIT_COMPLETION(context->response_event);
4470 spin_unlock(&hdd_context_lock);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473 if (!HAL_STATUS_SUCCESS(status)) {
4474 hddLog(VOS_TRACE_LEVEL_ERROR,
4475 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304476 return -EINVAL;
4477 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304478
4479 rc = wait_for_completion_timeout(&context->response_event,
4480 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4481 if (!rc) {
4482 hddLog(LOGE, FL("Target response timed out"));
4483 retval = -ETIMEDOUT;
4484 spin_lock(&hdd_context_lock);
4485 context->ignore_cached_results = true;
4486 spin_unlock(&hdd_context_lock);
4487 } else {
4488 spin_lock(&hdd_context_lock);
4489 retval = context->response_status;
4490 spin_unlock(&hdd_context_lock);
4491 }
4492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304493 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304494 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495
4496failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304497 return -EINVAL;
4498}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304499static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4500 struct wireless_dev *wdev,
4501 const void *data, int dataLen)
4502{
4503 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304505 vos_ssr_protect(__func__);
4506 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4507 vos_ssr_unprotect(__func__);
4508
4509 return ret;
4510}
4511
4512static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304514 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304515{
4516 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4517 struct net_device *dev = wdev->netdev;
4518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4520 struct nlattr
4521 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4522 struct nlattr
4523 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4524 struct nlattr *apTh;
4525 eHalStatus status;
4526 tANI_U8 i = 0;
4527 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304528 struct hdd_ext_scan_context *context;
4529 tANI_U32 request_id;
4530 unsigned long rc;
4531 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304535 if (VOS_FTM_MODE == hdd_get_conparam()) {
4536 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4537 return -EINVAL;
4538 }
4539
Dino Mycle6fb96c12014-06-10 11:52:40 +05304540 status = wlan_hdd_validate_context(pHddCtx);
4541 if (0 != status)
4542 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304543 return -EINVAL;
4544 }
Dino Myclee8843b32014-07-04 14:21:45 +05304545 /* check the EXTScan Capability */
4546 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304547 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4548 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304549 {
4550 hddLog(VOS_TRACE_LEVEL_ERROR,
4551 FL("EXTScan not enabled/supported by Firmware"));
4552 return -EINVAL;
4553 }
4554
Dino Mycle6fb96c12014-06-10 11:52:40 +05304555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4556 data, dataLen,
4557 wlan_hdd_extscan_config_policy)) {
4558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4559 return -EINVAL;
4560 }
4561
4562 /* Parse and fetch request Id */
4563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4565 return -EINVAL;
4566 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4568 vos_mem_malloc(sizeof(*pReqMsg));
4569 if (!pReqMsg) {
4570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4571 return -ENOMEM;
4572 }
4573
Dino Myclee8843b32014-07-04 14:21:45 +05304574
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 pReqMsg->requestId = nla_get_u32(
4576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4578
4579 /* Parse and fetch number of APs */
4580 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4582 goto fail;
4583 }
4584
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304585 /* Parse and fetch lost ap sample size */
4586 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4587 hddLog(LOGE, FL("attr lost ap sample size failed"));
4588 goto fail;
4589 }
4590
4591 pReqMsg->lostBssidSampleSize = nla_get_u32(
4592 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4593 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595 pReqMsg->sessionId = pAdapter->sessionId;
4596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4597
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304598 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304600 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4601 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4602 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4603 goto fail;
4604 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
4607 nla_for_each_nested(apTh,
4608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (i == pReqMsg->numBssid) {
4610 hddLog(LOGW, FL("Ignoring excess AP"));
4611 break;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4615 nla_data(apTh), nla_len(apTh),
4616 NULL)) {
4617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4618 goto fail;
4619 }
4620
4621 /* Parse and fetch MAC address */
4622 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4624 goto fail;
4625 }
4626 memcpy(pReqMsg->ap[i].bssid, nla_data(
4627 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4628 sizeof(tSirMacAddr));
4629 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4630
4631 /* Parse and fetch low RSSI */
4632 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4634 goto fail;
4635 }
4636 pReqMsg->ap[i].low = nla_get_s32(
4637 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4639
4640 /* Parse and fetch high RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].high = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4648 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 i++;
4650 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304651
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304652 if (i < pReqMsg->numBssid) {
4653 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4654 i, pReqMsg->numBssid);
4655 pReqMsg->numBssid = i;
4656 }
4657
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304658 context = &pHddCtx->ext_scan_context;
4659 spin_lock(&hdd_context_lock);
4660 INIT_COMPLETION(context->response_event);
4661 context->request_id = request_id = pReqMsg->requestId;
4662 spin_unlock(&hdd_context_lock);
4663
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4665 if (!HAL_STATUS_SUCCESS(status)) {
4666 hddLog(VOS_TRACE_LEVEL_ERROR,
4667 FL("sme_SetBssHotlist failed(err=%d)"), status);
4668 vos_mem_free(pReqMsg);
4669 return -EINVAL;
4670 }
4671
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304672 /* request was sent -- wait for the response */
4673 rc = wait_for_completion_timeout(&context->response_event,
4674 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4675
4676 if (!rc) {
4677 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4678 retval = -ETIMEDOUT;
4679 } else {
4680 spin_lock(&hdd_context_lock);
4681 if (context->request_id == request_id)
4682 retval = context->response_status;
4683 else
4684 retval = -EINVAL;
4685 spin_unlock(&hdd_context_lock);
4686 }
4687
Dino Myclee8843b32014-07-04 14:21:45 +05304688 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304689 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304690 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304691
4692fail:
4693 vos_mem_free(pReqMsg);
4694 return -EINVAL;
4695}
4696
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304697static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4698 struct wireless_dev *wdev,
4699 const void *data, int dataLen)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4705 dataLen);
4706 vos_ssr_unprotect(__func__);
4707
4708 return ret;
4709}
4710
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304711static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304713 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4716 struct net_device *dev = wdev->netdev;
4717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4718 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4719 uint8_t num_channels = 0;
4720 uint8_t num_chan_new = 0;
4721 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304723 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 tWifiBand wifiBand;
4725 eHalStatus status;
4726 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304727 tANI_U8 i,j,k;
4728 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 ENTER();
4731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 status = wlan_hdd_validate_context(pHddCtx);
4733 if (0 != status)
4734 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 return -EINVAL;
4736 }
Dino Myclee8843b32014-07-04 14:21:45 +05304737
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4739 data, dataLen,
4740 wlan_hdd_extscan_config_policy)) {
4741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4742 return -EINVAL;
4743 }
4744
4745 /* Parse and fetch request Id */
4746 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4748 return -EINVAL;
4749 }
4750 requestId = nla_get_u32(
4751 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4753
4754 /* Parse and fetch wifi band */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4756 {
4757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4758 return -EINVAL;
4759 }
4760 wifiBand = nla_get_u32(
4761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4763
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304764 /* Parse and fetch max channels */
4765 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4766 {
4767 hddLog(LOGE, FL("attr max channels failed"));
4768 return -EINVAL;
4769 }
4770 maxChannels = nla_get_u32(
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4773
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304775 wifiBand, chan_list,
4776 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304777 if (eHAL_STATUS_SUCCESS != status) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR,
4779 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4780 return -EINVAL;
4781 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304782
Agrawal Ashish16abf782016-08-18 22:42:59 +05304783 num_channels = VOS_MIN(num_channels, maxChannels);
4784 num_chan_new = num_channels;
4785 /* remove the indoor only channels if iface is SAP */
4786 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4787 {
4788 num_chan_new = 0;
4789 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304790 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304791 if (wiphy->bands[j] == NULL)
4792 continue;
4793 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4794 if ((chan_list[i] ==
4795 wiphy->bands[j]->channels[k].center_freq) &&
4796 (!(wiphy->bands[j]->channels[k].flags &
4797 IEEE80211_CHAN_INDOOR_ONLY))) {
4798 chan_list[num_chan_new] = chan_list[i];
4799 num_chan_new++;
4800 }
4801 }
4802 }
4803 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304804
Agrawal Ashish16abf782016-08-18 22:42:59 +05304805 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4806 for (i = 0; i < num_chan_new; i++)
4807 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4808 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809
4810 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304811 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 NLMSG_HDRLEN);
4813
4814 if (!replySkb) {
4815 hddLog(VOS_TRACE_LEVEL_ERROR,
4816 FL("valid channels: buffer alloc fail"));
4817 return -EINVAL;
4818 }
4819 if (nla_put_u32(replySkb,
4820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304821 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304823 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
4825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4826 kfree_skb(replySkb);
4827 return -EINVAL;
4828 }
4829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304830 ret = cfg80211_vendor_cmd_reply(replySkb);
4831
4832 EXIT();
4833 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834}
4835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304836static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4837 struct wireless_dev *wdev,
4838 const void *data, int dataLen)
4839{
4840 int ret = 0;
4841
4842 vos_ssr_protect(__func__);
4843 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4844 dataLen);
4845 vos_ssr_unprotect(__func__);
4846
4847 return ret;
4848}
4849
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304850static int hdd_extscan_start_fill_bucket_channel_spec(
4851 hdd_context_t *pHddCtx,
4852 tpSirEXTScanStartReqParams pReqMsg,
4853 struct nlattr **tb)
4854{
4855 struct nlattr *bucket[
4856 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4857 struct nlattr *channel[
4858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4859 struct nlattr *buckets;
4860 struct nlattr *channels;
4861 int rem1, rem2;
4862 eHalStatus status;
4863 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304864 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304865 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4866 tANI_U32 passive_max_chn_time, active_max_chn_time;
4867
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304868 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304869 bktIndex = 0;
4870
4871 nla_for_each_nested(buckets,
4872 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 if (bktIndex >= expected_buckets) {
4874 hddLog(LOGW, FL("ignoring excess buckets"));
4875 break;
4876 }
4877
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304879 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4880 nla_data(buckets), nla_len(buckets),
4881 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304882 hddLog(LOGE, FL("nla_parse failed"));
4883 return -EINVAL;
4884 }
4885
4886 /* Parse and fetch bucket spec */
4887 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4888 hddLog(LOGE, FL("attr bucket index failed"));
4889 return -EINVAL;
4890 }
4891 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4892 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4893 hddLog(LOG1, FL("Bucket spec Index %d"),
4894 pReqMsg->buckets[bktIndex].bucket);
4895
4896 /* Parse and fetch wifi band */
4897 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4898 hddLog(LOGE, FL("attr wifi band failed"));
4899 return -EINVAL;
4900 }
4901 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4902 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4903 hddLog(LOG1, FL("Wifi band %d"),
4904 pReqMsg->buckets[bktIndex].band);
4905
4906 /* Parse and fetch period */
4907 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4908 hddLog(LOGE, FL("attr period failed"));
4909 return -EINVAL;
4910 }
4911 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4912 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4913 hddLog(LOG1, FL("period %d"),
4914 pReqMsg->buckets[bktIndex].period);
4915
4916 /* Parse and fetch report events */
4917 if (!bucket[
4918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4919 hddLog(LOGE, FL("attr report events failed"));
4920 return -EINVAL;
4921 }
4922 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4923 bucket[
4924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4925 hddLog(LOG1, FL("report events %d"),
4926 pReqMsg->buckets[bktIndex].reportEvents);
4927
4928 /* Parse and fetch max period */
4929 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4930 hddLog(LOGE, FL("attr max period failed"));
4931 return -EINVAL;
4932 }
4933 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4934 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4935 hddLog(LOG1, FL("max period %u"),
4936 pReqMsg->buckets[bktIndex].max_period);
4937
4938 /* Parse and fetch exponent */
4939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4940 hddLog(LOGE, FL("attr exponent failed"));
4941 return -EINVAL;
4942 }
4943 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4944 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4945 hddLog(LOG1, FL("exponent %u"),
4946 pReqMsg->buckets[bktIndex].exponent);
4947
4948 /* Parse and fetch step count */
4949 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4950 hddLog(LOGE, FL("attr step count failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4954 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4955 hddLog(LOG1, FL("Step count %u"),
4956 pReqMsg->buckets[bktIndex].step_count);
4957
4958 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4959 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4960
4961 /* Framework shall pass the channel list if the input WiFi band is
4962 * WIFI_BAND_UNSPECIFIED.
4963 * If the input WiFi band is specified (any value other than
4964 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4965 */
4966 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4967 numChannels = 0;
4968 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4969 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4970 pReqMsg->buckets[bktIndex].band,
4971 chanList, &numChannels);
4972 if (!HAL_STATUS_SUCCESS(status)) {
4973 hddLog(LOGE,
4974 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4975 status);
4976 return -EINVAL;
4977 }
4978
4979 pReqMsg->buckets[bktIndex].numChannels =
4980 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4981 hddLog(LOG1, FL("Num channels %d"),
4982 pReqMsg->buckets[bktIndex].numChannels);
4983
4984 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4985 j++) {
4986 pReqMsg->buckets[bktIndex].channels[j].channel =
4987 chanList[j];
4988 pReqMsg->buckets[bktIndex].channels[j].
4989 chnlClass = 0;
4990 if (CSR_IS_CHANNEL_DFS(
4991 vos_freq_to_chan(chanList[j]))) {
4992 pReqMsg->buckets[bktIndex].channels[j].
4993 passive = 1;
4994 pReqMsg->buckets[bktIndex].channels[j].
4995 dwellTimeMs = passive_max_chn_time;
4996 } else {
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 passive = 0;
4999 pReqMsg->buckets[bktIndex].channels[j].
5000 dwellTimeMs = active_max_chn_time;
5001 }
5002
5003 hddLog(LOG1,
5004 "Channel %u Passive %u Dwell time %u ms",
5005 pReqMsg->buckets[bktIndex].channels[j].channel,
5006 pReqMsg->buckets[bktIndex].channels[j].passive,
5007 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5008 }
5009
5010 bktIndex++;
5011 continue;
5012 }
5013
5014 /* Parse and fetch number of channels */
5015 if (!bucket[
5016 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5017 hddLog(LOGE, FL("attr num channels failed"));
5018 return -EINVAL;
5019 }
5020
5021 pReqMsg->buckets[bktIndex].numChannels =
5022 nla_get_u32(bucket[
5023 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5024 hddLog(LOG1, FL("num channels %d"),
5025 pReqMsg->buckets[bktIndex].numChannels);
5026
5027 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5028 hddLog(LOGE, FL("attr channel spec failed"));
5029 return -EINVAL;
5030 }
5031
5032 j = 0;
5033 nla_for_each_nested(channels,
5034 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5035 if (nla_parse(channel,
5036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5037 nla_data(channels), nla_len(channels),
5038 wlan_hdd_extscan_config_policy)) {
5039 hddLog(LOGE, FL("nla_parse failed"));
5040 return -EINVAL;
5041 }
5042
5043 /* Parse and fetch channel */
5044 if (!channel[
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5046 hddLog(LOGE, FL("attr channel failed"));
5047 return -EINVAL;
5048 }
5049 pReqMsg->buckets[bktIndex].channels[j].channel =
5050 nla_get_u32(channel[
5051 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5052 hddLog(LOG1, FL("channel %u"),
5053 pReqMsg->buckets[bktIndex].channels[j].channel);
5054
5055 /* Parse and fetch dwell time */
5056 if (!channel[
5057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5058 hddLog(LOGE, FL("attr dwelltime failed"));
5059 return -EINVAL;
5060 }
5061 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5062 nla_get_u32(channel[
5063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5064
5065 hddLog(LOG1, FL("Dwell time (%u ms)"),
5066 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5067
5068
5069 /* Parse and fetch channel spec passive */
5070 if (!channel[
5071 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5072 hddLog(LOGE,
5073 FL("attr channel spec passive failed"));
5074 return -EINVAL;
5075 }
5076 pReqMsg->buckets[bktIndex].channels[j].passive =
5077 nla_get_u8(channel[
5078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5079 hddLog(LOG1, FL("Chnl spec passive %u"),
5080 pReqMsg->buckets[bktIndex].channels[j].passive);
5081
5082 j++;
5083 }
5084
5085 bktIndex++;
5086 }
5087
5088 return 0;
5089}
5090
5091
5092/*
5093 * define short names for the global vendor params
5094 * used by wlan_hdd_cfg80211_extscan_start()
5095 */
5096#define PARAM_MAX \
5097QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5098#define PARAM_REQUEST_ID \
5099QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5100#define PARAM_BASE_PERIOD \
5101QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5102#define PARAM_MAX_AP_PER_SCAN \
5103QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5104#define PARAM_RPT_THRHLD_PERCENT \
5105QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5106#define PARAM_RPT_THRHLD_NUM_SCANS \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5108#define PARAM_NUM_BUCKETS \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5110
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305111static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305112 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305113 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305114{
Dino Myclee8843b32014-07-04 14:21:45 +05305115 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 struct net_device *dev = wdev->netdev;
5117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5119 struct nlattr *tb[PARAM_MAX + 1];
5120 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305122 tANI_U32 request_id;
5123 struct hdd_ext_scan_context *context;
5124 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305126 ENTER();
5127
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128 if (VOS_FTM_MODE == hdd_get_conparam()) {
5129 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5130 return -EINVAL;
5131 }
5132
Dino Mycle6fb96c12014-06-10 11:52:40 +05305133 status = wlan_hdd_validate_context(pHddCtx);
5134 if (0 != status)
5135 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136 return -EINVAL;
5137 }
Dino Myclee8843b32014-07-04 14:21:45 +05305138 /* check the EXTScan Capability */
5139 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305140 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5141 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305142 {
5143 hddLog(VOS_TRACE_LEVEL_ERROR,
5144 FL("EXTScan not enabled/supported by Firmware"));
5145 return -EINVAL;
5146 }
5147
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305148 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305149 data, dataLen,
5150 wlan_hdd_extscan_config_policy)) {
5151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5152 return -EINVAL;
5153 }
5154
5155 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305156 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5158 return -EINVAL;
5159 }
5160
Dino Myclee8843b32014-07-04 14:21:45 +05305161 pReqMsg = (tpSirEXTScanStartReqParams)
5162 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305163 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5165 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 }
5167
5168 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305169 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5171
5172 pReqMsg->sessionId = pAdapter->sessionId;
5173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5174
5175 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305176 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5178 goto fail;
5179 }
5180 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305181 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5183 pReqMsg->basePeriod);
5184
5185 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305186 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5188 goto fail;
5189 }
5190 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305191 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5193 pReqMsg->maxAPperScan);
5194
5195 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305196 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5198 goto fail;
5199 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 pReqMsg->reportThresholdPercent = nla_get_u8(
5201 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 pReqMsg->reportThresholdPercent);
5204
5205 /* Parse and fetch report threshold num scans */
5206 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5207 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5208 goto fail;
5209 }
5210 pReqMsg->reportThresholdNumScans = nla_get_u8(
5211 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5212 hddLog(LOG1, FL("Report Threshold num scans %d"),
5213 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305214
5215 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305216 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5218 goto fail;
5219 }
5220 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305221 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305222 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5223 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5224 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5225 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5226 }
5227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5228 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305229
Dino Mycle6fb96c12014-06-10 11:52:40 +05305230 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5232 goto fail;
5233 }
5234
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305235 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5238 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305239
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240 context = &pHddCtx->ext_scan_context;
5241 spin_lock(&hdd_context_lock);
5242 INIT_COMPLETION(context->response_event);
5243 context->request_id = request_id = pReqMsg->requestId;
5244 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305245
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5247 if (!HAL_STATUS_SUCCESS(status)) {
5248 hddLog(VOS_TRACE_LEVEL_ERROR,
5249 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305250 goto fail;
5251 }
5252
Srinivas Dasari91727c12016-03-23 17:59:06 +05305253 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5254
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305255 /* request was sent -- wait for the response */
5256 rc = wait_for_completion_timeout(&context->response_event,
5257 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5258
5259 if (!rc) {
5260 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5261 retval = -ETIMEDOUT;
5262 } else {
5263 spin_lock(&hdd_context_lock);
5264 if (context->request_id == request_id)
5265 retval = context->response_status;
5266 else
5267 retval = -EINVAL;
5268 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305269 }
5270
Dino Myclee8843b32014-07-04 14:21:45 +05305271 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305272 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305273 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305274
5275fail:
5276 vos_mem_free(pReqMsg);
5277 return -EINVAL;
5278}
5279
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305280/*
5281 * done with short names for the global vendor params
5282 * used by wlan_hdd_cfg80211_extscan_start()
5283 */
5284#undef PARAM_MAX
5285#undef PARAM_REQUEST_ID
5286#undef PARAM_BASE_PERIOD
5287#undef PARAMS_MAX_AP_PER_SCAN
5288#undef PARAMS_RPT_THRHLD_PERCENT
5289#undef PARAMS_RPT_THRHLD_NUM_SCANS
5290#undef PARAMS_NUM_BUCKETS
5291
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305292static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5293 struct wireless_dev *wdev,
5294 const void *data, int dataLen)
5295{
5296 int ret = 0;
5297
5298 vos_ssr_protect(__func__);
5299 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5300 vos_ssr_unprotect(__func__);
5301
5302 return ret;
5303}
5304
5305static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305306 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305307 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305308{
Dino Myclee8843b32014-07-04 14:21:45 +05305309 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305310 struct net_device *dev = wdev->netdev;
5311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5314 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305315 int retval;
5316 unsigned long rc;
5317 struct hdd_ext_scan_context *context;
5318 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305320 ENTER();
5321
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305322 if (VOS_FTM_MODE == hdd_get_conparam()) {
5323 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5324 return -EINVAL;
5325 }
5326
Dino Mycle6fb96c12014-06-10 11:52:40 +05305327 status = wlan_hdd_validate_context(pHddCtx);
5328 if (0 != status)
5329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305330 return -EINVAL;
5331 }
Dino Myclee8843b32014-07-04 14:21:45 +05305332 /* check the EXTScan Capability */
5333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305336 {
5337 hddLog(VOS_TRACE_LEVEL_ERROR,
5338 FL("EXTScan not enabled/supported by Firmware"));
5339 return -EINVAL;
5340 }
5341
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5343 data, dataLen,
5344 wlan_hdd_extscan_config_policy)) {
5345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5346 return -EINVAL;
5347 }
5348
5349 /* Parse and fetch request Id */
5350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5352 return -EINVAL;
5353 }
5354
Dino Myclee8843b32014-07-04 14:21:45 +05305355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305358
Dino Myclee8843b32014-07-04 14:21:45 +05305359 reqMsg.sessionId = pAdapter->sessionId;
5360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305361
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305362 context = &pHddCtx->ext_scan_context;
5363 spin_lock(&hdd_context_lock);
5364 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305365 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305366 spin_unlock(&hdd_context_lock);
5367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369 if (!HAL_STATUS_SUCCESS(status)) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR,
5371 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372 return -EINVAL;
5373 }
5374
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 /* request was sent -- wait for the response */
5376 rc = wait_for_completion_timeout(&context->response_event,
5377 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5378
5379 if (!rc) {
5380 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5381 retval = -ETIMEDOUT;
5382 } else {
5383 spin_lock(&hdd_context_lock);
5384 if (context->request_id == request_id)
5385 retval = context->response_status;
5386 else
5387 retval = -EINVAL;
5388 spin_unlock(&hdd_context_lock);
5389 }
5390
5391 return retval;
5392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305393 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305394 return 0;
5395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data, int dataLen)
5400{
5401 int ret = 0;
5402
5403 vos_ssr_protect(__func__);
5404 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5405 vos_ssr_unprotect(__func__);
5406
5407 return ret;
5408}
5409
5410static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305412 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305413{
Dino Myclee8843b32014-07-04 14:21:45 +05305414 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305415 struct net_device *dev = wdev->netdev;
5416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5417 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5418 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5419 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305420 struct hdd_ext_scan_context *context;
5421 tANI_U32 request_id;
5422 unsigned long rc;
5423 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305425 ENTER();
5426
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305427 if (VOS_FTM_MODE == hdd_get_conparam()) {
5428 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5429 return -EINVAL;
5430 }
5431
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432 status = wlan_hdd_validate_context(pHddCtx);
5433 if (0 != status)
5434 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305435 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305436 return -EINVAL;
5437 }
Dino Myclee8843b32014-07-04 14:21:45 +05305438 /* check the EXTScan Capability */
5439 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305440 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5441 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305442 {
5443 hddLog(VOS_TRACE_LEVEL_ERROR,
5444 FL("EXTScan not enabled/supported by Firmware"));
5445 return -EINVAL;
5446 }
5447
Dino Mycle6fb96c12014-06-10 11:52:40 +05305448 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5449 data, dataLen,
5450 wlan_hdd_extscan_config_policy)) {
5451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5452 return -EINVAL;
5453 }
5454
5455 /* Parse and fetch request Id */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5458 return -EINVAL;
5459 }
5460
Dino Myclee8843b32014-07-04 14:21:45 +05305461 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305462 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305464
Dino Myclee8843b32014-07-04 14:21:45 +05305465 reqMsg.sessionId = pAdapter->sessionId;
5466 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305467
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305468 context = &pHddCtx->ext_scan_context;
5469 spin_lock(&hdd_context_lock);
5470 INIT_COMPLETION(context->response_event);
5471 context->request_id = request_id = reqMsg.requestId;
5472 spin_unlock(&hdd_context_lock);
5473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305475 if (!HAL_STATUS_SUCCESS(status)) {
5476 hddLog(VOS_TRACE_LEVEL_ERROR,
5477 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305478 return -EINVAL;
5479 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305480
5481 /* request was sent -- wait for the response */
5482 rc = wait_for_completion_timeout(&context->response_event,
5483 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5484 if (!rc) {
5485 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5486 retval = -ETIMEDOUT;
5487 } else {
5488 spin_lock(&hdd_context_lock);
5489 if (context->request_id == request_id)
5490 retval = context->response_status;
5491 else
5492 retval = -EINVAL;
5493 spin_unlock(&hdd_context_lock);
5494 }
5495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305496 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305497 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data, int dataLen)
5503{
5504 int ret = 0;
5505
5506 vos_ssr_protect(__func__);
5507 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5508 vos_ssr_unprotect(__func__);
5509
5510 return ret;
5511}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305512#endif /* WLAN_FEATURE_EXTSCAN */
5513
Atul Mittal115287b2014-07-08 13:26:33 +05305514/*EXT TDLS*/
5515static const struct nla_policy
5516wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5517{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305518 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5519 .type = NLA_UNSPEC,
5520 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305521 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5522 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5523 {.type = NLA_S32 },
5524 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5525 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5526
5527};
5528
5529static const struct nla_policy
5530wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5531{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305532 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5533 .type = NLA_UNSPEC,
5534 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_state_change_policy[
5540 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5541{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305542 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5543 .type = NLA_UNSPEC,
5544 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305545 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5546 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305547 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5548 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5549 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305550
5551};
5552
5553static const struct nla_policy
5554wlan_hdd_tdls_config_get_status_policy[
5555 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5556{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305557 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5558 .type = NLA_UNSPEC,
5559 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305560 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5561 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305562 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5563 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5564 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305565
5566};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305567
5568static const struct nla_policy
5569wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5570{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305571 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5572 .type = NLA_UNSPEC,
5573 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305574};
5575
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305576static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305577 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305578 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305579 int data_len)
5580{
5581
5582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5583 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305585 ENTER();
5586
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305587 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 return -EINVAL;
5589 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305590 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305591 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305592 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305593 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305594 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305595 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 return -ENOTSUPP;
5597 }
5598
5599 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5600 data, data_len, wlan_hdd_mac_config)) {
5601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5602 return -EINVAL;
5603 }
5604
5605 /* Parse and fetch mac address */
5606 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5608 return -EINVAL;
5609 }
5610
5611 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5612 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5613 VOS_MAC_ADDR_LAST_3_BYTES);
5614
Siddharth Bhal76972212014-10-15 16:22:51 +05305615 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5616
5617 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305618 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5619 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305620 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5621 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5622 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5623 {
5624 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5625 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5626 VOS_MAC_ADDRESS_LEN);
5627 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305629
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305630 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5631 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305632
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305633 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305634 return 0;
5635}
5636
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305637static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5638 struct wireless_dev *wdev,
5639 const void *data,
5640 int data_len)
5641{
5642 int ret = 0;
5643
5644 vos_ssr_protect(__func__);
5645 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5646 vos_ssr_unprotect(__func__);
5647
5648 return ret;
5649}
5650
5651static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305652 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305653 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305654 int data_len)
5655{
5656 u8 peer[6] = {0};
5657 struct net_device *dev = wdev->netdev;
5658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5660 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5661 eHalStatus ret;
5662 tANI_S32 state;
5663 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305664 tANI_S32 global_operating_class = 0;
5665 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305666 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305667 int retVal;
5668
5669 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305670
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305671 if (!pAdapter) {
5672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5673 return -EINVAL;
5674 }
5675
Atul Mittal115287b2014-07-08 13:26:33 +05305676 ret = wlan_hdd_validate_context(pHddCtx);
5677 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305679 return -EINVAL;
5680 }
5681 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305683 return -ENOTSUPP;
5684 }
5685 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5686 data, data_len,
5687 wlan_hdd_tdls_config_get_status_policy)) {
5688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5689 return -EINVAL;
5690 }
5691
5692 /* Parse and fetch mac address */
5693 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5695 return -EINVAL;
5696 }
5697
5698 memcpy(peer, nla_data(
5699 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5700 sizeof(peer));
5701 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5702
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305703 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305704
Atul Mittal115287b2014-07-08 13:26:33 +05305705 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305706 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305707 NLMSG_HDRLEN);
5708
5709 if (!skb) {
5710 hddLog(VOS_TRACE_LEVEL_ERROR,
5711 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5712 return -EINVAL;
5713 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305714 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305715 reason,
5716 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305717 global_operating_class,
5718 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305719 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305720 if (nla_put_s32(skb,
5721 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5722 state) ||
5723 nla_put_s32(skb,
5724 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5725 reason) ||
5726 nla_put_s32(skb,
5727 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5728 global_operating_class) ||
5729 nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5731 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305732
5733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5734 goto nla_put_failure;
5735 }
5736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305737 retVal = cfg80211_vendor_cmd_reply(skb);
5738 EXIT();
5739 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305740
5741nla_put_failure:
5742 kfree_skb(skb);
5743 return -EINVAL;
5744}
5745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305746static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5747 struct wireless_dev *wdev,
5748 const void *data,
5749 int data_len)
5750{
5751 int ret = 0;
5752
5753 vos_ssr_protect(__func__);
5754 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5755 vos_ssr_unprotect(__func__);
5756
5757 return ret;
5758}
5759
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305760static int wlan_hdd_cfg80211_exttdls_callback(
5761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5762 const tANI_U8* mac,
5763#else
5764 tANI_U8* mac,
5765#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305766 tANI_S32 state,
5767 tANI_S32 reason,
5768 void *ctx)
5769{
5770 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305771 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305772 tANI_S32 global_operating_class = 0;
5773 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305774 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305776 ENTER();
5777
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305778 if (!pAdapter) {
5779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5780 return -EINVAL;
5781 }
5782
5783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305784 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305786 return -EINVAL;
5787 }
5788
5789 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305791 return -ENOTSUPP;
5792 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305793 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5795 NULL,
5796#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305797 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5798 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5799 GFP_KERNEL);
5800
5801 if (!skb) {
5802 hddLog(VOS_TRACE_LEVEL_ERROR,
5803 FL("cfg80211_vendor_event_alloc failed"));
5804 return -EINVAL;
5805 }
5806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305807 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5808 reason,
5809 state,
5810 global_operating_class,
5811 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305812 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5813 MAC_ADDR_ARRAY(mac));
5814
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305815 if (nla_put(skb,
5816 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5817 VOS_MAC_ADDR_SIZE, mac) ||
5818 nla_put_s32(skb,
5819 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5820 state) ||
5821 nla_put_s32(skb,
5822 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5823 reason) ||
5824 nla_put_s32(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5826 channel) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5829 global_operating_class)
5830 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5832 goto nla_put_failure;
5833 }
5834
5835 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305836 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305837 return (0);
5838
5839nla_put_failure:
5840 kfree_skb(skb);
5841 return -EINVAL;
5842}
5843
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305844static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305845 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305846 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305847 int data_len)
5848{
5849 u8 peer[6] = {0};
5850 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5853 eHalStatus status;
5854 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305855 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305856 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305857
5858 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305859
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305860 if (!dev) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5862 return -EINVAL;
5863 }
5864
5865 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5866 if (!pAdapter) {
5867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5868 return -EINVAL;
5869 }
5870
Atul Mittal115287b2014-07-08 13:26:33 +05305871 status = wlan_hdd_validate_context(pHddCtx);
5872 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305874 return -EINVAL;
5875 }
5876 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305878 return -ENOTSUPP;
5879 }
5880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5881 data, data_len,
5882 wlan_hdd_tdls_config_enable_policy)) {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5884 return -EINVAL;
5885 }
5886
5887 /* Parse and fetch mac address */
5888 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5890 return -EINVAL;
5891 }
5892
5893 memcpy(peer, nla_data(
5894 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5895 sizeof(peer));
5896 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5897
5898 /* Parse and fetch channel */
5899 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5901 return -EINVAL;
5902 }
5903 pReqMsg.channel = nla_get_s32(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5906
5907 /* Parse and fetch global operating class */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.global_operating_class = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5915 pReqMsg.global_operating_class);
5916
5917 /* Parse and fetch latency ms */
5918 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5920 return -EINVAL;
5921 }
5922 pReqMsg.max_latency_ms = nla_get_s32(
5923 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5925 pReqMsg.max_latency_ms);
5926
5927 /* Parse and fetch required bandwidth kbps */
5928 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5930 return -EINVAL;
5931 }
5932
5933 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5934 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5935 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5936 pReqMsg.min_bandwidth_kbps);
5937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305938 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305939 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305940 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305941 wlan_hdd_cfg80211_exttdls_callback);
5942
5943 EXIT();
5944 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305945}
5946
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305947static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5948 struct wireless_dev *wdev,
5949 const void *data,
5950 int data_len)
5951{
5952 int ret = 0;
5953
5954 vos_ssr_protect(__func__);
5955 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5956 vos_ssr_unprotect(__func__);
5957
5958 return ret;
5959}
5960
5961static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305962 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305963 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305964 int data_len)
5965{
5966 u8 peer[6] = {0};
5967 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5969 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5970 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305971 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305972 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305973
5974 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305975
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305976 if (!dev) {
5977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5978 return -EINVAL;
5979 }
5980
5981 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5982 if (!pAdapter) {
5983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5984 return -EINVAL;
5985 }
5986
Atul Mittal115287b2014-07-08 13:26:33 +05305987 status = wlan_hdd_validate_context(pHddCtx);
5988 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305990 return -EINVAL;
5991 }
5992 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305994 return -ENOTSUPP;
5995 }
5996 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5997 data, data_len,
5998 wlan_hdd_tdls_config_disable_policy)) {
5999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6000 return -EINVAL;
6001 }
6002 /* Parse and fetch mac address */
6003 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6005 return -EINVAL;
6006 }
6007
6008 memcpy(peer, nla_data(
6009 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6010 sizeof(peer));
6011 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306013 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6014
6015 EXIT();
6016 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306017}
6018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306019static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6020 struct wireless_dev *wdev,
6021 const void *data,
6022 int data_len)
6023{
6024 int ret = 0;
6025
6026 vos_ssr_protect(__func__);
6027 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6028 vos_ssr_unprotect(__func__);
6029
6030 return ret;
6031}
6032
Dasari Srinivas7875a302014-09-26 17:50:57 +05306033static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306034__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306035 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306036 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306037{
6038 struct net_device *dev = wdev->netdev;
6039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6040 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6041 struct sk_buff *skb = NULL;
6042 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306045 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306046
6047 ret = wlan_hdd_validate_context(pHddCtx);
6048 if (0 != ret)
6049 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306050 return ret;
6051 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306052 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6053 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6054 fset |= WIFI_FEATURE_INFRA;
6055 }
6056
6057 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6058 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6059 fset |= WIFI_FEATURE_INFRA_5G;
6060 }
6061
6062#ifdef WLAN_FEATURE_P2P
6063 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6064 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6065 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6066 fset |= WIFI_FEATURE_P2P;
6067 }
6068#endif
6069
6070 /* Soft-AP is supported currently by default */
6071 fset |= WIFI_FEATURE_SOFT_AP;
6072
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306073 /* HOTSPOT is a supplicant feature, enable it by default */
6074 fset |= WIFI_FEATURE_HOTSPOT;
6075
Dasari Srinivas7875a302014-09-26 17:50:57 +05306076#ifdef WLAN_FEATURE_EXTSCAN
6077 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306078 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6079 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6080 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306081 fset |= WIFI_FEATURE_EXTSCAN;
6082 }
6083#endif
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085 if (sme_IsFeatureSupportedByFW(NAN)) {
6086 hddLog(LOG1, FL("NAN is supported by firmware"));
6087 fset |= WIFI_FEATURE_NAN;
6088 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306089
6090 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306091 if (sme_IsFeatureSupportedByFW(RTT) &&
6092 pHddCtx->cfg_ini->enable_rtt_support) {
6093 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 fset |= WIFI_FEATURE_D2AP_RTT;
6095 }
6096
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306097 if (sme_IsFeatureSupportedByFW(RTT3)) {
6098 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6099 fset |= WIFI_FEATURE_RTT3;
6100 }
6101
Dasari Srinivas7875a302014-09-26 17:50:57 +05306102#ifdef FEATURE_WLAN_BATCH_SCAN
6103 if (fset & WIFI_FEATURE_EXTSCAN) {
6104 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6105 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6106 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6107 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6108 fset |= WIFI_FEATURE_BATCH_SCAN;
6109 }
6110#endif
6111
6112#ifdef FEATURE_WLAN_SCAN_PNO
6113 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6114 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6115 hddLog(LOG1, FL("PNO is supported by firmware"));
6116 fset |= WIFI_FEATURE_PNO;
6117 }
6118#endif
6119
6120 /* STA+STA is supported currently by default */
6121 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6122
6123#ifdef FEATURE_WLAN_TDLS
6124 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6125 sme_IsFeatureSupportedByFW(TDLS)) {
6126 hddLog(LOG1, FL("TDLS is supported by firmware"));
6127 fset |= WIFI_FEATURE_TDLS;
6128 }
6129
6130 /* TDLS_OFFCHANNEL is not supported currently by default */
6131#endif
6132
6133#ifdef WLAN_AP_STA_CONCURRENCY
6134 /* AP+STA concurrency is supported currently by default */
6135 fset |= WIFI_FEATURE_AP_STA;
6136#endif
6137
Mukul Sharma5add0532015-08-17 15:57:47 +05306138#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306139 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6140 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306141 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6142 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306143 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306144#endif
6145
Dasari Srinivas7875a302014-09-26 17:50:57 +05306146 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6147 NLMSG_HDRLEN);
6148
6149 if (!skb) {
6150 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6151 return -EINVAL;
6152 }
6153 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6154
6155 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6156 hddLog(LOGE, FL("nla put fail"));
6157 goto nla_put_failure;
6158 }
6159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306160 ret = cfg80211_vendor_cmd_reply(skb);
6161 EXIT();
6162 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306163
6164nla_put_failure:
6165 kfree_skb(skb);
6166 return -EINVAL;
6167}
6168
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306169static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306170wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6171 struct wireless_dev *wdev,
6172 const void *data, int data_len)
6173{
6174 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306175 vos_ssr_protect(__func__);
6176 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6177 vos_ssr_unprotect(__func__);
6178
6179 return ret;
6180}
6181
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306182
6183static const struct
6184nla_policy
6185qca_wlan_vendor_wifi_logger_get_ring_data_policy
6186[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6187 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6188 = {.type = NLA_U32 },
6189};
6190
6191static int
6192 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6193 struct wireless_dev *wdev,
6194 const void *data,
6195 int data_len)
6196{
6197 int ret;
6198 VOS_STATUS status;
6199 uint32_t ring_id;
6200 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6201 struct nlattr *tb
6202 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6203
6204 ENTER();
6205
6206 ret = wlan_hdd_validate_context(hdd_ctx);
6207 if (0 != ret) {
6208 return ret;
6209 }
6210
6211 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6212 data, data_len,
6213 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6214 hddLog(LOGE, FL("Invalid attribute"));
6215 return -EINVAL;
6216 }
6217
6218 /* Parse and fetch ring id */
6219 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6220 hddLog(LOGE, FL("attr ATTR failed"));
6221 return -EINVAL;
6222 }
6223
6224 ring_id = nla_get_u32(
6225 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6226
6227 hddLog(LOG1, FL("Bug report triggered by framework"));
6228
6229 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6230 WLAN_LOG_INDICATOR_FRAMEWORK,
6231 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306232 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306233 );
6234 if (VOS_STATUS_SUCCESS != status) {
6235 hddLog(LOGE, FL("Failed to trigger bug report"));
6236
6237 return -EINVAL;
6238 }
6239
6240 return 0;
6241
6242
6243}
6244
6245
6246static int
6247 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6248 struct wireless_dev *wdev,
6249 const void *data,
6250 int data_len)
6251{
6252 int ret = 0;
6253
6254 vos_ssr_protect(__func__);
6255 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6256 wdev, data, data_len);
6257 vos_ssr_unprotect(__func__);
6258
6259 return ret;
6260
6261}
6262
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306263#define MAX_CONCURRENT_MATRIX \
6264 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6265#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6266 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6267static const struct nla_policy
6268wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6269 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6270};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306271
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306272static int
6273__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306274 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306275 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306276{
6277 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6278 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306279 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306280 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6282 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283
6284 ENTER();
6285
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306286 ret = wlan_hdd_validate_context(pHddCtx);
6287 if (0 != ret)
6288 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306289 return ret;
6290 }
6291
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306292 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6293 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306294 hddLog(LOGE, FL("Invalid ATTR"));
6295 return -EINVAL;
6296 }
6297
6298 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306299 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306300 hddLog(LOGE, FL("Attr max feature set size failed"));
6301 return -EINVAL;
6302 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306303 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6305
6306 /* Fill feature combination matrix */
6307 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306308 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6309 WIFI_FEATURE_P2P;
6310
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306311 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6312 WIFI_FEATURE_SOFT_AP;
6313
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306314 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6315 WIFI_FEATURE_SOFT_AP;
6316
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_SOFT_AP |
6319 WIFI_FEATURE_P2P;
6320
6321 /* Add more feature combinations here */
6322
6323 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6324 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6325 hddLog(LOG1, "Feature set matrix");
6326 for (i = 0; i < feature_sets; i++)
6327 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6328
6329 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6330 sizeof(u32) * feature_sets +
6331 NLMSG_HDRLEN);
6332
6333 if (reply_skb) {
6334 if (nla_put_u32(reply_skb,
6335 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6336 feature_sets) ||
6337 nla_put(reply_skb,
6338 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6339 sizeof(u32) * feature_sets, feature_set_matrix)) {
6340 hddLog(LOGE, FL("nla put fail"));
6341 kfree_skb(reply_skb);
6342 return -EINVAL;
6343 }
6344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306345 ret = cfg80211_vendor_cmd_reply(reply_skb);
6346 EXIT();
6347 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306348 }
6349 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6350 return -ENOMEM;
6351
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306352}
6353
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306354#undef MAX_CONCURRENT_MATRIX
6355#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6356
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306357static int
6358wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6359 struct wireless_dev *wdev,
6360 const void *data, int data_len)
6361{
6362 int ret = 0;
6363
6364 vos_ssr_protect(__func__);
6365 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6366 data_len);
6367 vos_ssr_unprotect(__func__);
6368
6369 return ret;
6370}
6371
c_manjeecfd1efb2015-09-25 19:32:34 +05306372
6373static int
6374__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6375 struct wireless_dev *wdev,
6376 const void *data, int data_len)
6377{
6378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6379 int ret;
6380 ENTER();
6381
6382 ret = wlan_hdd_validate_context(pHddCtx);
6383 if (0 != ret)
6384 {
6385 return ret;
6386 }
6387
6388 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6389 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6390 {
6391 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306392 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306393 }
6394 /*call common API for FW mem dump req*/
6395 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6396
Abhishek Singhc783fa72015-12-09 18:07:34 +05306397 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306398 {
6399 /*indicate to userspace the status of fw mem dump */
6400 wlan_indicate_mem_dump_complete(true);
6401 }
6402 else
6403 {
6404 /*else send failure to userspace */
6405 wlan_indicate_mem_dump_complete(false);
6406 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306407 EXIT();
6408 return ret;
6409}
6410
6411/**
6412 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6413 * @wiphy: pointer to wireless wiphy structure.
6414 * @wdev: pointer to wireless_dev structure.
6415 * @data: Pointer to the NL data.
6416 * @data_len:Length of @data
6417 *
6418 * This is called when wlan driver needs to get the firmware memory dump
6419 * via vendor specific command.
6420 *
6421 * Return: 0 on success, error number otherwise.
6422 */
6423
6424static int
6425wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6426 struct wireless_dev *wdev,
6427 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306428{
6429 int ret = 0;
6430 vos_ssr_protect(__func__);
6431 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6432 data_len);
6433 vos_ssr_unprotect(__func__);
6434 return ret;
6435}
c_manjeecfd1efb2015-09-25 19:32:34 +05306436
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437static const struct
6438nla_policy
6439qca_wlan_vendor_wifi_logger_start_policy
6440[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6441 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6442 = {.type = NLA_U32 },
6443 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6444 = {.type = NLA_U32 },
6445 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6446 = {.type = NLA_U32 },
6447};
6448
6449/**
6450 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6451 * or disable the collection of packet statistics from the firmware
6452 * @wiphy: WIPHY structure pointer
6453 * @wdev: Wireless device structure pointer
6454 * @data: Pointer to the data received
6455 * @data_len: Length of the data received
6456 *
6457 * This function is used to enable or disable the collection of packet
6458 * statistics from the firmware
6459 *
6460 * Return: 0 on success and errno on failure
6461 */
6462static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6463 struct wireless_dev *wdev,
6464 const void *data,
6465 int data_len)
6466{
6467 eHalStatus status;
6468 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6469 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6470 tAniWifiStartLog start_log;
6471
6472 status = wlan_hdd_validate_context(hdd_ctx);
6473 if (0 != status) {
6474 return -EINVAL;
6475 }
6476
6477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6478 data, data_len,
6479 qca_wlan_vendor_wifi_logger_start_policy)) {
6480 hddLog(LOGE, FL("Invalid attribute"));
6481 return -EINVAL;
6482 }
6483
6484 /* Parse and fetch ring id */
6485 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6486 hddLog(LOGE, FL("attr ATTR failed"));
6487 return -EINVAL;
6488 }
6489 start_log.ringId = nla_get_u32(
6490 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6491 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6492
6493 /* Parse and fetch verbose level */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6495 hddLog(LOGE, FL("attr verbose_level failed"));
6496 return -EINVAL;
6497 }
6498 start_log.verboseLevel = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6500 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6501
6502 /* Parse and fetch flag */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6504 hddLog(LOGE, FL("attr flag failed"));
6505 return -EINVAL;
6506 }
6507 start_log.flag = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6509 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6510
6511 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306512 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6513 !vos_isPktStatsEnabled()))
6514
Sushant Kaushik8e644982015-09-23 12:18:54 +05306515 {
6516 hddLog(LOGE, FL("per pkt stats not enabled"));
6517 return -EINVAL;
6518 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306519
Sushant Kaushik33200572015-08-05 16:46:20 +05306520 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306521 return 0;
6522}
6523
6524/**
6525 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6526 * or disable the collection of packet statistics from the firmware
6527 * @wiphy: WIPHY structure pointer
6528 * @wdev: Wireless device structure pointer
6529 * @data: Pointer to the data received
6530 * @data_len: Length of the data received
6531 *
6532 * This function is used to enable or disable the collection of packet
6533 * statistics from the firmware
6534 *
6535 * Return: 0 on success and errno on failure
6536 */
6537static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6538 struct wireless_dev *wdev,
6539 const void *data,
6540 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306541{
6542 int ret = 0;
6543
6544 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306545
6546 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6547 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306548 vos_ssr_unprotect(__func__);
6549
6550 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306551}
6552
6553
Agarwal Ashish738843c2014-09-25 12:27:56 +05306554static const struct nla_policy
6555wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6556 +1] =
6557{
6558 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6559};
6560
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306561static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306562 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306563 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306564 int data_len)
6565{
6566 struct net_device *dev = wdev->netdev;
6567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6568 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6570 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6571 eHalStatus status;
6572 u32 dfsFlag = 0;
6573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306574 ENTER();
6575
Agarwal Ashish738843c2014-09-25 12:27:56 +05306576 status = wlan_hdd_validate_context(pHddCtx);
6577 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306578 return -EINVAL;
6579 }
6580 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6581 data, data_len,
6582 wlan_hdd_set_no_dfs_flag_config_policy)) {
6583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6584 return -EINVAL;
6585 }
6586
6587 /* Parse and fetch required bandwidth kbps */
6588 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6590 return -EINVAL;
6591 }
6592
6593 dfsFlag = nla_get_u32(
6594 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6595 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6596 dfsFlag);
6597
6598 pHddCtx->disable_dfs_flag = dfsFlag;
6599
6600 sme_disable_dfs_channel(hHal, dfsFlag);
6601 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306602
6603 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306604 return 0;
6605}
Atul Mittal115287b2014-07-08 13:26:33 +05306606
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306607static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6608 struct wireless_dev *wdev,
6609 const void *data,
6610 int data_len)
6611{
6612 int ret = 0;
6613
6614 vos_ssr_protect(__func__);
6615 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6616 vos_ssr_unprotect(__func__);
6617
6618 return ret;
6619
6620}
6621
Mukul Sharma2a271632014-10-13 14:59:01 +05306622const struct
6623nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6624{
6625 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306626 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6627 .type = NLA_UNSPEC,
6628 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306629};
6630
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306631static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306632 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306633{
6634
6635 u8 bssid[6] = {0};
6636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6637 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6638 eHalStatus status = eHAL_STATUS_SUCCESS;
6639 v_U32_t isFwrRoamEnabled = FALSE;
6640 int ret;
6641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306642 ENTER();
6643
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306644 ret = wlan_hdd_validate_context(pHddCtx);
6645 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306646 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306647 }
6648
6649 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6650 data, data_len,
6651 qca_wlan_vendor_attr);
6652 if (ret){
6653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6654 return -EINVAL;
6655 }
6656
6657 /* Parse and fetch Enable flag */
6658 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6660 return -EINVAL;
6661 }
6662
6663 isFwrRoamEnabled = nla_get_u32(
6664 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6665
6666 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6667
6668 /* Parse and fetch bssid */
6669 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6671 return -EINVAL;
6672 }
6673
6674 memcpy(bssid, nla_data(
6675 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6676 sizeof(bssid));
6677 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6678
6679 //Update roaming
6680 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306681 if (!HAL_STATUS_SUCCESS(status)) {
6682 hddLog(LOGE,
6683 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6684 return -EINVAL;
6685 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306686 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306687 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306688}
6689
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306690static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6691 struct wireless_dev *wdev, const void *data, int data_len)
6692{
6693 int ret = 0;
6694
6695 vos_ssr_protect(__func__);
6696 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6697 vos_ssr_unprotect(__func__);
6698
6699 return ret;
6700}
6701
Sushant Kaushik847890c2015-09-28 16:05:17 +05306702static const struct
6703nla_policy
6704qca_wlan_vendor_get_wifi_info_policy[
6705 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6706 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6707 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6708};
6709
6710
6711/**
6712 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6713 * @wiphy: pointer to wireless wiphy structure.
6714 * @wdev: pointer to wireless_dev structure.
6715 * @data: Pointer to the data to be passed via vendor interface
6716 * @data_len:Length of the data to be passed
6717 *
6718 * This is called when wlan driver needs to send wifi driver related info
6719 * (driver/fw version) to the user space application upon request.
6720 *
6721 * Return: Return the Success or Failure code.
6722 */
6723static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6724 struct wireless_dev *wdev,
6725 const void *data, int data_len)
6726{
6727 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6728 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6729 tSirVersionString version;
6730 uint32 version_len;
6731 uint8 attr;
6732 int status;
6733 struct sk_buff *reply_skb = NULL;
6734
6735 if (VOS_FTM_MODE == hdd_get_conparam()) {
6736 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6737 return -EINVAL;
6738 }
6739
6740 status = wlan_hdd_validate_context(hdd_ctx);
6741 if (0 != status) {
6742 hddLog(LOGE, FL("HDD context is not valid"));
6743 return -EINVAL;
6744 }
6745
6746 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6747 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6748 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6749 return -EINVAL;
6750 }
6751
6752 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6753 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6754 QWLAN_VERSIONSTR);
6755 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6756 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6757 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6758 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6759 hdd_ctx->fw_Version);
6760 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6761 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6762 } else {
6763 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6764 return -EINVAL;
6765 }
6766
6767 version_len = strlen(version);
6768 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6769 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6770 if (!reply_skb) {
6771 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6772 return -ENOMEM;
6773 }
6774
6775 if (nla_put(reply_skb, attr, version_len, version)) {
6776 hddLog(LOGE, FL("nla put fail"));
6777 kfree_skb(reply_skb);
6778 return -EINVAL;
6779 }
6780
6781 return cfg80211_vendor_cmd_reply(reply_skb);
6782}
6783
6784/**
6785 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6786 * @wiphy: pointer to wireless wiphy structure.
6787 * @wdev: pointer to wireless_dev structure.
6788 * @data: Pointer to the data to be passed via vendor interface
6789 * @data_len:Length of the data to be passed
6790 * @data_len: Length of the data received
6791 *
6792 * This function is used to enable or disable the collection of packet
6793 * statistics from the firmware
6794 *
6795 * Return: 0 on success and errno on failure
6796 */
6797
6798static int
6799wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6800 struct wireless_dev *wdev,
6801 const void *data, int data_len)
6802
6803
6804{
6805 int ret = 0;
6806
6807 vos_ssr_protect(__func__);
6808 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6809 wdev, data, data_len);
6810 vos_ssr_unprotect(__func__);
6811
6812 return ret;
6813}
6814
6815
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306816/*
6817 * define short names for the global vendor params
6818 * used by __wlan_hdd_cfg80211_monitor_rssi()
6819 */
6820#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6821#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6822#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6823#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6824#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6825
6826/**---------------------------------------------------------------------------
6827
6828 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6829 monitor start is completed successfully.
6830
6831 \return - None
6832
6833 --------------------------------------------------------------------------*/
6834void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6835{
6836 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6837
6838 if (NULL == pHddCtx)
6839 {
6840 hddLog(VOS_TRACE_LEVEL_ERROR,
6841 "%s: HDD context is NULL",__func__);
6842 return;
6843 }
6844
6845 if (VOS_STATUS_SUCCESS == status)
6846 {
6847 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6848 }
6849 else
6850 {
6851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6852 }
6853
6854 return;
6855}
6856
6857/**---------------------------------------------------------------------------
6858
6859 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6860 stop is completed successfully.
6861
6862 \return - None
6863
6864 --------------------------------------------------------------------------*/
6865void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6866{
6867 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6868
6869 if (NULL == pHddCtx)
6870 {
6871 hddLog(VOS_TRACE_LEVEL_ERROR,
6872 "%s: HDD context is NULL",__func__);
6873 return;
6874 }
6875
6876 if (VOS_STATUS_SUCCESS == status)
6877 {
6878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6879 }
6880 else
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6883 }
6884
6885 return;
6886}
6887
6888/**
6889 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6890 * @wiphy: Pointer to wireless phy
6891 * @wdev: Pointer to wireless device
6892 * @data: Pointer to data
6893 * @data_len: Data length
6894 *
6895 * Return: 0 on success, negative errno on failure
6896 */
6897
6898static int
6899__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6900 struct wireless_dev *wdev,
6901 const void *data,
6902 int data_len)
6903{
6904 struct net_device *dev = wdev->netdev;
6905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6906 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6907 hdd_station_ctx_t *pHddStaCtx;
6908 struct nlattr *tb[PARAM_MAX + 1];
6909 tpSirRssiMonitorReq pReq;
6910 eHalStatus status;
6911 int ret;
6912 uint32_t control;
6913 static const struct nla_policy policy[PARAM_MAX + 1] = {
6914 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6915 [PARAM_CONTROL] = { .type = NLA_U32 },
6916 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6917 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6918 };
6919
6920 ENTER();
6921
6922 ret = wlan_hdd_validate_context(hdd_ctx);
6923 if (0 != ret) {
6924 return -EINVAL;
6925 }
6926
6927 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6928 hddLog(LOGE, FL("Not in Connected state!"));
6929 return -ENOTSUPP;
6930 }
6931
6932 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6933 hddLog(LOGE, FL("Invalid ATTR"));
6934 return -EINVAL;
6935 }
6936
6937 if (!tb[PARAM_REQUEST_ID]) {
6938 hddLog(LOGE, FL("attr request id failed"));
6939 return -EINVAL;
6940 }
6941
6942 if (!tb[PARAM_CONTROL]) {
6943 hddLog(LOGE, FL("attr control failed"));
6944 return -EINVAL;
6945 }
6946
6947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6948
6949 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6950 if(NULL == pReq)
6951 {
6952 hddLog(LOGE,
6953 FL("vos_mem_alloc failed "));
6954 return eHAL_STATUS_FAILED_ALLOC;
6955 }
6956 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6957
6958 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6959 pReq->sessionId = pAdapter->sessionId;
6960 pReq->rssiMonitorCbContext = hdd_ctx;
6961 control = nla_get_u32(tb[PARAM_CONTROL]);
6962 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6963
6964 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6965 pReq->requestId, pReq->sessionId, control);
6966
6967 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6968 if (!tb[PARAM_MIN_RSSI]) {
6969 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306970 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306971 }
6972
6973 if (!tb[PARAM_MAX_RSSI]) {
6974 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306975 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306976 }
6977
6978 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6979 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6980 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6981
6982 if (!(pReq->minRssi < pReq->maxRssi)) {
6983 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6984 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306985 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306986 }
6987 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6988 pReq->minRssi, pReq->maxRssi);
6989 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6990
6991 }
6992 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6993 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6994 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6995 }
6996 else {
6997 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306998 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306999 }
7000
7001 if (!HAL_STATUS_SUCCESS(status)) {
7002 hddLog(LOGE,
7003 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307004 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307005 }
7006
7007 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307008fail:
7009 vos_mem_free(pReq);
7010 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307011}
7012
7013/*
7014 * done with short names for the global vendor params
7015 * used by __wlan_hdd_cfg80211_monitor_rssi()
7016 */
7017#undef PARAM_MAX
7018#undef PARAM_CONTROL
7019#undef PARAM_REQUEST_ID
7020#undef PARAM_MAX_RSSI
7021#undef PARAM_MIN_RSSI
7022
7023/**
7024 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7025 * @wiphy: wiphy structure pointer
7026 * @wdev: Wireless device structure pointer
7027 * @data: Pointer to the data received
7028 * @data_len: Length of @data
7029 *
7030 * Return: 0 on success; errno on failure
7031 */
7032static int
7033wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7034 const void *data, int data_len)
7035{
7036 int ret;
7037
7038 vos_ssr_protect(__func__);
7039 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7040 vos_ssr_unprotect(__func__);
7041
7042 return ret;
7043}
7044
7045/**
7046 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7047 * @hddctx: HDD context
7048 * @data: rssi breached event data
7049 *
7050 * This function reads the rssi breached event %data and fill in the skb with
7051 * NL attributes and send up the NL event.
7052 * This callback execute in atomic context and must not invoke any
7053 * blocking calls.
7054 *
7055 * Return: none
7056 */
7057void hdd_rssi_threshold_breached_cb(void *hddctx,
7058 struct rssi_breach_event *data)
7059{
7060 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7061 int status;
7062 struct sk_buff *skb;
7063
7064 ENTER();
7065 status = wlan_hdd_validate_context(pHddCtx);
7066
7067 if (0 != status) {
7068 return;
7069 }
7070
7071 if (!data) {
7072 hddLog(LOGE, FL("data is null"));
7073 return;
7074 }
7075
7076 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7078 NULL,
7079#endif
7080 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7081 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7082 GFP_KERNEL);
7083
7084 if (!skb) {
7085 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7086 return;
7087 }
7088
7089 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7090 data->request_id, data->curr_rssi);
7091 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7092 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7093
7094 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7095 data->request_id) ||
7096 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7097 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7098 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7099 data->curr_rssi)) {
7100 hddLog(LOGE, FL("nla put fail"));
7101 goto fail;
7102 }
7103
7104 cfg80211_vendor_event(skb, GFP_KERNEL);
7105 return;
7106
7107fail:
7108 kfree_skb(skb);
7109 return;
7110}
7111
7112
7113
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307114/**
7115 * __wlan_hdd_cfg80211_setband() - set band
7116 * @wiphy: Pointer to wireless phy
7117 * @wdev: Pointer to wireless device
7118 * @data: Pointer to data
7119 * @data_len: Data length
7120 *
7121 * Return: 0 on success, negative errno on failure
7122 */
7123static int
7124__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7125 struct wireless_dev *wdev,
7126 const void *data,
7127 int data_len)
7128{
7129 struct net_device *dev = wdev->netdev;
7130 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7131 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7132 int ret;
7133 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7134 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7135
7136 ENTER();
7137
7138 ret = wlan_hdd_validate_context(hdd_ctx);
7139 if (0 != ret) {
7140 hddLog(LOGE, FL("HDD context is not valid"));
7141 return ret;
7142 }
7143
7144 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7145 policy)) {
7146 hddLog(LOGE, FL("Invalid ATTR"));
7147 return -EINVAL;
7148 }
7149
7150 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7151 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7152 return -EINVAL;
7153 }
7154
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307155 hdd_ctx->isSetBandByNL = TRUE;
7156 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307157 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307158 hdd_ctx->isSetBandByNL = FALSE;
7159
7160 EXIT();
7161 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307162}
7163
7164/**
7165 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7166 * @wiphy: wiphy structure pointer
7167 * @wdev: Wireless device structure pointer
7168 * @data: Pointer to the data received
7169 * @data_len: Length of @data
7170 *
7171 * Return: 0 on success; errno on failure
7172 */
7173static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7174 struct wireless_dev *wdev,
7175 const void *data,
7176 int data_len)
7177{
7178 int ret = 0;
7179
7180 vos_ssr_protect(__func__);
7181 ret = __wlan_hdd_cfg80211_setband(wiphy,
7182 wdev, data, data_len);
7183 vos_ssr_unprotect(__func__);
7184
7185 return ret;
7186}
7187
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307188#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7189/**
7190 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7191 * @hdd_ctx: HDD context
7192 * @request_id: [input] request id
7193 * @pattern_id: [output] pattern id
7194 *
7195 * This function loops through request id to pattern id array
7196 * if the slot is available, store the request id and return pattern id
7197 * if entry exists, return the pattern id
7198 *
7199 * Return: 0 on success and errno on failure
7200 */
7201static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7202 uint32_t request_id,
7203 uint8_t *pattern_id)
7204{
7205 uint32_t i;
7206
7207 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7208 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7209 {
7210 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7211 {
7212 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7213 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7214 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7215 return 0;
7216 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7217 request_id) {
7218 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7219 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7220 return 0;
7221 }
7222 }
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return -EINVAL;
7225}
7226
7227/**
7228 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7229 * @hdd_ctx: HDD context
7230 * @request_id: [input] request id
7231 * @pattern_id: [output] pattern id
7232 *
7233 * This function loops through request id to pattern id array
7234 * reset request id to 0 (slot available again) and
7235 * return pattern id
7236 *
7237 * Return: 0 on success and errno on failure
7238 */
7239static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7240 uint32_t request_id,
7241 uint8_t *pattern_id)
7242{
7243 uint32_t i;
7244
7245 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7246 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7247 {
7248 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7249 {
7250 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7251 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7252 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7253 return 0;
7254 }
7255 }
7256 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7257 return -EINVAL;
7258}
7259
7260
7261/*
7262 * define short names for the global vendor params
7263 * used by __wlan_hdd_cfg80211_offloaded_packets()
7264 */
7265#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7266#define PARAM_REQUEST_ID \
7267 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7268#define PARAM_CONTROL \
7269 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7270#define PARAM_IP_PACKET \
7271 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7272#define PARAM_SRC_MAC_ADDR \
7273 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7274#define PARAM_DST_MAC_ADDR \
7275 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7276#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7277
7278/**
7279 * wlan_hdd_add_tx_ptrn() - add tx pattern
7280 * @adapter: adapter pointer
7281 * @hdd_ctx: hdd context
7282 * @tb: nl attributes
7283 *
7284 * This function reads the NL attributes and forms a AddTxPtrn message
7285 * posts it to SME.
7286 *
7287 */
7288static int
7289wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7290 struct nlattr **tb)
7291{
7292 struct sSirAddPeriodicTxPtrn *add_req;
7293 eHalStatus status;
7294 uint32_t request_id, ret, len;
7295 uint8_t pattern_id = 0;
7296 v_MACADDR_t dst_addr;
7297 uint16_t eth_type = htons(ETH_P_IP);
7298
7299 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7300 {
7301 hddLog(LOGE, FL("Not in Connected state!"));
7302 return -ENOTSUPP;
7303 }
7304
7305 add_req = vos_mem_malloc(sizeof(*add_req));
7306 if (!add_req)
7307 {
7308 hddLog(LOGE, FL("memory allocation failed"));
7309 return -ENOMEM;
7310 }
7311
7312 /* Parse and fetch request Id */
7313 if (!tb[PARAM_REQUEST_ID])
7314 {
7315 hddLog(LOGE, FL("attr request id failed"));
7316 goto fail;
7317 }
7318
7319 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7320 hddLog(LOG1, FL("Request Id: %u"), request_id);
7321 if (request_id == 0)
7322 {
7323 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307324 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307325 }
7326
7327 if (!tb[PARAM_PERIOD])
7328 {
7329 hddLog(LOGE, FL("attr period failed"));
7330 goto fail;
7331 }
7332 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7333 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7334 if (add_req->usPtrnIntervalMs == 0)
7335 {
7336 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7337 goto fail;
7338 }
7339
7340 if (!tb[PARAM_SRC_MAC_ADDR])
7341 {
7342 hddLog(LOGE, FL("attr source mac address failed"));
7343 goto fail;
7344 }
7345 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7346 VOS_MAC_ADDR_SIZE);
7347 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7348 MAC_ADDR_ARRAY(add_req->macAddress));
7349
7350 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7351 VOS_MAC_ADDR_SIZE))
7352 {
7353 hddLog(LOGE,
7354 FL("input src mac address and connected ap bssid are different"));
7355 goto fail;
7356 }
7357
7358 if (!tb[PARAM_DST_MAC_ADDR])
7359 {
7360 hddLog(LOGE, FL("attr dst mac address failed"));
7361 goto fail;
7362 }
7363 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7364 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7365 MAC_ADDR_ARRAY(dst_addr.bytes));
7366
7367 if (!tb[PARAM_IP_PACKET])
7368 {
7369 hddLog(LOGE, FL("attr ip packet failed"));
7370 goto fail;
7371 }
7372 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7373 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7374
7375 if (add_req->ucPtrnSize < 0 ||
7376 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7377 HDD_ETH_HEADER_LEN))
7378 {
7379 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7380 add_req->ucPtrnSize);
7381 goto fail;
7382 }
7383
7384 len = 0;
7385 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7386 len += VOS_MAC_ADDR_SIZE;
7387 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7388 VOS_MAC_ADDR_SIZE);
7389 len += VOS_MAC_ADDR_SIZE;
7390 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7391 len += 2;
7392
7393 /*
7394 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7395 * ------------------------------------------------------------
7396 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7397 * ------------------------------------------------------------
7398 */
7399 vos_mem_copy(&add_req->ucPattern[len],
7400 nla_data(tb[PARAM_IP_PACKET]),
7401 add_req->ucPtrnSize);
7402 add_req->ucPtrnSize += len;
7403
7404 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7405 add_req->ucPattern, add_req->ucPtrnSize);
7406
7407 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7408 if (ret)
7409 {
7410 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7411 goto fail;
7412 }
7413 add_req->ucPtrnId = pattern_id;
7414 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7415
7416 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7417 if (!HAL_STATUS_SUCCESS(status))
7418 {
7419 hddLog(LOGE,
7420 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7421 goto fail;
7422 }
7423
7424 EXIT();
7425 vos_mem_free(add_req);
7426 return 0;
7427
7428fail:
7429 vos_mem_free(add_req);
7430 return -EINVAL;
7431}
7432
7433/**
7434 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7435 * @adapter: adapter pointer
7436 * @hdd_ctx: hdd context
7437 * @tb: nl attributes
7438 *
7439 * This function reads the NL attributes and forms a DelTxPtrn message
7440 * posts it to SME.
7441 *
7442 */
7443static int
7444wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7445 struct nlattr **tb)
7446{
7447 struct sSirDelPeriodicTxPtrn *del_req;
7448 eHalStatus status;
7449 uint32_t request_id, ret;
7450 uint8_t pattern_id = 0;
7451
7452 /* Parse and fetch request Id */
7453 if (!tb[PARAM_REQUEST_ID])
7454 {
7455 hddLog(LOGE, FL("attr request id failed"));
7456 return -EINVAL;
7457 }
7458 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7459 if (request_id == 0)
7460 {
7461 hddLog(LOGE, FL("request_id cannot be zero"));
7462 return -EINVAL;
7463 }
7464
7465 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7466 if (ret)
7467 {
7468 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7469 return -EINVAL;
7470 }
7471
7472 del_req = vos_mem_malloc(sizeof(*del_req));
7473 if (!del_req)
7474 {
7475 hddLog(LOGE, FL("memory allocation failed"));
7476 return -ENOMEM;
7477 }
7478
7479 vos_mem_set(del_req, sizeof(*del_req), 0);
7480 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7481 VOS_MAC_ADDR_SIZE);
7482 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7483 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7484 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7485 request_id, pattern_id, del_req->ucPatternIdBitmap);
7486
7487 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7488 if (!HAL_STATUS_SUCCESS(status))
7489 {
7490 hddLog(LOGE,
7491 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7492 goto fail;
7493 }
7494
7495 EXIT();
7496 vos_mem_free(del_req);
7497 return 0;
7498
7499fail:
7500 vos_mem_free(del_req);
7501 return -EINVAL;
7502}
7503
7504
7505/**
7506 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7507 * @wiphy: Pointer to wireless phy
7508 * @wdev: Pointer to wireless device
7509 * @data: Pointer to data
7510 * @data_len: Data length
7511 *
7512 * Return: 0 on success, negative errno on failure
7513 */
7514static int
7515__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7516 struct wireless_dev *wdev,
7517 const void *data,
7518 int data_len)
7519{
7520 struct net_device *dev = wdev->netdev;
7521 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7522 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7523 struct nlattr *tb[PARAM_MAX + 1];
7524 uint8_t control;
7525 int ret;
7526 static const struct nla_policy policy[PARAM_MAX + 1] =
7527 {
7528 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7529 [PARAM_CONTROL] = { .type = NLA_U32 },
7530 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7531 .len = VOS_MAC_ADDR_SIZE },
7532 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7533 .len = VOS_MAC_ADDR_SIZE },
7534 [PARAM_PERIOD] = { .type = NLA_U32 },
7535 };
7536
7537 ENTER();
7538
7539 ret = wlan_hdd_validate_context(hdd_ctx);
7540 if (0 != ret)
7541 {
7542 hddLog(LOGE, FL("HDD context is not valid"));
7543 return ret;
7544 }
7545
7546 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7547 {
7548 hddLog(LOGE,
7549 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7550 return -ENOTSUPP;
7551 }
7552
7553 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7554 {
7555 hddLog(LOGE, FL("Invalid ATTR"));
7556 return -EINVAL;
7557 }
7558
7559 if (!tb[PARAM_CONTROL])
7560 {
7561 hddLog(LOGE, FL("attr control failed"));
7562 return -EINVAL;
7563 }
7564 control = nla_get_u32(tb[PARAM_CONTROL]);
7565 hddLog(LOG1, FL("Control: %d"), control);
7566
7567 if (control == WLAN_START_OFFLOADED_PACKETS)
7568 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7569 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7570 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7571 else
7572 {
7573 hddLog(LOGE, FL("Invalid control: %d"), control);
7574 return -EINVAL;
7575 }
7576}
7577
7578/*
7579 * done with short names for the global vendor params
7580 * used by __wlan_hdd_cfg80211_offloaded_packets()
7581 */
7582#undef PARAM_MAX
7583#undef PARAM_REQUEST_ID
7584#undef PARAM_CONTROL
7585#undef PARAM_IP_PACKET
7586#undef PARAM_SRC_MAC_ADDR
7587#undef PARAM_DST_MAC_ADDR
7588#undef PARAM_PERIOD
7589
7590/**
7591 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7592 * @wiphy: wiphy structure pointer
7593 * @wdev: Wireless device structure pointer
7594 * @data: Pointer to the data received
7595 * @data_len: Length of @data
7596 *
7597 * Return: 0 on success; errno on failure
7598 */
7599static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7600 struct wireless_dev *wdev,
7601 const void *data,
7602 int data_len)
7603{
7604 int ret = 0;
7605
7606 vos_ssr_protect(__func__);
7607 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7608 wdev, data, data_len);
7609 vos_ssr_unprotect(__func__);
7610
7611 return ret;
7612}
7613#endif
7614
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307615static const struct
7616nla_policy
7617qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307618 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7619 .type = NLA_BINARY,
7620 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307621};
7622
7623/**
7624 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7625 * get link properties like nss, rate flags and operating frequency for
7626 * the connection with the given peer.
7627 * @wiphy: WIPHY structure pointer
7628 * @wdev: Wireless device structure pointer
7629 * @data: Pointer to the data received
7630 * @data_len: Length of the data received
7631 *
7632 * This function return the above link properties on success.
7633 *
7634 * Return: 0 on success and errno on failure
7635 */
7636static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7637 struct wireless_dev *wdev,
7638 const void *data,
7639 int data_len)
7640{
7641 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7642 struct net_device *dev = wdev->netdev;
7643 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7644 hdd_station_ctx_t *hdd_sta_ctx;
7645 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7646 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7647 uint32_t sta_id;
7648 struct sk_buff *reply_skb;
7649 uint32_t rate_flags = 0;
7650 uint8_t nss;
7651 uint8_t final_rate_flags = 0;
7652 uint32_t freq;
7653 v_CONTEXT_t pVosContext = NULL;
7654 ptSapContext pSapCtx = NULL;
7655
7656 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7658 return -EINVAL;
7659 }
7660
7661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7662 qca_wlan_vendor_attr_policy)) {
7663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7664 return -EINVAL;
7665 }
7666
7667 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7668 hddLog(VOS_TRACE_LEVEL_ERROR,
7669 FL("Attribute peerMac not provided for mode=%d"),
7670 adapter->device_mode);
7671 return -EINVAL;
7672 }
7673
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307674 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("Attribute peerMac is invalid=%d"),
7677 adapter->device_mode);
7678 return -EINVAL;
7679 }
7680
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307681 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7682 sizeof(peer_mac));
7683 hddLog(VOS_TRACE_LEVEL_INFO,
7684 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7685 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7686
7687 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7688 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7689 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7690 if ((hdd_sta_ctx->conn_info.connState !=
7691 eConnectionState_Associated) ||
7692 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7693 VOS_MAC_ADDRESS_LEN)) {
7694 hddLog(VOS_TRACE_LEVEL_ERROR,
7695 FL("Not Associated to mac "MAC_ADDRESS_STR),
7696 MAC_ADDR_ARRAY(peer_mac));
7697 return -EINVAL;
7698 }
7699
7700 nss = 1; //pronto supports only one spatial stream
7701 freq = vos_chan_to_freq(
7702 hdd_sta_ctx->conn_info.operationChannel);
7703 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7704
7705 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7706 adapter->device_mode == WLAN_HDD_SOFTAP) {
7707
7708 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7709 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7710 if(pSapCtx == NULL){
7711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7712 FL("psapCtx is NULL"));
7713 return -ENOENT;
7714 }
7715
7716
7717 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7718 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7719 !vos_is_macaddr_broadcast(
7720 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7721 vos_mem_compare(
7722 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7723 peer_mac, VOS_MAC_ADDRESS_LEN))
7724 break;
7725 }
7726
7727 if (WLAN_MAX_STA_COUNT == sta_id) {
7728 hddLog(VOS_TRACE_LEVEL_ERROR,
7729 FL("No active peer with mac="MAC_ADDRESS_STR),
7730 MAC_ADDR_ARRAY(peer_mac));
7731 return -EINVAL;
7732 }
7733
7734 nss = 1; //pronto supports only one spatial stream
7735 freq = vos_chan_to_freq(
7736 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7737 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7738 } else {
7739 hddLog(VOS_TRACE_LEVEL_ERROR,
7740 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7741 MAC_ADDR_ARRAY(peer_mac));
7742 return -EINVAL;
7743 }
7744
7745 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7746 if (rate_flags & eHAL_TX_RATE_VHT80) {
7747 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307748#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7749 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307750 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307751#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307752 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7753 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307754#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7755 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307756 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307758 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7759 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7760 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7761 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307762#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7763 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307764 if (rate_flags & eHAL_TX_RATE_HT40)
7765 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307766#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307767 }
7768
7769 if (rate_flags & eHAL_TX_RATE_SGI) {
7770 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7771 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7772 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7773 }
7774 }
7775
7776 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7777 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7778
7779 if (NULL == reply_skb) {
7780 hddLog(VOS_TRACE_LEVEL_ERROR,
7781 FL("getLinkProperties: skb alloc failed"));
7782 return -EINVAL;
7783 }
7784
7785 if (nla_put_u8(reply_skb,
7786 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7787 nss) ||
7788 nla_put_u8(reply_skb,
7789 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7790 final_rate_flags) ||
7791 nla_put_u32(reply_skb,
7792 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7793 freq)) {
7794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7795 kfree_skb(reply_skb);
7796 return -EINVAL;
7797 }
7798
7799 return cfg80211_vendor_cmd_reply(reply_skb);
7800}
7801
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307802#define BEACON_MISS_THRESH_2_4 \
7803 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7804#define BEACON_MISS_THRESH_5_0 \
7805 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307806#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7807#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7808#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7809#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307810#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7811 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307812
7813/**
7814 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7815 * vendor command
7816 *
7817 * @wiphy: wiphy device pointer
7818 * @wdev: wireless device pointer
7819 * @data: Vendor command data buffer
7820 * @data_len: Buffer length
7821 *
7822 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7823 *
7824 * Return: EOK or other error codes.
7825 */
7826
7827static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7828 struct wireless_dev *wdev,
7829 const void *data,
7830 int data_len)
7831{
7832 struct net_device *dev = wdev->netdev;
7833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7834 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7835 hdd_station_ctx_t *pHddStaCtx;
7836 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7837 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307838 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839 eHalStatus status;
7840 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307841 uint8_t hb_thresh_val;
7842
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307843 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7844 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7845 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307846 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7847 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7848 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307849 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7850 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307851 };
7852
7853 ENTER();
7854
7855 if (VOS_FTM_MODE == hdd_get_conparam()) {
7856 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7857 return -EINVAL;
7858 }
7859
7860 ret_val = wlan_hdd_validate_context(pHddCtx);
7861 if (ret_val) {
7862 return ret_val;
7863 }
7864
7865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7866
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7868 hddLog(LOGE, FL("Invalid ATTR"));
7869 return -EINVAL;
7870 }
7871
7872 /* check the Wifi Capability */
7873 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7874 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7875 {
7876 hddLog(VOS_TRACE_LEVEL_ERROR,
7877 FL("WIFICONFIG not supported by Firmware"));
7878 return -EINVAL;
7879 }
7880
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307881 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7882 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7883 modifyRoamParamsReq.value =
7884 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7885
7886 if (eHAL_STATUS_SUCCESS !=
7887 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7888 {
7889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7890 ret_val = -EINVAL;
7891 }
7892 return ret_val;
7893 }
7894
7895 /* Moved this down in order to provide provision to set beacon
7896 * miss penalty count irrespective of connection state.
7897 */
7898 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7899 hddLog(LOGE, FL("Not in Connected state!"));
7900 return -ENOTSUPP;
7901 }
7902
7903 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307904
7905 if (!pReq) {
7906 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7907 "%s: Not able to allocate memory for tSetWifiConfigParams",
7908 __func__);
7909 return eHAL_STATUS_E_MALLOC_FAILED;
7910 }
7911
7912 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7913
7914 pReq->sessionId = pAdapter->sessionId;
7915 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7916
7917 if (tb[PARAM_MODULATED_DTIM]) {
7918 pReq->paramValue = nla_get_u32(
7919 tb[PARAM_MODULATED_DTIM]);
7920 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7921 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307922 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307923 hdd_set_pwrparams(pHddCtx);
7924 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7925 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7926
7927 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7928 iw_full_power_cbfn, pAdapter,
7929 eSME_FULL_PWR_NEEDED_BY_HDD);
7930 }
7931 else
7932 {
7933 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7934 }
7935 }
7936
7937 if (tb[PARAM_STATS_AVG_FACTOR]) {
7938 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7939 pReq->paramValue = nla_get_u16(
7940 tb[PARAM_STATS_AVG_FACTOR]);
7941 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7942 pReq->paramType, pReq->paramValue);
7943 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7944
7945 if (eHAL_STATUS_SUCCESS != status)
7946 {
7947 vos_mem_free(pReq);
7948 pReq = NULL;
7949 ret_val = -EPERM;
7950 return ret_val;
7951 }
7952 }
7953
7954
7955 if (tb[PARAM_GUARD_TIME]) {
7956 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7957 pReq->paramValue = nla_get_u32(
7958 tb[PARAM_GUARD_TIME]);
7959 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7960 pReq->paramType, pReq->paramValue);
7961 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7962
7963 if (eHAL_STATUS_SUCCESS != status)
7964 {
7965 vos_mem_free(pReq);
7966 pReq = NULL;
7967 ret_val = -EPERM;
7968 return ret_val;
7969 }
7970
7971 }
7972
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307973 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7974 hb_thresh_val = nla_get_u8(
7975 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7976
7977 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7978 hb_thresh_val);
7979 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7980 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7981 NULL, eANI_BOOLEAN_FALSE);
7982
7983 status = sme_update_hb_threshold(
7984 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7985 WNI_CFG_HEART_BEAT_THRESHOLD,
7986 hb_thresh_val, eCSR_BAND_24);
7987 if (eHAL_STATUS_SUCCESS != status) {
7988 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7989 vos_mem_free(pReq);
7990 pReq = NULL;
7991 return -EPERM;
7992 }
7993 }
7994
7995 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7996 hb_thresh_val = nla_get_u8(
7997 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7998
7999 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8000 hb_thresh_val);
8001 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8002 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8003 NULL, eANI_BOOLEAN_FALSE);
8004
8005 status = sme_update_hb_threshold(
8006 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD,
8008 hb_thresh_val, eCSR_BAND_5G);
8009 if (eHAL_STATUS_SUCCESS != status) {
8010 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8011 vos_mem_free(pReq);
8012 pReq = NULL;
8013 return -EPERM;
8014 }
8015 }
8016
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308017 EXIT();
8018 return ret_val;
8019}
8020
8021/**
8022 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8023 * vendor command
8024 *
8025 * @wiphy: wiphy device pointer
8026 * @wdev: wireless device pointer
8027 * @data: Vendor command data buffer
8028 * @data_len: Buffer length
8029 *
8030 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8031 *
8032 * Return: EOK or other error codes.
8033 */
8034static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8035 struct wireless_dev *wdev,
8036 const void *data,
8037 int data_len)
8038{
8039 int ret;
8040
8041 vos_ssr_protect(__func__);
8042 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8043 data, data_len);
8044 vos_ssr_unprotect(__func__);
8045
8046 return ret;
8047}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308048
8049/*
8050 * define short names for the global vendor params
8051 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8052 */
8053#define STATS_SET_INVALID \
8054 QCA_ATTR_NUD_STATS_SET_INVALID
8055#define STATS_SET_START \
8056 QCA_ATTR_NUD_STATS_SET_START
8057#define STATS_GW_IPV4 \
8058 QCA_ATTR_NUD_STATS_GW_IPV4
8059#define STATS_SET_MAX \
8060 QCA_ATTR_NUD_STATS_SET_MAX
8061
8062const struct nla_policy
8063qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8064{
8065 [STATS_SET_START] = {.type = NLA_FLAG },
8066 [STATS_GW_IPV4] = {.type = NLA_U32 },
8067};
8068
8069/**
8070 * hdd_set_nud_stats_cb() - hdd callback api to get status
8071 * @data: pointer to adapter
8072 * @rsp: status
8073 *
8074 * Return: None
8075 */
8076static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8077{
8078
8079 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8080
8081 if (NULL == adapter)
8082 return;
8083
8084 if (VOS_STATUS_SUCCESS == rsp) {
8085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8086 "%s success received STATS_SET_START", __func__);
8087 } else {
8088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8089 "%s STATS_SET_START Failed!!", __func__);
8090 }
8091 return;
8092}
8093
8094/**
8095 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8096 * @wiphy: pointer to wireless wiphy structure.
8097 * @wdev: pointer to wireless_dev structure.
8098 * @data: pointer to apfind configuration data.
8099 * @data_len: the length in byte of apfind data.
8100 *
8101 * This is called when wlan driver needs to send arp stats to
8102 * firmware.
8103 *
8104 * Return: An error code or 0 on success.
8105 */
8106static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8107 struct wireless_dev *wdev,
8108 const void *data, int data_len)
8109{
8110 struct nlattr *tb[STATS_SET_MAX + 1];
8111 struct net_device *dev = wdev->netdev;
8112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8113 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308114 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308115 setArpStatsParams arp_stats_params;
8116 int err = 0;
8117
8118 ENTER();
8119
8120 err = wlan_hdd_validate_context(hdd_ctx);
8121 if (0 != err)
8122 return err;
8123
8124 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8127 return -EINVAL;
8128 }
8129
8130 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8131 qca_wlan_vendor_set_nud_stats);
8132 if (err)
8133 {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s STATS_SET_START ATTR", __func__);
8136 return err;
8137 }
8138
8139 if (tb[STATS_SET_START])
8140 {
8141 if (!tb[STATS_GW_IPV4]) {
8142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8143 "%s STATS_SET_START CMD", __func__);
8144 return -EINVAL;
8145 }
8146 arp_stats_params.flag = true;
8147 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8148 } else {
8149 arp_stats_params.flag = false;
8150 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308151 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8153 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308154 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8155 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308156
8157 arp_stats_params.pkt_type = 1; // ARP packet type
8158
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308159 if (arp_stats_params.flag) {
8160 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8161 WLANTL_SetARPFWDatapath(pVosContext, true);
8162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8163 "%s Set FW in data path for ARP with tgt IP :%d",
8164 __func__, hdd_ctx->track_arp_ip);
8165 }
8166 else {
8167 WLANTL_SetARPFWDatapath(pVosContext, false);
8168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8169 "%s Remove FW from data path", __func__);
8170 }
8171
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308172 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8173 arp_stats_params.data_ctx = adapter;
8174
8175 if (eHAL_STATUS_SUCCESS !=
8176 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8178 "%s STATS_SET_START CMD Failed!!", __func__);
8179 return -EINVAL;
8180 }
8181
8182 EXIT();
8183
8184 return err;
8185}
8186
8187/**
8188 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8189 * @wiphy: pointer to wireless wiphy structure.
8190 * @wdev: pointer to wireless_dev structure.
8191 * @data: pointer to apfind configuration data.
8192 * @data_len: the length in byte of apfind data.
8193 *
8194 * This is called when wlan driver needs to send arp stats to
8195 * firmware.
8196 *
8197 * Return: An error code or 0 on success.
8198 */
8199static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8200 struct wireless_dev *wdev,
8201 const void *data, int data_len)
8202{
8203 int ret;
8204
8205 vos_ssr_protect(__func__);
8206 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8207 vos_ssr_unprotect(__func__);
8208
8209 return ret;
8210}
8211#undef STATS_SET_INVALID
8212#undef STATS_SET_START
8213#undef STATS_GW_IPV4
8214#undef STATS_SET_MAX
8215
8216/*
8217 * define short names for the global vendor params
8218 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8219 */
8220#define STATS_GET_INVALID \
8221 QCA_ATTR_NUD_STATS_SET_INVALID
8222#define COUNT_FROM_NETDEV \
8223 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8224#define COUNT_TO_LOWER_MAC \
8225 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8226#define RX_COUNT_BY_LOWER_MAC \
8227 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8228#define COUNT_TX_SUCCESS \
8229 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8230#define RSP_RX_COUNT_BY_LOWER_MAC \
8231 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8232#define RSP_RX_COUNT_BY_UPPER_MAC \
8233 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8234#define RSP_COUNT_TO_NETDEV \
8235 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8236#define RSP_COUNT_OUT_OF_ORDER_DROP \
8237 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8238#define AP_LINK_ACTIVE \
8239 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8240#define AP_LINK_DAD \
8241 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8242#define STATS_GET_MAX \
8243 QCA_ATTR_NUD_STATS_GET_MAX
8244
8245const struct nla_policy
8246qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8247{
8248 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8249 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8250 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8251 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8252 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8253 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8254 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8255 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8256 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8257 [AP_LINK_DAD] = {.type = NLA_FLAG },
8258};
8259
8260static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8261{
8262
8263 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308264 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308265 struct hdd_nud_stats_context *context;
8266 int status;
8267
8268 ENTER();
8269
8270 if (NULL == adapter)
8271 return;
8272
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308273 if (!rsp) {
8274 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308275 return;
8276 }
8277
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308278 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8279 status = wlan_hdd_validate_context(hdd_ctx);
8280 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308281 return;
8282 }
8283
8284 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8285 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8286 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8287 adapter->dad |= rsp->dad;
8288
8289 spin_lock(&hdd_context_lock);
8290 context = &hdd_ctx->nud_stats_context;
8291 complete(&context->response_event);
8292 spin_unlock(&hdd_context_lock);
8293
8294 return;
8295}
8296static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8297 struct wireless_dev *wdev,
8298 const void *data, int data_len)
8299{
8300 int err = 0;
8301 unsigned long rc;
8302 struct hdd_nud_stats_context *context;
8303 struct net_device *dev = wdev->netdev;
8304 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8305 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8306 getArpStatsParams arp_stats_params;
8307 struct sk_buff *skb;
8308
8309 ENTER();
8310
8311 err = wlan_hdd_validate_context(hdd_ctx);
8312 if (0 != err)
8313 return err;
8314
8315 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8316 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8317 arp_stats_params.data_ctx = adapter;
8318
8319 spin_lock(&hdd_context_lock);
8320 context = &hdd_ctx->nud_stats_context;
8321 INIT_COMPLETION(context->response_event);
8322 spin_unlock(&hdd_context_lock);
8323
8324 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8326 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8327 return -EINVAL;
8328 }
8329
8330 if (eHAL_STATUS_SUCCESS !=
8331 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8333 "%s STATS_SET_START CMD Failed!!", __func__);
8334 return -EINVAL;
8335 }
8336
8337 rc = wait_for_completion_timeout(&context->response_event,
8338 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8339 if (!rc)
8340 {
8341 hddLog(LOGE,
8342 FL("Target response timed out request "));
8343 return -ETIMEDOUT;
8344 }
8345
8346 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8347 WLAN_NUD_STATS_LEN);
8348 if (!skb)
8349 {
8350 hddLog(VOS_TRACE_LEVEL_ERROR,
8351 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8352 __func__);
8353 return -ENOMEM;
8354 }
8355
8356 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8357 adapter->hdd_stats.hddArpStats.txCount) ||
8358 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8359 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8360 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8361 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8362 nla_put_u16(skb, COUNT_TX_SUCCESS,
8363 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8364 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8365 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8366 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8367 adapter->hdd_stats.hddArpStats.rxCount) ||
8368 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8369 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8370 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8371 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8372 hddLog(LOGE, FL("nla put fail"));
8373 kfree_skb(skb);
8374 return -EINVAL;
8375 }
8376 if (adapter->con_status)
8377 nla_put_flag(skb, AP_LINK_ACTIVE);
8378 if (adapter->dad)
8379 nla_put_flag(skb, AP_LINK_DAD);
8380
8381 cfg80211_vendor_cmd_reply(skb);
8382 return err;
8383}
8384
8385static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8386 struct wireless_dev *wdev,
8387 const void *data, int data_len)
8388{
8389 int ret;
8390
8391 vos_ssr_protect(__func__);
8392 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8393 vos_ssr_unprotect(__func__);
8394
8395 return ret;
8396}
8397
8398#undef QCA_ATTR_NUD_STATS_SET_INVALID
8399#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8400#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8401#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8402#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8403#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8404#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8405#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8406#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8407#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8408#undef QCA_ATTR_NUD_STATS_GET_MAX
8409
8410
8411
Kapil Guptaee33bf12016-12-20 18:27:37 +05308412#ifdef WLAN_FEATURE_APFIND
8413/**
8414 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8415 * @wiphy: pointer to wireless wiphy structure.
8416 * @wdev: pointer to wireless_dev structure.
8417 * @data: pointer to apfind configuration data.
8418 * @data_len: the length in byte of apfind data.
8419 *
8420 * This is called when wlan driver needs to send APFIND configurations to
8421 * firmware.
8422 *
8423 * Return: An error code or 0 on success.
8424 */
8425static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8426 struct wireless_dev *wdev,
8427 const void *data, int data_len)
8428{
8429 struct sme_ap_find_request_req apfind_req;
8430 VOS_STATUS status;
8431 int ret_val;
8432 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8433
8434 ENTER();
8435
8436 ret_val = wlan_hdd_validate_context(hdd_ctx);
8437 if (ret_val)
8438 return ret_val;
8439
8440 if (VOS_FTM_MODE == hdd_get_conparam()) {
8441 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8442 return -EPERM;
8443 }
8444
8445 apfind_req.request_data_len = data_len;
8446 apfind_req.request_data = data;
8447
8448 status = sme_apfind_set_cmd(&apfind_req);
8449 if (VOS_STATUS_SUCCESS != status) {
8450 ret_val = -EIO;
8451 }
8452 return ret_val;
8453}
8454
8455/**
8456 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8457 * @wiphy: pointer to wireless wiphy structure.
8458 * @wdev: pointer to wireless_dev structure.
8459 * @data: pointer to apfind configuration data.
8460 * @data_len: the length in byte of apfind data.
8461 *
8462 * This is called when wlan driver needs to send APFIND configurations to
8463 * firmware.
8464 *
8465 * Return: An error code or 0 on success.
8466 */
8467static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8468 struct wireless_dev *wdev,
8469 const void *data, int data_len)
8470{
8471 int ret;
8472
8473 vos_ssr_protect(__func__);
8474 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8475 vos_ssr_unprotect(__func__);
8476
8477 return ret;
8478}
8479#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308480const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8481{
Mukul Sharma2a271632014-10-13 14:59:01 +05308482 {
8483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8486 WIPHY_VENDOR_CMD_NEED_NETDEV |
8487 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308488 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308489 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308490
8491 {
8492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8495 WIPHY_VENDOR_CMD_NEED_NETDEV |
8496 WIPHY_VENDOR_CMD_NEED_RUNNING,
8497 .doit = wlan_hdd_cfg80211_nan_request
8498 },
8499
Sunil Duttc69bccb2014-05-26 21:30:20 +05308500#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8501 {
8502 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8503 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8504 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8505 WIPHY_VENDOR_CMD_NEED_NETDEV |
8506 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308507 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308508 },
8509
8510 {
8511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8514 WIPHY_VENDOR_CMD_NEED_NETDEV |
8515 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308516 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308517 },
8518
8519 {
8520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8523 WIPHY_VENDOR_CMD_NEED_NETDEV |
8524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308526 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308527#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308528#ifdef WLAN_FEATURE_EXTSCAN
8529 {
8530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8533 WIPHY_VENDOR_CMD_NEED_NETDEV |
8534 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308535 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308536 },
8537 {
8538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8541 WIPHY_VENDOR_CMD_NEED_NETDEV |
8542 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308543 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308544 },
8545 {
8546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8549 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308550 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308551 },
8552 {
8553 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8554 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8555 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8556 WIPHY_VENDOR_CMD_NEED_NETDEV |
8557 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308558 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308559 },
8560 {
8561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8564 WIPHY_VENDOR_CMD_NEED_NETDEV |
8565 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308566 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308567 },
8568 {
8569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8572 WIPHY_VENDOR_CMD_NEED_NETDEV |
8573 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308574 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308575 },
8576 {
8577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8580 WIPHY_VENDOR_CMD_NEED_NETDEV |
8581 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308582 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308583 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308584#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308585/*EXT TDLS*/
8586 {
8587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8590 WIPHY_VENDOR_CMD_NEED_NETDEV |
8591 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308592 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308593 },
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308600 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308601 },
8602 {
8603 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8604 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8605 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8606 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308607 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308608 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308609 {
8610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8613 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308614 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308615 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308616 {
8617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8620 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308621 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308622 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308623 {
8624 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8625 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8626 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8627 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308628 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308629 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308635 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308636 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308637 {
8638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8641 WIPHY_VENDOR_CMD_NEED_NETDEV |
8642 WIPHY_VENDOR_CMD_NEED_RUNNING,
8643 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8644 },
8645 {
8646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8649 WIPHY_VENDOR_CMD_NEED_NETDEV |
8650 WIPHY_VENDOR_CMD_NEED_RUNNING,
8651 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308652 },
8653 {
8654 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8655 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8656 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8657 WIPHY_VENDOR_CMD_NEED_NETDEV,
8658 .doit = wlan_hdd_cfg80211_wifi_logger_start
8659 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV|
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
8666 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308667 },
8668 {
8669 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8670 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8671 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8672 WIPHY_VENDOR_CMD_NEED_NETDEV |
8673 WIPHY_VENDOR_CMD_NEED_RUNNING,
8674 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308675 },
8676 {
8677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8680 WIPHY_VENDOR_CMD_NEED_NETDEV |
8681 WIPHY_VENDOR_CMD_NEED_RUNNING,
8682 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308683 },
8684#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
8691 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308692 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308693#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308694 {
8695 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8696 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8697 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8698 WIPHY_VENDOR_CMD_NEED_NETDEV |
8699 WIPHY_VENDOR_CMD_NEED_RUNNING,
8700 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308701 },
8702 {
8703 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8704 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8705 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8706 WIPHY_VENDOR_CMD_NEED_NETDEV |
8707 WIPHY_VENDOR_CMD_NEED_RUNNING,
8708 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308709 },
8710#ifdef WLAN_FEATURE_APFIND
8711 {
8712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8715 WIPHY_VENDOR_CMD_NEED_NETDEV,
8716 .doit = wlan_hdd_cfg80211_apfind_cmd
8717 },
8718#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV |
8724 WIPHY_VENDOR_CMD_NEED_RUNNING,
8725 .doit = wlan_hdd_cfg80211_set_nud_stats
8726 },
8727 {
8728 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8729 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8730 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8731 WIPHY_VENDOR_CMD_NEED_NETDEV |
8732 WIPHY_VENDOR_CMD_NEED_RUNNING,
8733 .doit = wlan_hdd_cfg80211_get_nud_stats
8734 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308735 {
8736 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8737 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8738 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8739 WIPHY_VENDOR_CMD_NEED_NETDEV |
8740 WIPHY_VENDOR_CMD_NEED_RUNNING,
8741 .doit = hdd_cfg80211_get_station_cmd
8742 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308743};
8744
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008745/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308746static const
8747struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008748{
8749#ifdef FEATURE_WLAN_CH_AVOID
8750 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308751 .vendor_id = QCA_NL80211_VENDOR_ID,
8752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008753 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308754#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8755#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8756 {
8757 /* Index = 1*/
8758 .vendor_id = QCA_NL80211_VENDOR_ID,
8759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8760 },
8761 {
8762 /* Index = 2*/
8763 .vendor_id = QCA_NL80211_VENDOR_ID,
8764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8765 },
8766 {
8767 /* Index = 3*/
8768 .vendor_id = QCA_NL80211_VENDOR_ID,
8769 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8770 },
8771 {
8772 /* Index = 4*/
8773 .vendor_id = QCA_NL80211_VENDOR_ID,
8774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8775 },
8776 {
8777 /* Index = 5*/
8778 .vendor_id = QCA_NL80211_VENDOR_ID,
8779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8780 },
8781 {
8782 /* Index = 6*/
8783 .vendor_id = QCA_NL80211_VENDOR_ID,
8784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8785 },
8786#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308787#ifdef WLAN_FEATURE_EXTSCAN
8788 {
8789 .vendor_id = QCA_NL80211_VENDOR_ID,
8790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8791 },
8792 {
8793 .vendor_id = QCA_NL80211_VENDOR_ID,
8794 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8795 },
8796 {
8797 .vendor_id = QCA_NL80211_VENDOR_ID,
8798 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8799 },
8800 {
8801 .vendor_id = QCA_NL80211_VENDOR_ID,
8802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8803 },
8804 {
8805 .vendor_id = QCA_NL80211_VENDOR_ID,
8806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8807 },
8808 {
8809 .vendor_id = QCA_NL80211_VENDOR_ID,
8810 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8811 },
8812 {
8813 .vendor_id = QCA_NL80211_VENDOR_ID,
8814 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8815 },
8816 {
8817 .vendor_id = QCA_NL80211_VENDOR_ID,
8818 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8819 },
8820 {
8821 .vendor_id = QCA_NL80211_VENDOR_ID,
8822 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8823 },
8824 {
8825 .vendor_id = QCA_NL80211_VENDOR_ID,
8826 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8827 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308828#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308829/*EXT TDLS*/
8830 {
8831 .vendor_id = QCA_NL80211_VENDOR_ID,
8832 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8833 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308834 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8835 .vendor_id = QCA_NL80211_VENDOR_ID,
8836 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8837 },
8838
Srinivas Dasari030bad32015-02-18 23:23:54 +05308839
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308840 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308841 .vendor_id = QCA_NL80211_VENDOR_ID,
8842 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8843 },
8844
Sushant Kaushik084f6592015-09-10 13:11:56 +05308845 {
8846 .vendor_id = QCA_NL80211_VENDOR_ID,
8847 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308848 },
8849 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8850 .vendor_id = QCA_NL80211_VENDOR_ID,
8851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8852 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308853 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8856 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308857 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8858 .vendor_id = QCA_NL80211_VENDOR_ID,
8859 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8860 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308861 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8862 .vendor_id = QCA_NL80211_VENDOR_ID,
8863 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8864 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308865 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8866 .vendor_id = QCA_NL80211_VENDOR_ID,
8867 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8868 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008869};
8870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308872 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 * This function is called by hdd_wlan_startup()
8874 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308875 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308877struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008878{
8879 struct wiphy *wiphy;
8880 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881 /*
8882 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 */
8884 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8885
8886 if (!wiphy)
8887 {
8888 /* Print error and jump into err label and free the memory */
8889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8890 return NULL;
8891 }
8892
Sunil Duttc69bccb2014-05-26 21:30:20 +05308893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 return wiphy;
8895}
8896
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308897#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8898 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8899/**
8900 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8901 * @wiphy: pointer to wiphy
8902 * @config: pointer to config
8903 *
8904 * Return: None
8905 */
8906static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8907 hdd_config_t *config)
8908{
8909 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8910 if (config->max_sched_scan_plan_interval)
8911 wiphy->max_sched_scan_plan_interval =
8912 config->max_sched_scan_plan_interval;
8913 if (config->max_sched_scan_plan_iterations)
8914 wiphy->max_sched_scan_plan_iterations =
8915 config->max_sched_scan_plan_iterations;
8916}
8917#else
8918static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8919 hdd_config_t *config)
8920{
8921}
8922#endif
8923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924/*
8925 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308926 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 * private ioctl to change the band value
8928 */
8929int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8930{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308931 int i, j;
8932 eNVChannelEnabledType channelEnabledState;
8933
Jeff Johnsone7245742012-09-05 17:12:55 -07008934 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308935
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308936 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308938
8939 if (NULL == wiphy->bands[i])
8940 {
8941 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8942 __func__, i);
8943 continue;
8944 }
8945
8946 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8947 {
8948 struct ieee80211_supported_band *band = wiphy->bands[i];
8949
8950 channelEnabledState = vos_nv_getChannelEnabledState(
8951 band->channels[j].hw_value);
8952
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308953 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308954 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308955 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308956 continue;
8957 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308958 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308959 {
8960 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8961 continue;
8962 }
8963
8964 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8965 NV_CHANNEL_INVALID == channelEnabledState)
8966 {
8967 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8968 }
8969 else if (NV_CHANNEL_DFS == channelEnabledState)
8970 {
8971 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8972 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8973 }
8974 else
8975 {
8976 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8977 |IEEE80211_CHAN_RADAR);
8978 }
8979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 }
8981 return 0;
8982}
8983/*
8984 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308985 * This function is called by hdd_wlan_startup()
8986 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 * This function is used to initialize and register wiphy structure.
8988 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308989int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 struct wiphy *wiphy,
8991 hdd_config_t *pCfg
8992 )
8993{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308994 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308995 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8996
Jeff Johnsone7245742012-09-05 17:12:55 -07008997 ENTER();
8998
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 /* Now bind the underlying wlan device with wiphy */
9000 set_wiphy_dev(wiphy, dev);
9001
9002 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009003
Kiet Lam6c583332013-10-14 05:37:09 +05309004#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009005 /* the flag for the other case would be initialzed in
9006 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9008 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9009#else
Amar Singhal0a402232013-10-11 20:57:16 -07009010 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309011#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309012#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009013
Amar Singhalfddc28c2013-09-05 13:03:40 -07009014 /* This will disable updating of NL channels from passive to
9015 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9017 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9018#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009019 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309020#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009021
Amar Singhala49cbc52013-10-08 18:37:44 -07009022
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009024 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9025 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9026 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009027 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309029 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309030#else
9031 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9032#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009033#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009034
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009035#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009036 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009037#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009038 || pCfg->isFastRoamIniFeatureEnabled
9039#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009040#ifdef FEATURE_WLAN_ESE
9041 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009042#endif
9043 )
9044 {
9045 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9046 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009047#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009048#ifdef FEATURE_WLAN_TDLS
9049 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9050 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9051#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309052#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309053 if (pCfg->configPNOScanSupport)
9054 {
9055 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9056 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9057 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9058 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9059 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309060#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009061
Abhishek Singh10d85972015-04-17 10:27:23 +05309062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9063 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9064#endif
9065
Amar Singhalfddc28c2013-09-05 13:03:40 -07009066#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009067 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9068 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009069 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009070 driver need to determine what to do with both
9071 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009072
9073 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009074#else
9075 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009076#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009077
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309078 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9079
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309080 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009081
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309082 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9083
Jeff Johnson295189b2012-06-20 16:38:30 -07009084 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309085 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9086 | BIT(NL80211_IFTYPE_ADHOC)
9087 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9088 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309089 | BIT(NL80211_IFTYPE_AP)
9090 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009091
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309092 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009093 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9095 if( pCfg->enableMCC )
9096 {
9097 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309098 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009099
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309100 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309101 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009102
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309103 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309104 wiphy->iface_combinations = wlan_hdd_iface_combination;
9105 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009106#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309107 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 /* Before registering we need to update the ht capabilitied based
9110 * on ini values*/
9111 if( !pCfg->ShortGI20MhzEnable )
9112 {
9113 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9114 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 }
9116
9117 if( !pCfg->ShortGI40MhzEnable )
9118 {
9119 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9120 }
9121
9122 if( !pCfg->nChannelBondingMode5GHz )
9123 {
9124 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9125 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309126 /*
9127 * In case of static linked driver at the time of driver unload,
9128 * module exit doesn't happens. Module cleanup helps in cleaning
9129 * of static memory.
9130 * If driver load happens statically, at the time of driver unload,
9131 * wiphy flags don't get reset because of static memory.
9132 * It's better not to store channel in static memory.
9133 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309134 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9135 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309136 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309137 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309138 {
9139 hddLog(VOS_TRACE_LEVEL_ERROR,
9140 FL("Not enough memory to allocate channels"));
9141 return -ENOMEM;
9142 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309143 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309144 &hdd_channels_2_4_GHZ[0],
9145 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009146
Agrawal Ashish97dec502015-11-26 20:20:58 +05309147 if (true == hdd_is_5g_supported(pHddCtx))
9148 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309149 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9150 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309151 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309152 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309153 {
9154 hddLog(VOS_TRACE_LEVEL_ERROR,
9155 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309156 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9157 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309158 return -ENOMEM;
9159 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309160 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309161 &hdd_channels_5_GHZ[0],
9162 sizeof(hdd_channels_5_GHZ));
9163 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309164
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309165 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309166 {
9167
9168 if (NULL == wiphy->bands[i])
9169 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309170 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309171 __func__, i);
9172 continue;
9173 }
9174
9175 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9176 {
9177 struct ieee80211_supported_band *band = wiphy->bands[i];
9178
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309179 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309180 {
9181 // Enable social channels for P2P
9182 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9183 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9184 else
9185 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9186 continue;
9187 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309188 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309189 {
9190 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9191 continue;
9192 }
9193 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 }
9195 /*Initialise the supported cipher suite details*/
9196 wiphy->cipher_suites = hdd_cipher_suites;
9197 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9198
9199 /*signal strength in mBm (100*dBm) */
9200 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9201
9202#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309203 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009205
Sunil Duttc69bccb2014-05-26 21:30:20 +05309206 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9207 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009208 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9209 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9210
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309211 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9212
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309213 EXIT();
9214 return 0;
9215}
9216
9217/* In this function we are registering wiphy. */
9218int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9219{
9220 ENTER();
9221 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 if (0 > wiphy_register(wiphy))
9223 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309224 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9226 return -EIO;
9227 }
9228
9229 EXIT();
9230 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309231}
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309233/* In this function we are updating channel list when,
9234 regulatory domain is FCC and country code is US.
9235 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9236 As per FCC smart phone is not a indoor device.
9237 GO should not opeate on indoor channels */
9238void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9239{
9240 int j;
9241 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9242 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9243 //Default counrtycode from NV at the time of wiphy initialization.
9244 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9245 &defaultCountryCode[0]))
9246 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009247 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309248 }
9249 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9250 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309251 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309252 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309253 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309254 return;
9255 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309256 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309257 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309258 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309259 // Mark UNII -1 band channel as passive
9260 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9261 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9262 }
9263 }
9264}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309265/* This function registers for all frame which supplicant is interested in */
9266void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009267{
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9269 /* Register for all P2P action, public action etc frames */
9270 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009271 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309272 /* Register frame indication call back */
9273 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 /* Right now we are registering these frame when driver is getting
9275 initialized. Once we will move to 2.6.37 kernel, in which we have
9276 frame register ops, we will move this code as a part of that */
9277 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9280
9281 /* GAS Initial Response */
9282 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9283 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309284
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 /* GAS Comeback Request */
9286 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9287 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9288
9289 /* GAS Comeback Response */
9290 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9291 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9292
9293 /* P2P Public Action */
9294 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309295 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 P2P_PUBLIC_ACTION_FRAME_SIZE );
9297
9298 /* P2P Action */
9299 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9300 (v_U8_t*)P2P_ACTION_FRAME,
9301 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009302
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309303 /* WNM BSS Transition Request frame */
9304 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9305 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9306 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009307
9308 /* WNM-Notification */
9309 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9310 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9311 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009312}
9313
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309314void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009315{
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9317 /* Register for all P2P action, public action etc frames */
9318 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9319
Jeff Johnsone7245742012-09-05 17:12:55 -07009320 ENTER();
9321
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 /* Right now we are registering these frame when driver is getting
9323 initialized. Once we will move to 2.6.37 kernel, in which we have
9324 frame register ops, we will move this code as a part of that */
9325 /* GAS Initial Request */
9326
9327 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9328 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9329
9330 /* GAS Initial Response */
9331 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9332 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 /* GAS Comeback Request */
9335 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9336 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9337
9338 /* GAS Comeback Response */
9339 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9340 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9341
9342 /* P2P Public Action */
9343 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 P2P_PUBLIC_ACTION_FRAME_SIZE );
9346
9347 /* P2P Action */
9348 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9349 (v_U8_t*)P2P_ACTION_FRAME,
9350 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009351 /* WNM-Notification */
9352 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9353 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9354 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009355}
9356
9357#ifdef FEATURE_WLAN_WAPI
9358void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309359 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009360{
9361 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9362 tCsrRoamSetKey setKey;
9363 v_BOOL_t isConnected = TRUE;
9364 int status = 0;
9365 v_U32_t roamId= 0xFF;
9366 tANI_U8 *pKeyPtr = NULL;
9367 int n = 0;
9368
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9370 __func__, hdd_device_modetoString(pAdapter->device_mode),
9371 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309373 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 setKey.keyId = key_index; // Store Key ID
9375 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9376 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9377 setKey.paeRole = 0 ; // the PAE role
9378 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9379 {
9380 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9381 }
9382 else
9383 {
9384 isConnected = hdd_connIsConnected(pHddStaCtx);
9385 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9386 }
9387 setKey.keyLength = key_Len;
9388 pKeyPtr = setKey.Key;
9389 memcpy( pKeyPtr, key, key_Len);
9390
Arif Hussain6d2a3322013-11-17 19:50:10 -08009391 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 __func__, key_Len);
9393 for (n = 0 ; n < key_Len; n++)
9394 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9395 __func__,n,setKey.Key[n]);
9396
9397 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9398 if ( isConnected )
9399 {
9400 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9401 pAdapter->sessionId, &setKey, &roamId );
9402 }
9403 if ( status != 0 )
9404 {
9405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9406 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9407 __LINE__, status );
9408 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9409 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309410 /* Need to clear any trace of key value in the memory.
9411 * Thus zero out the memory even though it is local
9412 * variable.
9413 */
9414 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009415}
9416#endif /* FEATURE_WLAN_WAPI*/
9417
9418#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 beacon_data_t **ppBeacon,
9421 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009422#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009424 beacon_data_t **ppBeacon,
9425 struct cfg80211_beacon_data *params,
9426 int dtim_period)
9427#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428{
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 int size;
9430 beacon_data_t *beacon = NULL;
9431 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309432 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9433 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009434
Jeff Johnsone7245742012-09-05 17:12:55 -07009435 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309437 {
9438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9439 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009442
9443 old = pAdapter->sessionCtx.ap.beacon;
9444
9445 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309446 {
9447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9448 FL("session(%d) old and new heads points to NULL"),
9449 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309451 }
9452
9453 if (params->tail && !params->tail_len)
9454 {
9455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9456 FL("tail_len is zero but tail is not NULL"));
9457 return -EINVAL;
9458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009459
Jeff Johnson295189b2012-06-20 16:38:30 -07009460#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9461 /* Kernel 3.0 is not updating dtim_period for set beacon */
9462 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309463 {
9464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9465 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009468#endif
9469
Kapil Gupta137ef892016-12-13 19:38:00 +05309470 if (params->head)
9471 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309473 head = params->head;
9474 } else
9475 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309477 head = old->head;
9478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009479
Kapil Gupta137ef892016-12-13 19:38:00 +05309480 if (params->tail || !old)
9481 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309483 tail = params->tail;
9484 } else
9485 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309487 tail = old->tail;
9488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009489
Kapil Gupta137ef892016-12-13 19:38:00 +05309490 if (params->proberesp_ies || !old)
9491 {
9492 proberesp_ies_len = params->proberesp_ies_len;
9493 proberesp_ies = params->proberesp_ies;
9494 } else
9495 {
9496 proberesp_ies_len = old->proberesp_ies_len;
9497 proberesp_ies = old->proberesp_ies;
9498 }
9499
9500 if (params->assocresp_ies || !old)
9501 {
9502 assocresp_ies_len = params->assocresp_ies_len;
9503 assocresp_ies = params->assocresp_ies;
9504 } else
9505 {
9506 assocresp_ies_len = old->assocresp_ies_len;
9507 assocresp_ies = old->assocresp_ies;
9508 }
9509
9510 size = sizeof(beacon_data_t) + head_len + tail_len +
9511 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009512
9513 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309515 {
9516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9517 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009520
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009521#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309522 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 beacon->dtim_period = params->dtim_period;
9524 else
9525 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009526#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309527 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009528 beacon->dtim_period = dtim_period;
9529 else
9530 beacon->dtim_period = old->dtim_period;
9531#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309532
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9534 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309535 beacon->proberesp_ies = beacon->tail + tail_len;
9536 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9537
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 beacon->head_len = head_len;
9539 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309540 beacon->proberesp_ies_len = proberesp_ies_len;
9541 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
c_manjee527ecac2017-01-25 12:25:27 +05309543 if (head && head_len)
9544 memcpy(beacon->head, head, head_len);
9545 if (tail && tail_len)
9546 memcpy(beacon->tail, tail, tail_len);
9547 if (proberesp_ies && proberesp_ies_len)
9548 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9549 if (assocresp_ies && assocresp_ies_len)
9550 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009551
9552 *ppBeacon = beacon;
9553
9554 kfree(old);
9555
9556 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009557}
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309559v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9561 const v_U8_t *pIes,
9562#else
9563 v_U8_t *pIes,
9564#endif
9565 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009566{
9567 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309568 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309570
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 elem_id = ptr[0];
9574 elem_len = ptr[1];
9575 left -= 2;
9576 if(elem_len > left)
9577 {
9578 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009579 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 eid,elem_len,left);
9581 return NULL;
9582 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 {
9585 return ptr;
9586 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 left -= elem_len;
9589 ptr += (elem_len + 2);
9590 }
9591 return NULL;
9592}
9593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594/* Check if rate is 11g rate or not */
9595static int wlan_hdd_rate_is_11g(u8 rate)
9596{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009597 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 u8 i;
9599 for (i = 0; i < 8; i++)
9600 {
9601 if(rate == gRateArray[i])
9602 return TRUE;
9603 }
9604 return FALSE;
9605}
9606
9607/* Check for 11g rate and set proper 11g only mode */
9608static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9609 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9610{
9611 u8 i, num_rates = pIe[0];
9612
9613 pIe += 1;
9614 for ( i = 0; i < num_rates; i++)
9615 {
9616 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9617 {
9618 /* If rate set have 11g rate than change the mode to 11G */
9619 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9620 if (pIe[i] & BASIC_RATE_MASK)
9621 {
9622 /* If we have 11g rate as basic rate, it means mode
9623 is 11g only mode.
9624 */
9625 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9626 *pCheckRatesfor11g = FALSE;
9627 }
9628 }
9629 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9630 {
9631 *require_ht = TRUE;
9632 }
9633 }
9634 return;
9635}
9636
9637static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9638{
9639 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9640 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9641 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9642 u8 checkRatesfor11g = TRUE;
9643 u8 require_ht = FALSE;
9644 u8 *pIe=NULL;
9645
9646 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9647
9648 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9649 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9650 if (pIe != NULL)
9651 {
9652 pIe += 1;
9653 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9654 &pConfig->SapHw_mode);
9655 }
9656
9657 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9658 WLAN_EID_EXT_SUPP_RATES);
9659 if (pIe != NULL)
9660 {
9661
9662 pIe += 1;
9663 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9664 &pConfig->SapHw_mode);
9665 }
9666
9667 if( pConfig->channel > 14 )
9668 {
9669 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9670 }
9671
9672 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9673 WLAN_EID_HT_CAPABILITY);
9674
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309675 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 {
9677 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9678 if(require_ht)
9679 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9680 }
9681}
9682
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9684 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9685{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009686 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309687 v_U8_t *pIe = NULL;
9688 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9689
9690 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9691 pBeacon->tail, pBeacon->tail_len);
9692
9693 if (pIe)
9694 {
9695 ielen = pIe[1] + 2;
9696 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9697 {
9698 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9699 }
9700 else
9701 {
9702 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9703 return -EINVAL;
9704 }
9705 *total_ielen += ielen;
9706 }
9707 return 0;
9708}
9709
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009710static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9711 v_U8_t *genie, v_U8_t *total_ielen)
9712{
9713 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9714 int left = pBeacon->tail_len;
9715 v_U8_t *ptr = pBeacon->tail;
9716 v_U8_t elem_id, elem_len;
9717 v_U16_t ielen = 0;
9718
9719 if ( NULL == ptr || 0 == left )
9720 return;
9721
9722 while (left >= 2)
9723 {
9724 elem_id = ptr[0];
9725 elem_len = ptr[1];
9726 left -= 2;
9727 if (elem_len > left)
9728 {
9729 hddLog( VOS_TRACE_LEVEL_ERROR,
9730 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9731 elem_id, elem_len, left);
9732 return;
9733 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309734 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009735 {
9736 /* skipping the VSIE's which we don't want to include or
9737 * it will be included by existing code
9738 */
9739 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9740#ifdef WLAN_FEATURE_WFD
9741 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9742#endif
9743 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9744 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9745 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9746 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9747 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9748 {
9749 ielen = ptr[1] + 2;
9750 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9751 {
9752 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9753 *total_ielen += ielen;
9754 }
9755 else
9756 {
9757 hddLog( VOS_TRACE_LEVEL_ERROR,
9758 "IE Length is too big "
9759 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9760 elem_id, elem_len, *total_ielen);
9761 }
9762 }
9763 }
9764
9765 left -= elem_len;
9766 ptr += (elem_len + 2);
9767 }
9768 return;
9769}
9770
Kapil Gupta137ef892016-12-13 19:38:00 +05309771int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009772{
9773 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309774 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009776 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309777 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009778
9779 genie = vos_mem_malloc(MAX_GENIE_LEN);
9780
9781 if(genie == NULL) {
9782
9783 return -ENOMEM;
9784 }
9785
Kapil Gupta137ef892016-12-13 19:38:00 +05309786 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309787 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9788 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309790 hddLog(LOGE,
9791 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309792 ret = -EINVAL;
9793 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 }
9795
9796#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309797 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9798 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9799 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309800 hddLog(LOGE,
9801 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309802 ret = -EINVAL;
9803 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 }
9805#endif
9806
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309807 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9808 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309810 hddLog(LOGE,
9811 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309812 ret = -EINVAL;
9813 goto done;
9814 }
9815
9816 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9817 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009818 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9822 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9823 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9824 {
9825 hddLog(LOGE,
9826 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 ret = -EINVAL;
9828 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 }
9830
9831 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9832 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9833 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9834 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9835 ==eHAL_STATUS_FAILURE)
9836 {
9837 hddLog(LOGE,
9838 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009839 ret = -EINVAL;
9840 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 }
9842
9843 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309844 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309846 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 u8 probe_rsp_ie_len[3] = {0};
9848 u8 counter = 0;
9849 /* Check Probe Resp Length if it is greater then 255 then Store
9850 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9851 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9852 Store More then 255 bytes into One Variable.
9853 */
9854 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9855 {
9856 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9857 {
9858 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9859 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9860 }
9861 else
9862 {
9863 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9864 rem_probe_resp_ie_len = 0;
9865 }
9866 }
9867
9868 rem_probe_resp_ie_len = 0;
9869
9870 if (probe_rsp_ie_len[0] > 0)
9871 {
9872 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9873 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309874 (tANI_U8*)&pBeacon->
9875 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 probe_rsp_ie_len[0], NULL,
9877 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9878 {
9879 hddLog(LOGE,
9880 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009881 ret = -EINVAL;
9882 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 }
9884 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9885 }
9886
9887 if (probe_rsp_ie_len[1] > 0)
9888 {
9889 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9890 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309891 (tANI_U8*)&pBeacon->
9892 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 probe_rsp_ie_len[1], NULL,
9894 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9895 {
9896 hddLog(LOGE,
9897 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009898 ret = -EINVAL;
9899 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 }
9901 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9902 }
9903
9904 if (probe_rsp_ie_len[2] > 0)
9905 {
9906 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9907 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309908 (tANI_U8*)&pBeacon->
9909 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 probe_rsp_ie_len[2], NULL,
9911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9912 {
9913 hddLog(LOGE,
9914 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009915 ret = -EINVAL;
9916 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
9918 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9919 }
9920
9921 if (probe_rsp_ie_len[1] == 0 )
9922 {
9923 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9924 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9925 eANI_BOOLEAN_FALSE) )
9926 {
9927 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009928 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 }
9930 }
9931
9932 if (probe_rsp_ie_len[2] == 0 )
9933 {
9934 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9935 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9936 eANI_BOOLEAN_FALSE) )
9937 {
9938 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009939 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 }
9941 }
9942
9943 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9944 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9945 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9946 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9947 == eHAL_STATUS_FAILURE)
9948 {
9949 hddLog(LOGE,
9950 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009951 ret = -EINVAL;
9952 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 }
9954 }
9955 else
9956 {
9957 // Reset WNI_CFG_PROBE_RSP Flags
9958 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9959
9960 hddLog(VOS_TRACE_LEVEL_INFO,
9961 "%s: No Probe Response IE received in set beacon",
9962 __func__);
9963 }
9964
9965 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309966 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 {
9968 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309969 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9970 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9972 {
9973 hddLog(LOGE,
9974 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009975 ret = -EINVAL;
9976 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 }
9978
9979 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9980 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9981 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9982 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9983 == eHAL_STATUS_FAILURE)
9984 {
9985 hddLog(LOGE,
9986 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009987 ret = -EINVAL;
9988 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 }
9990 }
9991 else
9992 {
9993 hddLog(VOS_TRACE_LEVEL_INFO,
9994 "%s: No Assoc Response IE received in set beacon",
9995 __func__);
9996
9997 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9998 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9999 eANI_BOOLEAN_FALSE) )
10000 {
10001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010002 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 }
10004 }
10005
Jeff Johnsone7245742012-09-05 17:12:55 -070010006done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010008 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010009}
Jeff Johnson295189b2012-06-20 16:38:30 -070010010
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010011/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 * FUNCTION: wlan_hdd_validate_operation_channel
10013 * called by wlan_hdd_cfg80211_start_bss() and
10014 * wlan_hdd_cfg80211_set_channel()
10015 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 * channel list.
10017 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010018VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 v_U32_t num_ch = 0;
10022 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10023 u32 indx = 0;
10024 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010025 v_U8_t fValidChannel = FALSE, count = 0;
10026 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10029
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010030 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010032 /* Validate the channel */
10033 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010035 if ( channel == rfChannels[count].channelNum )
10036 {
10037 fValidChannel = TRUE;
10038 break;
10039 }
10040 }
10041 if (fValidChannel != TRUE)
10042 {
10043 hddLog(VOS_TRACE_LEVEL_ERROR,
10044 "%s: Invalid Channel [%d]", __func__, channel);
10045 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 }
10047 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010048 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010050 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10051 valid_ch, &num_ch))
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,
10054 "%s: failed to get valid channel list", __func__);
10055 return VOS_STATUS_E_FAILURE;
10056 }
10057 for (indx = 0; indx < num_ch; indx++)
10058 {
10059 if (channel == valid_ch[indx])
10060 {
10061 break;
10062 }
10063 }
10064
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010065 if (indx >= num_ch)
10066 {
10067 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10068 {
10069 eCsrBand band;
10070 unsigned int freq;
10071
10072 sme_GetFreqBand(hHal, &band);
10073
10074 if (eCSR_BAND_5G == band)
10075 {
10076#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10077 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10078 {
10079 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010080 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010081 }
10082 else
10083 {
10084 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010085 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010086 }
10087#else
10088 freq = ieee80211_channel_to_frequency(channel);
10089#endif
10090 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10091 return VOS_STATUS_SUCCESS;
10092 }
10093 }
10094
10095 hddLog(VOS_TRACE_LEVEL_ERROR,
10096 "%s: Invalid Channel [%d]", __func__, channel);
10097 return VOS_STATUS_E_FAILURE;
10098 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010100
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102
Jeff Johnson295189b2012-06-20 16:38:30 -070010103}
10104
Viral Modi3a32cc52013-02-08 11:14:52 -080010105/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010106 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010107 * This function is used to set the channel number
10108 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010109static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010110 struct ieee80211_channel *chan,
10111 enum nl80211_channel_type channel_type
10112 )
10113{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010114 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010115 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010116 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010117 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010118 hdd_context_t *pHddCtx;
10119 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010120
10121 ENTER();
10122
10123 if( NULL == dev )
10124 {
10125 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010127 return -ENODEV;
10128 }
10129 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10132 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10133 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010134 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010135 "%s: device_mode = %s (%d) freq = %d", __func__,
10136 hdd_device_modetoString(pAdapter->device_mode),
10137 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010138
10139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010141 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010143 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010144 }
10145
10146 /*
10147 * Do freq to chan conversion
10148 * TODO: for 11a
10149 */
10150
10151 channel = ieee80211_frequency_to_channel(freq);
10152
10153 /* Check freq range */
10154 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10155 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10156 {
10157 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010158 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010159 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10160 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10161 return -EINVAL;
10162 }
10163
10164 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10165
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010166 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10167 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010168 {
10169 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10170 {
10171 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010172 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010173 return -EINVAL;
10174 }
10175 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10176 "%s: set channel to [%d] for device mode =%d",
10177 __func__, channel,pAdapter->device_mode);
10178 }
10179 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010180 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010181 )
10182 {
10183 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10184 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10185 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10186
10187 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10188 {
10189 /* Link is up then return cant set channel*/
10190 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010191 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010192 return -EINVAL;
10193 }
10194
10195 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10196 pHddStaCtx->conn_info.operationChannel = channel;
10197 pRoamProfile->ChannelInfo.ChannelList =
10198 &pHddStaCtx->conn_info.operationChannel;
10199 }
10200 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010202 )
10203 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010204 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10205 {
10206 if(VOS_STATUS_SUCCESS !=
10207 wlan_hdd_validate_operation_channel(pAdapter,channel))
10208 {
10209 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010210 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010211 return -EINVAL;
10212 }
10213 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10214 }
10215 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010216 {
10217 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10218
10219 /* If auto channel selection is configured as enable/ 1 then ignore
10220 channel set by supplicant
10221 */
10222 if ( cfg_param->apAutoChannelSelection )
10223 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010224 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10225 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010226 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010227 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10228 __func__, hdd_device_modetoString(pAdapter->device_mode),
10229 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010230 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010231 else
10232 {
10233 if(VOS_STATUS_SUCCESS !=
10234 wlan_hdd_validate_operation_channel(pAdapter,channel))
10235 {
10236 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010237 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010238 return -EINVAL;
10239 }
10240 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10241 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010242 }
10243 }
10244 else
10245 {
10246 hddLog(VOS_TRACE_LEVEL_FATAL,
10247 "%s: Invalid device mode failed to set valid channel", __func__);
10248 return -EINVAL;
10249 }
10250 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010251 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010252}
10253
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010254static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10255 struct net_device *dev,
10256 struct ieee80211_channel *chan,
10257 enum nl80211_channel_type channel_type
10258 )
10259{
10260 int ret;
10261
10262 vos_ssr_protect(__func__);
10263 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10264 vos_ssr_unprotect(__func__);
10265
10266 return ret;
10267}
10268
Anurag Chouhan83026002016-12-13 22:46:21 +053010269#ifdef DHCP_SERVER_OFFLOAD
10270void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10271 VOS_STATUS status)
10272{
10273 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10274
10275 ENTER();
10276
10277 if (NULL == adapter)
10278 {
10279 hddLog(VOS_TRACE_LEVEL_ERROR,
10280 "%s: adapter is NULL",__func__);
10281 return;
10282 }
10283
10284 adapter->dhcp_status.dhcp_offload_status = status;
10285 vos_event_set(&adapter->dhcp_status.vos_event);
10286 return;
10287}
10288
10289/**
10290 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10291 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010292 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010293 *
10294 * Return: None
10295 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010296VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10297 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010298{
10299 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10300 sir_dhcp_srv_offload_info dhcp_srv_info;
10301 tANI_U8 num_entries = 0;
10302 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10303 tANI_U8 num;
10304 tANI_U32 temp;
10305 VOS_STATUS ret;
10306
10307 ENTER();
10308
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010309 if (!re_init) {
10310 ret = wlan_hdd_validate_context(hdd_ctx);
10311 if (0 != ret)
10312 return VOS_STATUS_E_INVAL;
10313 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010314
10315 /* Prepare the request to send to SME */
10316 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10317 if (NULL == dhcp_srv_info) {
10318 hddLog(VOS_TRACE_LEVEL_ERROR,
10319 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10320 return VOS_STATUS_E_NOMEM;
10321 }
10322
10323 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10324
10325 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10326 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10327 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10328 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10329 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10330 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10331
10332 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10333 srv_ip,
10334 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010335 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010336 if (num_entries != IPADDR_NUM_ENTRIES) {
10337 hddLog(VOS_TRACE_LEVEL_ERROR,
10338 "%s: incorrect IP address (%s) assigned for DHCP server!",
10339 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10340 vos_mem_free(dhcp_srv_info);
10341 return VOS_STATUS_E_FAILURE;
10342 }
10343
10344 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10345 hddLog(VOS_TRACE_LEVEL_ERROR,
10346 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10347 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10348 vos_mem_free(dhcp_srv_info);
10349 return VOS_STATUS_E_FAILURE;
10350 }
10351
10352 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10353 hddLog(VOS_TRACE_LEVEL_ERROR,
10354 "%s: invalid IP address (%s)! The last field must be less than 100!",
10355 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10356 vos_mem_free(dhcp_srv_info);
10357 return VOS_STATUS_E_FAILURE;
10358 }
10359
10360 for (num = 0; num < num_entries; num++) {
10361 temp = srv_ip[num];
10362 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10363 }
10364
10365 if (eHAL_STATUS_SUCCESS !=
10366 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10367 hddLog(VOS_TRACE_LEVEL_ERROR,
10368 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10369 vos_mem_free(dhcp_srv_info);
10370 return VOS_STATUS_E_FAILURE;
10371 }
10372
10373 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10374 "%s: enable DHCP Server offload successfully!", __func__);
10375
10376 vos_mem_free(dhcp_srv_info);
10377 return 0;
10378}
10379#endif /* DHCP_SERVER_OFFLOAD */
10380
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010381/*
10382 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10383 * @wiphy_chan: wiphy channel number
10384 * @rfChannel: channel hw value
10385 * @disable: Disable/enable the flags
10386 *
10387 * Modify wiphy flags and cds state if channel is indoor.
10388 *
10389 * Return: void
10390 */
10391void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10392 v_U32_t rfChannel, bool disable)
10393{
10394 v_U32_t channelLoop;
10395 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10396
10397 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10398
10399 if (rfChannels[channelLoop].channelNum == rfChannel) {
10400 channelEnum = (eRfChannels)channelLoop;
10401 break;
10402 }
10403 }
10404
10405 if (INVALID_RF_CHANNEL == channelEnum)
10406 return;
10407
10408 if (disable) {
10409 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10410 wiphy_chan->flags |=
10411 IEEE80211_CHAN_DISABLED;
10412 regChannels[channelEnum].enabled =
10413 NV_CHANNEL_DISABLE;
10414 }
10415 } else {
10416 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10417 wiphy_chan->flags &=
10418 ~IEEE80211_CHAN_DISABLED;
10419 /*
10420 * Indoor channels are marked as DFS
10421 * during regulatory processing
10422 */
10423
10424 regChannels[channelEnum].enabled =
10425 NV_CHANNEL_DFS;
10426 }
10427 }
10428
10429}
10430
10431void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10432 bool disable)
10433{
10434 int band_num;
10435 int chan_num;
10436 v_U32_t rfChannel;
10437 struct ieee80211_channel *wiphy_chan;
10438 struct wiphy *wiphy;
10439
10440 ENTER();
10441 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10442
10443 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010444 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010445
10446 if (wiphy->bands[band_num] == NULL)
10447 continue;
10448
10449 for (chan_num = 0;
10450 chan_num < wiphy->bands[band_num]->n_channels;
10451 chan_num++) {
10452
10453 wiphy_chan =
10454 &(wiphy->bands[band_num]->channels[chan_num]);
10455 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10456
10457 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10458 disable);
10459 }
10460 }
10461 EXIT();
10462}
10463
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010464/*
10465 * FUNCTION: wlan_hdd_disconnect
10466 * This function is used to issue a disconnect request to SME
10467 */
10468int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10469{
10470 int status, result = 0;
10471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10473 long ret;
10474 eConnectionState prev_conn_state;
10475 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10476
10477 ENTER();
10478
10479 status = wlan_hdd_validate_context(pHddCtx);
10480 if (0 != status)
10481 {
10482 return status;
10483 }
10484 /* Indicate sme of disconnect so that in progress connection or preauth
10485 * can be aborted
10486 */
10487 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10488 pAdapter->sessionId);
10489 pHddCtx->isAmpAllowed = VOS_TRUE;
10490
10491 /* Need to apply spin lock before decreasing active sessions
10492 * as there can be chance for double decrement if context switch
10493 * Calls hdd_DisConnectHandler.
10494 */
10495
10496 prev_conn_state = pHddStaCtx->conn_info.connState;
10497
10498 spin_lock_bh(&pAdapter->lock_for_active_session);
10499 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10500 {
10501 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10502 }
10503 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10504 spin_unlock_bh(&pAdapter->lock_for_active_session);
10505 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10506
10507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10508 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10509
10510 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10511
10512 /*
10513 * stop tx queues before deleting STA/BSS context from the firmware.
10514 * tx has to be disabled because the firmware can get busy dropping
10515 * the tx frames after BSS/STA has been deleted and will not send
10516 * back a response resulting in WDI timeout
10517 */
10518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10519 netif_tx_disable(pAdapter->dev);
10520 netif_carrier_off(pAdapter->dev);
10521
10522 wlan_hdd_check_and_stop_mon(pAdapter, true);
10523
10524 /*issue disconnect*/
10525 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10526 pAdapter->sessionId, reason);
10527 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10528 prev_conn_state != eConnectionState_Connecting)
10529 {
10530 hddLog(LOG1,
10531 FL("status = %d, already disconnected"), status);
10532 result = 0;
10533 /*
10534 * Wait here instead of returning directly. This will block the
10535 * next connect command and allow processing of the disconnect
10536 * in SME else we might hit some race conditions leading to SME
10537 * and HDD out of sync. As disconnect is already in progress,
10538 * wait here for 1 sec instead of 5 sec.
10539 */
10540 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10541 goto wait_for_disconnect;
10542 }
10543 /*
10544 * Wait here instead of returning directly, this will block the next
10545 * connect command and allow processing of the scan for ssid and
10546 * the previous connect command in CSR. Else we might hit some
10547 * race conditions leading to SME and HDD out of sync.
10548 */
10549 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10550 {
10551 hddLog(LOG1,
10552 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10553 }
10554 else if ( 0 != status )
10555 {
10556 hddLog(LOGE,
10557 FL("csrRoamDisconnect failure, returned %d"),
10558 (int)status);
10559 result = -EINVAL;
10560 goto disconnected;
10561 }
10562wait_for_disconnect:
10563 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10564 msecs_to_jiffies(wait_time));
10565 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10566 {
10567 hddLog(LOGE,
10568 "%s: Failed to disconnect, timed out", __func__);
10569 result = -ETIMEDOUT;
10570 }
10571disconnected:
10572 hddLog(LOG1,
10573 FL("Set HDD connState to eConnectionState_NotConnected"));
10574 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10575#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10576 /* Sending disconnect event to userspace for kernel version < 3.11
10577 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10578 */
10579 hddLog(LOG1, FL("Send disconnected event to userspace"));
10580
10581 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10582 WLAN_REASON_UNSPECIFIED);
10583#endif
10584
10585 EXIT();
10586 return result;
10587}
10588
10589/*
10590 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10591 * on indoor channel
10592 * @hdd_ctx: pointer to hdd context
10593 *
10594 * STA should be disconnected before starting the SAP if it is on indoor
10595 * channel.
10596 *
10597 * Return: void
10598 */
10599void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10600{
10601
10602 hdd_adapter_t *sta_adapter;
10603 tANI_U8 sta_chan;
10604
10605 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10606
10607 if (!sta_chan) {
10608 hddLog(LOG1, FL("STA not connected"));
10609 return;
10610 }
10611
10612 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10613
10614 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10615 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10616 sta_chan);
10617 return;
10618 }
10619
10620 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10621
10622 if (!sta_adapter) {
10623 hddLog(LOG1, FL("STA adapter doesn't exist"));
10624 return;
10625 }
10626
10627 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10628 /* Issue Disconnect request */
10629 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10630}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010631
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010632int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10633{
10634 struct hdd_cache_channels *cache_chann;
10635 struct wiphy *wiphy;
10636 int freq, status, rfChannel;
10637 int i, band_num, channel_num;
10638 struct ieee80211_channel *wiphy_channel;
10639
10640 ENTER();
10641
10642 if (!hdd_ctx) {
10643 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10644 return -EINVAL;
10645 }
10646
10647 wiphy = hdd_ctx->wiphy;
10648
10649 mutex_lock(&hdd_ctx->cache_channel_lock);
10650
10651 cache_chann = hdd_ctx->orginal_channels;
10652
10653 if (!cache_chann || !cache_chann->num_channels) {
10654 hddLog(VOS_TRACE_LEVEL_INFO,
10655 "%s channel list is NULL or num channels are zero",
10656 __func__);
10657 mutex_unlock(&hdd_ctx->cache_channel_lock);
10658 return -EINVAL;
10659 }
10660
10661 for (i = 0; i < cache_chann->num_channels; i++) {
10662 status = hdd_wlan_get_freq(
10663 cache_chann->channel_info[i].channel_num,
10664 &freq);
10665
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010666 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
10667 band_num++) {
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010668 for (channel_num = 0; channel_num <
10669 wiphy->bands[band_num]->n_channels;
10670 channel_num++) {
10671 wiphy_channel = &(wiphy->bands[band_num]->
10672 channels[channel_num]);
10673 if (wiphy_channel->center_freq == freq) {
10674 rfChannel = wiphy_channel->hw_value;
10675 /*
10676 *Restore the orginal states
10677 *of the channels
10678 */
10679 vos_nv_set_channel_state(
10680 rfChannel,
10681 cache_chann->
10682 channel_info[i].reg_status);
10683 wiphy_channel->flags =
10684 cache_chann->
10685 channel_info[i].wiphy_status;
10686 break;
10687 }
10688 }
10689 if (channel_num < wiphy->bands[band_num]->n_channels)
10690 break;
10691 }
10692 }
10693
10694 mutex_unlock(&hdd_ctx->cache_channel_lock);
10695
10696 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10697 if (status)
10698 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10699 EXIT();
10700
10701 return 0;
10702}
10703
10704/*
10705 * wlan_hdd_disable_channels() - Cache the the channels
10706 * and current state of the channels from the channel list
10707 * received in the command and disable the channels on the
10708 * wiphy and NV table.
10709 * @hdd_ctx: Pointer to hdd context
10710 *
10711 * @return: 0 on success, Error code on failure
10712 */
10713
10714static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10715{
10716 struct hdd_cache_channels *cache_chann;
10717 struct wiphy *wiphy;
10718 int freq, status, rfChannel;
10719 int i, band_num, band_ch_num;
10720 struct ieee80211_channel *wiphy_channel;
10721
10722 if (!hdd_ctx) {
10723 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10724 return -EINVAL;
10725 }
10726
10727 wiphy = hdd_ctx->wiphy;
10728
10729 mutex_lock(&hdd_ctx->cache_channel_lock);
10730 cache_chann = hdd_ctx->orginal_channels;
10731
10732 if (!cache_chann || !cache_chann->num_channels) {
10733 hddLog(VOS_TRACE_LEVEL_INFO,
10734 "%s channel list is NULL or num channels are zero",
10735 __func__);
10736 mutex_unlock(&hdd_ctx->cache_channel_lock);
10737 return -EINVAL;
10738 }
10739
10740 for (i = 0; i < cache_chann->num_channels; i++) {
10741 status = hdd_wlan_get_freq(
10742 cache_chann->channel_info[i].channel_num,
10743 &freq);
10744
Rajeev Kumar Sirasanagandla17b649a2018-03-19 16:58:30 +053010745 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS;
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010746 band_num++) {
10747 for (band_ch_num = 0; band_ch_num <
10748 wiphy->bands[band_num]->n_channels;
10749 band_ch_num++) {
10750 wiphy_channel = &(wiphy->bands[band_num]->
10751 channels[band_ch_num]);
10752 if (wiphy_channel->center_freq == freq) {
10753 rfChannel = wiphy_channel->hw_value;
10754 /*
10755 * Cache the current states of
10756 * the channels
10757 */
10758 cache_chann->
10759 channel_info[i].reg_status =
10760 vos_nv_getChannelEnabledState(
10761 rfChannel);
10762
10763 cache_chann->
10764 channel_info[i].wiphy_status =
10765 wiphy_channel->flags;
10766 hddLog(VOS_TRACE_LEVEL_INFO,
10767 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10768 cache_chann->
10769 channel_info[i].channel_num,
10770 cache_chann->
10771 channel_info[i].reg_status,
10772 wiphy_channel->flags);
10773
10774 vos_nv_set_channel_state(
10775 rfChannel,
10776 NV_CHANNEL_DISABLE);
10777 wiphy_channel->flags |=
10778 IEEE80211_CHAN_DISABLED;
10779 break;
10780 }
10781 }
10782 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10783 break;
10784 }
10785 }
10786
10787 mutex_unlock(&hdd_ctx->cache_channel_lock);
10788 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10789 return 0;
10790}
10791
Jeff Johnson295189b2012-06-20 16:38:30 -070010792#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10793static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10794 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010795#else
10796static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10797 struct cfg80211_beacon_data *params,
10798 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010799 enum nl80211_hidden_ssid hidden_ssid,
10800 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010801#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010802{
10803 tsap_Config_t *pConfig;
10804 beacon_data_t *pBeacon = NULL;
10805 struct ieee80211_mgmt *pMgmt_frame;
10806 v_U8_t *pIe=NULL;
10807 v_U16_t capab_info;
10808 eCsrAuthType RSNAuthType;
10809 eCsrEncryptionType RSNEncryptType;
10810 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010811 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 tpWLAN_SAPEventCB pSapEventCallback;
10813 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010814 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010815 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010816 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010817 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010818 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010819 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010820 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010821 v_BOOL_t MFPCapable = VOS_FALSE;
10822 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010823 v_BOOL_t sapEnable11AC =
10824 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010825 u_int16_t prev_rsn_length = 0;
10826
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 ENTER();
10828
Nitesh Shah9b066282017-06-06 18:05:52 +053010829 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010830 iniConfig = pHddCtx->cfg_ini;
10831
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010832 /* Mark the indoor channel (passive) to disable */
10833 if (iniConfig->disable_indoor_channel) {
10834 hdd_update_indoor_channel(pHddCtx, true);
10835
10836 if (!VOS_IS_STATUS_SUCCESS(
10837 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10838 hdd_update_indoor_channel(pHddCtx, false);
10839 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10840 FL("Can't start BSS: update channel list failed"));
10841 return eHAL_STATUS_FAILURE;
10842 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010843
10844 /* check if STA is on indoor channel */
10845 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10846 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010847 }
10848
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010849 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
10850 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
10851 wlan_hdd_disable_channels(pHddCtx);
10852 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
10853 }
10854
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10856
10857 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10858
10859 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10860
10861 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10862
10863 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10864
10865 //channel is already set in the set_channel Call back
10866 //pConfig->channel = pCommitConfig->channel;
10867
10868 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010869 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10871
10872 pConfig->dtim_period = pBeacon->dtim_period;
10873
Arif Hussain6d2a3322013-11-17 19:50:10 -080010874 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010875 pConfig->dtim_period);
10876
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010877 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010878 {
10879 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010881 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10882 {
10883 tANI_BOOLEAN restartNeeded;
10884 pConfig->ieee80211d = 1;
10885 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10886 sme_setRegInfo(hHal, pConfig->countryCode);
10887 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10888 }
10889 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010890 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010891 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010892 pConfig->ieee80211d = 1;
10893 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10894 sme_setRegInfo(hHal, pConfig->countryCode);
10895 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010896 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010897 else
10898 {
10899 pConfig->ieee80211d = 0;
10900 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010901 /*
10902 * If auto channel is configured i.e. channel is 0,
10903 * so skip channel validation.
10904 */
10905 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10906 {
10907 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10908 {
10909 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010910 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010911 ret = -EINVAL;
10912 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010913 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010914 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010915 }
10916 else
10917 {
10918 if(1 != pHddCtx->is_dynamic_channel_range_set)
10919 {
10920 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10921 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10922 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10923 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010924 pHddCtx->is_dynamic_channel_range_set = 0;
10925 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010926 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010927 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010928 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010929 {
10930 pConfig->ieee80211d = 0;
10931 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010932
10933#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10934 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10935 pConfig->authType = eSAP_OPEN_SYSTEM;
10936 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10937 pConfig->authType = eSAP_SHARED_KEY;
10938 else
10939 pConfig->authType = eSAP_AUTO_SWITCH;
10940#else
10941 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10942 pConfig->authType = eSAP_OPEN_SYSTEM;
10943 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10944 pConfig->authType = eSAP_SHARED_KEY;
10945 else
10946 pConfig->authType = eSAP_AUTO_SWITCH;
10947#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010948
10949 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010950
10951 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010952 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010953#ifdef SAP_AUTH_OFFLOAD
10954 /* In case of sap offload, hostapd.conf is configuted with open mode and
10955 * security is configured from ini file. Due to open mode in hostapd.conf
10956 * privacy bit is set to false which will result in not sending,
10957 * data packets as encrypted.
10958 * If enable_sap_auth_offload is enabled in ini and
10959 * sap_auth_offload_sec_type is type of WPA2-PSK,
10960 * driver will set privacy bit to 1.
10961 */
10962 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10963 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10964 pConfig->privacy = VOS_TRUE;
10965#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010966
10967 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10968
10969 /*Set wps station to configured*/
10970 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10971
10972 if(pIe)
10973 {
10974 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10975 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010976 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010977 ret = -EINVAL;
10978 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010979 }
10980 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10981 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010982 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010983 /* Check 15 bit of WPS IE as it contain information for wps state
10984 * WPS state
10985 */
10986 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10987 {
10988 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10989 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10990 {
10991 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10992 }
10993 }
10994 }
10995 else
10996 {
10997 pConfig->wps_state = SAP_WPS_DISABLED;
10998 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010999 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070011000
c_hpothufe599e92014-06-16 11:38:55 +053011001 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11002 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11003 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11004 eCSR_ENCRYPT_TYPE_NONE;
11005
Jeff Johnson295189b2012-06-20 16:38:30 -070011006 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011007 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011008 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011009 WLAN_EID_RSN);
11010 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011011 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011012 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011013 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11014 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11015 pConfig->RSNWPAReqIELength);
11016 else
11017 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11018 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011019 /* The actual processing may eventually be more extensive than
11020 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 * by the app.
11022 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011023 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011024 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11025 &RSNEncryptType,
11026 &mcRSNEncryptType,
11027 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011028 &MFPCapable,
11029 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011030 pConfig->RSNWPAReqIE[1]+2,
11031 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011032
11033 if( VOS_STATUS_SUCCESS == status )
11034 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011035 /* Now copy over all the security attributes you have
11036 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011037 * */
11038 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11039 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11040 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11041 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011042 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011043 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011044 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11045 }
11046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011047
Jeff Johnson295189b2012-06-20 16:38:30 -070011048 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11049 pBeacon->tail, pBeacon->tail_len);
11050
11051 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11052 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011053 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011054 {
11055 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011056 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011057 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011058 if (pConfig->RSNWPAReqIELength <=
11059 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11060 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11061 pIe[1] + 2);
11062 else
11063 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11064 pConfig->RSNWPAReqIELength);
11065
Jeff Johnson295189b2012-06-20 16:38:30 -070011066 }
11067 else
11068 {
11069 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011070 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11071 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11072 pConfig->RSNWPAReqIELength);
11073 else
11074 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11075 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011076 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011077 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11078 &RSNEncryptType,
11079 &mcRSNEncryptType,
11080 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011081 &MFPCapable,
11082 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011083 pConfig->RSNWPAReqIE[1]+2,
11084 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011085
11086 if( VOS_STATUS_SUCCESS == status )
11087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011088 /* Now copy over all the security attributes you have
11089 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011090 * */
11091 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11092 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11093 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11094 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011095 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011096 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011097 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11098 }
11099 }
11100 }
11101
Kapil Gupta137ef892016-12-13 19:38:00 +053011102 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011103 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011104 ret = -EINVAL;
11105 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011106 }
11107
Jeff Johnson295189b2012-06-20 16:38:30 -070011108 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11109
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011110#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011111 if (params->ssid != NULL)
11112 {
11113 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11114 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11115 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11116 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11117 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011118#else
11119 if (ssid != NULL)
11120 {
11121 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11122 pConfig->SSIDinfo.ssid.length = ssid_len;
11123 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11124 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11125 }
11126#endif
11127
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011128 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011130
Jeff Johnson295189b2012-06-20 16:38:30 -070011131 /* default value */
11132 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11133 pConfig->num_accept_mac = 0;
11134 pConfig->num_deny_mac = 0;
11135
11136 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11137 pBeacon->tail, pBeacon->tail_len);
11138
11139 /* pIe for black list is following form:
11140 type : 1 byte
11141 length : 1 byte
11142 OUI : 4 bytes
11143 acl type : 1 byte
11144 no of mac addr in black list: 1 byte
11145 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011146 */
11147 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011148 {
11149 pConfig->SapMacaddr_acl = pIe[6];
11150 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011151 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011153 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11154 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11156 for (i = 0; i < pConfig->num_deny_mac; i++)
11157 {
11158 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11159 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011160 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011161 }
11162 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11163 pBeacon->tail, pBeacon->tail_len);
11164
11165 /* pIe for white list is following form:
11166 type : 1 byte
11167 length : 1 byte
11168 OUI : 4 bytes
11169 acl type : 1 byte
11170 no of mac addr in white list: 1 byte
11171 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011172 */
11173 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011174 {
11175 pConfig->SapMacaddr_acl = pIe[6];
11176 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011177 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011178 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011179 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11180 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011181 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11182 for (i = 0; i < pConfig->num_accept_mac; i++)
11183 {
11184 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11185 acl_entry++;
11186 }
11187 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011188
Jeff Johnson295189b2012-06-20 16:38:30 -070011189 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11190
Jeff Johnsone7245742012-09-05 17:12:55 -070011191#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011192 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011193 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11194 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011195 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11196 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011197 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11198 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011199 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11200 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011201 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011202 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011203 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011204 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011205
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011206 /* If ACS disable and selected channel <= 14
11207 * OR
11208 * ACS enabled and ACS operating band is choosen as 2.4
11209 * AND
11210 * VHT in 2.4G Disabled
11211 * THEN
11212 * Fallback to 11N mode
11213 */
11214 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11215 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011216 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011217 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011218 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011219 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11220 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011221 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11222 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011223 }
11224#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011225
Jeff Johnson295189b2012-06-20 16:38:30 -070011226 // ht_capab is not what the name conveys,this is used for protection bitmap
11227 pConfig->ht_capab =
11228 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11229
Kapil Gupta137ef892016-12-13 19:38:00 +053011230 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011231 {
11232 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011233 ret = -EINVAL;
11234 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011235 }
11236
11237 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011238 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011239 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11240 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011241 pConfig->obssProtEnabled =
11242 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011243
Chet Lanctot8cecea22014-02-11 19:09:36 -080011244#ifdef WLAN_FEATURE_11W
11245 pConfig->mfpCapable = MFPCapable;
11246 pConfig->mfpRequired = MFPRequired;
11247 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11248 pConfig->mfpCapable, pConfig->mfpRequired);
11249#endif
11250
Arif Hussain6d2a3322013-11-17 19:50:10 -080011251 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011252 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011253 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11254 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11255 (int)pConfig->channel);
11256 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11257 pConfig->SapHw_mode, pConfig->privacy,
11258 pConfig->authType);
11259 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11260 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11261 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11262 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011263
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011264 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011265 {
11266 //Bss already started. just return.
11267 //TODO Probably it should update some beacon params.
11268 hddLog( LOGE, "Bss Already started...Ignore the request");
11269 EXIT();
11270 return 0;
11271 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011272
Agarwal Ashish51325b52014-06-16 16:50:49 +053011273 if (vos_max_concurrent_connections_reached()) {
11274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011275 ret = -EINVAL;
11276 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011277 }
11278
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 pConfig->persona = pHostapdAdapter->device_mode;
11280
Peng Xu2446a892014-09-05 17:21:18 +053011281 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11282 if ( NULL != psmeConfig)
11283 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011284 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011285 sme_GetConfigParam(hHal, psmeConfig);
11286 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011287#ifdef WLAN_FEATURE_AP_HT40_24G
11288 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11289 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11290 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11291 {
11292 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11293 sme_UpdateConfig (hHal, psmeConfig);
11294 }
11295#endif
Peng Xu2446a892014-09-05 17:21:18 +053011296 vos_mem_free(psmeConfig);
11297 }
Peng Xuafc34e32014-09-25 13:23:55 +053011298 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011299
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011300 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11301
Jeff Johnson295189b2012-06-20 16:38:30 -070011302 pSapEventCallback = hdd_hostapd_SAPEventCB;
11303 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11304 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11305 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011306 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011307 ret = -EINVAL;
11308 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 }
11310
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011311 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011312 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11313
11314 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011315
Jeff Johnson295189b2012-06-20 16:38:30 -070011316 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011317 {
11318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011319 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011320 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 VOS_ASSERT(0);
11322 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011323
Jeff Johnson295189b2012-06-20 16:38:30 -070011324 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011325 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11326 VOS_STATUS_SUCCESS)
11327 {
11328 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11329 VOS_ASSERT(0);
11330 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011331 /* Initialize WMM configuation */
11332 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011333 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011334
Anurag Chouhan83026002016-12-13 22:46:21 +053011335#ifdef DHCP_SERVER_OFFLOAD
11336 /* set dhcp server offload */
11337 if (iniConfig->enable_dhcp_srv_offload &&
11338 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011339 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011340 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011341 if (!VOS_IS_STATUS_SUCCESS(status))
11342 {
11343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11344 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011345 vos_event_reset(&pHostapdState->vosEvent);
11346 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11347 status = vos_wait_single_event(&pHostapdState->vosEvent,
11348 10000);
11349 if (!VOS_IS_STATUS_SUCCESS(status)) {
11350 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011351 ret = -EINVAL;
11352 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011353 }
11354 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011355 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011356 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11357 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11358 {
11359 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11360 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11361 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011362 vos_event_reset(&pHostapdState->vosEvent);
11363 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11364 status = vos_wait_single_event(&pHostapdState->vosEvent,
11365 10000);
11366 if (!VOS_IS_STATUS_SUCCESS(status)) {
11367 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011368 ret = -EINVAL;
11369 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011370 }
11371 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011372 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011373#ifdef MDNS_OFFLOAD
11374 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011375 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011376 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11377 if (VOS_IS_STATUS_SUCCESS(status))
11378 {
11379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11380 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011381 vos_event_reset(&pHostapdState->vosEvent);
11382 if (VOS_STATUS_SUCCESS ==
11383 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11384 status = vos_wait_single_event(&pHostapdState->vosEvent,
11385 10000);
11386 if (!VOS_IS_STATUS_SUCCESS(status)) {
11387 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011388 ret = -EINVAL;
11389 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011390 }
11391 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011392 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011393 status = vos_wait_single_event(&pHostapdAdapter->
11394 mdns_status.vos_event, 2000);
11395 if (!VOS_IS_STATUS_SUCCESS(status) ||
11396 pHostapdAdapter->mdns_status.mdns_enable_status ||
11397 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11398 pHostapdAdapter->mdns_status.mdns_resp_status)
11399 {
11400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11401 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11402 pHostapdAdapter->mdns_status.mdns_enable_status,
11403 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11404 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011405 vos_event_reset(&pHostapdState->vosEvent);
11406 if (VOS_STATUS_SUCCESS ==
11407 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11408 status = vos_wait_single_event(&pHostapdState->vosEvent,
11409 10000);
11410 if (!VOS_IS_STATUS_SUCCESS(status)) {
11411 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011412 ret = -EINVAL;
11413 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011414 }
11415 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011416 }
11417 }
11418#endif /* MDNS_OFFLOAD */
11419 } else {
11420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11421 ("DHCP Disabled ini %d, FW %d"),
11422 iniConfig->enable_dhcp_srv_offload,
11423 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011424 }
11425#endif /* DHCP_SERVER_OFFLOAD */
11426
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011427#ifdef WLAN_FEATURE_P2P_DEBUG
11428 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11429 {
11430 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11431 {
11432 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11433 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011434 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011435 }
11436 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11437 {
11438 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11439 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011440 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011441 }
11442 }
11443#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011444 /* Check and restart SAP if it is on Unsafe channel */
11445 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011446
Jeff Johnson295189b2012-06-20 16:38:30 -070011447 pHostapdState->bCommit = TRUE;
11448 EXIT();
11449
11450 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011451error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011452 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11453 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011454 /* Revert the indoor to passive marking if START BSS fails */
11455 if (iniConfig->disable_indoor_channel) {
11456 hdd_update_indoor_channel(pHddCtx, false);
11457 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11458 }
11459
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011460 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11461 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011462}
11463
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011464#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011465static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011466 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 struct beacon_parameters *params)
11468{
11469 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011470 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011471 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011472
11473 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011474
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011475 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11476 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11477 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011478 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11479 hdd_device_modetoString(pAdapter->device_mode),
11480 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011481
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011482 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11483 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011484 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011485 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011486 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011487 }
11488
Agarwal Ashish51325b52014-06-16 16:50:49 +053011489 if (vos_max_concurrent_connections_reached()) {
11490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11491 return -EINVAL;
11492 }
11493
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011494 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 )
11497 {
11498 beacon_data_t *old,*new;
11499
11500 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011503 {
11504 hddLog(VOS_TRACE_LEVEL_WARN,
11505 FL("already beacon info added to session(%d)"),
11506 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011509
11510 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11511
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011512 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 {
11514 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011515 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 return -EINVAL;
11517 }
11518
11519 pAdapter->sessionCtx.ap.beacon = new;
11520
11521 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11522 }
11523
11524 EXIT();
11525 return status;
11526}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011527
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011528static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11529 struct net_device *dev,
11530 struct beacon_parameters *params)
11531{
11532 int ret;
11533
11534 vos_ssr_protect(__func__);
11535 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11536 vos_ssr_unprotect(__func__);
11537
11538 return ret;
11539}
11540
11541static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011542 struct net_device *dev,
11543 struct beacon_parameters *params)
11544{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011545 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011546 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11547 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011548 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011549
11550 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011551
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011552 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11553 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11554 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11555 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11556 __func__, hdd_device_modetoString(pAdapter->device_mode),
11557 pAdapter->device_mode);
11558
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011559 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11560 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011561 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011562 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011563 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011564 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011565
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011566 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011567 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011568 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011569 {
11570 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011571
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011573
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011575 {
11576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11577 FL("session(%d) old and new heads points to NULL"),
11578 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011580 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011581
11582 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11583
11584 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011585 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011586 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011587 return -EINVAL;
11588 }
11589
11590 pAdapter->sessionCtx.ap.beacon = new;
11591
11592 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11593 }
11594
11595 EXIT();
11596 return status;
11597}
11598
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011599static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11600 struct net_device *dev,
11601 struct beacon_parameters *params)
11602{
11603 int ret;
11604
11605 vos_ssr_protect(__func__);
11606 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11607 vos_ssr_unprotect(__func__);
11608
11609 return ret;
11610}
11611
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011612#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11613
11614#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011615static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011617#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011618static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011619 struct net_device *dev)
11620#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011621{
11622 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011623 hdd_context_t *pHddCtx = NULL;
11624 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011625 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011626 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011627
11628 ENTER();
11629
11630 if (NULL == pAdapter)
11631 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011633 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 return -ENODEV;
11635 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011636
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011637 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11638 TRACE_CODE_HDD_CFG80211_STOP_AP,
11639 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011640 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11641 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011643 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011644 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011645 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011646
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011647 pScanInfo = &pHddCtx->scan_info;
11648
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011649 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11650 __func__, hdd_device_modetoString(pAdapter->device_mode),
11651 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011652
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011653 ret = wlan_hdd_scan_abort(pAdapter);
11654
Girish Gowli4bf7a632014-06-12 13:42:11 +053011655 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011656 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11658 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011659
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011660 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011661 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11663 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011664
Jeff Johnsone7245742012-09-05 17:12:55 -070011665 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011666 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011667 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011668 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011669 }
11670
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011671 /* Delete all associated STAs before stopping AP/P2P GO */
11672 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011673 hdd_hostapd_stop(dev);
11674
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 )
11678 {
11679 beacon_data_t *old;
11680
11681 old = pAdapter->sessionCtx.ap.beacon;
11682
11683 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011684 {
11685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11686 FL("session(%d) beacon data points to NULL"),
11687 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011689 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011690
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011692
11693 mutex_lock(&pHddCtx->sap_lock);
11694 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11695 {
Abhishek Singh10e17cf2018-03-12 14:34:22 +053011696 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
11697 hdd_wait_for_ecsa_complete(pHddCtx);
Jeff Johnson4416a782013-03-25 14:17:50 -070011698 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 {
11700 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11701
11702 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11703
11704 if (!VOS_IS_STATUS_SUCCESS(status))
11705 {
11706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011707 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011709 }
11710 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011712 /* BSS stopped, clear the active sessions for this device mode */
11713 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 }
11715 mutex_unlock(&pHddCtx->sap_lock);
11716
11717 if(status != VOS_STATUS_SUCCESS)
11718 {
11719 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011720 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 return -EINVAL;
11722 }
11723
Jeff Johnson4416a782013-03-25 14:17:50 -070011724 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11726 ==eHAL_STATUS_FAILURE)
11727 {
11728 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011729 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 }
11731
Jeff Johnson4416a782013-03-25 14:17:50 -070011732 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11734 eANI_BOOLEAN_FALSE) )
11735 {
11736 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011737 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 }
11739
11740 // Reset WNI_CFG_PROBE_RSP Flags
11741 wlan_hdd_reset_prob_rspies(pAdapter);
11742
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011743 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11744
Jeff Johnson295189b2012-06-20 16:38:30 -070011745 pAdapter->sessionCtx.ap.beacon = NULL;
11746 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011747#ifdef WLAN_FEATURE_P2P_DEBUG
11748 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11749 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11750 {
11751 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11752 "GO got removed");
11753 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11754 }
11755#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011756 }
11757 EXIT();
11758 return status;
11759}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011760
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011761#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11762static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11763 struct net_device *dev)
11764{
11765 int ret;
11766
11767 vos_ssr_protect(__func__);
11768 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11769 vos_ssr_unprotect(__func__);
11770
11771 return ret;
11772}
11773#else
11774static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11775 struct net_device *dev)
11776{
11777 int ret;
11778
11779 vos_ssr_protect(__func__);
11780 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11781 vos_ssr_unprotect(__func__);
11782
11783 return ret;
11784}
11785#endif
11786
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011787#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11788
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011789static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011790 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011791 struct cfg80211_ap_settings *params)
11792{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011793 hdd_adapter_t *pAdapter;
11794 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011795 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011796
11797 ENTER();
11798
Girish Gowlib143d7a2015-02-18 19:39:55 +053011799 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011800 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011801 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011802 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011803 return -ENODEV;
11804 }
11805
11806 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11807 if (NULL == pAdapter)
11808 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011810 "%s: HDD adapter is Null", __func__);
11811 return -ENODEV;
11812 }
11813
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011814 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11815 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11816 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011817 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11818 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011819 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011820 "%s: HDD adapter magic is invalid", __func__);
11821 return -ENODEV;
11822 }
11823
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011824 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11825
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011826 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011827 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011828 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011829 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011830 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011831 }
11832
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011833 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11834 __func__, hdd_device_modetoString(pAdapter->device_mode),
11835 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011836
11837 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011838 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011839 )
11840 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011841 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011842
11843 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011844
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011845 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011846 {
11847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11848 FL("already beacon info added to session(%d)"),
11849 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011850 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011851 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011852
Girish Gowlib143d7a2015-02-18 19:39:55 +053011853#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11854 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11855 &new,
11856 &params->beacon);
11857#else
11858 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11859 &new,
11860 &params->beacon,
11861 params->dtim_period);
11862#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011863
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011864 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011865 {
11866 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011867 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011868 return -EINVAL;
11869 }
11870 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011871#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011872 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11873#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11874 params->channel, params->channel_type);
11875#else
11876 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11877#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011878#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011879 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011880 params->ssid_len, params->hidden_ssid,
11881 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011882 }
11883
11884 EXIT();
11885 return status;
11886}
11887
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011888static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11889 struct net_device *dev,
11890 struct cfg80211_ap_settings *params)
11891{
11892 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011893
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011894 vos_ssr_protect(__func__);
11895 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11896 vos_ssr_unprotect(__func__);
11897
11898 return ret;
11899}
11900
11901static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011902 struct net_device *dev,
11903 struct cfg80211_beacon_data *params)
11904{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011906 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011907 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011908
11909 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011910
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011911 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11912 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11913 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011914 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011915 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011916
11917 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11918 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011919 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011921 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011922 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011923
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011924 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011925 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011926 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011927 {
11928 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011929
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011930 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011932 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011933 {
11934 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11935 FL("session(%d) beacon data points to NULL"),
11936 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011937 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011938 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011939
11940 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11941
11942 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011943 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011944 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011945 return -EINVAL;
11946 }
11947
11948 pAdapter->sessionCtx.ap.beacon = new;
11949
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011950 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11951 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011952 }
11953
11954 EXIT();
11955 return status;
11956}
11957
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011958static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11959 struct net_device *dev,
11960 struct cfg80211_beacon_data *params)
11961{
11962 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011963
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011964 vos_ssr_protect(__func__);
11965 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11966 vos_ssr_unprotect(__func__);
11967
11968 return ret;
11969}
11970
11971#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011972
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011973static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011974 struct net_device *dev,
11975 struct bss_parameters *params)
11976{
11977 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011978 hdd_context_t *pHddCtx;
11979 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011980
11981 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011982
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011983 if (NULL == pAdapter)
11984 {
11985 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11986 "%s: HDD adapter is Null", __func__);
11987 return -ENODEV;
11988 }
11989 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011990 ret = wlan_hdd_validate_context(pHddCtx);
11991 if (0 != ret)
11992 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011993 return ret;
11994 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011995 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11996 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11997 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011998 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11999 __func__, hdd_device_modetoString(pAdapter->device_mode),
12000 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012001
12002 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012003 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 {
12006 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12007 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012008 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 {
12010 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012011 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 }
12013
12014 EXIT();
12015 return 0;
12016}
12017
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012018static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12019 struct net_device *dev,
12020 struct bss_parameters *params)
12021{
12022 int ret;
12023
12024 vos_ssr_protect(__func__);
12025 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12026 vos_ssr_unprotect(__func__);
12027
12028 return ret;
12029}
Kiet Lam10841362013-11-01 11:36:50 +053012030/* FUNCTION: wlan_hdd_change_country_code_cd
12031* to wait for contry code completion
12032*/
12033void* wlan_hdd_change_country_code_cb(void *pAdapter)
12034{
12035 hdd_adapter_t *call_back_pAdapter = pAdapter;
12036 complete(&call_back_pAdapter->change_country_code);
12037 return NULL;
12038}
12039
Jeff Johnson295189b2012-06-20 16:38:30 -070012040/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012041 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012042 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12043 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012044int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012045 struct net_device *ndev,
12046 enum nl80211_iftype type,
12047 u32 *flags,
12048 struct vif_params *params
12049 )
12050{
12051 struct wireless_dev *wdev;
12052 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012053 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012054 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012055 tCsrRoamProfile *pRoamProfile = NULL;
12056 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012057 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012058 eMib_dot11DesiredBssType connectedBssType;
12059 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012060 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012061
12062 ENTER();
12063
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012064 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012065 {
12066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12067 "%s: Adapter context is null", __func__);
12068 return VOS_STATUS_E_FAILURE;
12069 }
12070
12071 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12072 if (!pHddCtx)
12073 {
12074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12075 "%s: HDD context is null", __func__);
12076 return VOS_STATUS_E_FAILURE;
12077 }
12078
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012079 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12080 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12081 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012082 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012083 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012085 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 }
12087
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012088 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12089 __func__, hdd_device_modetoString(pAdapter->device_mode),
12090 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012091
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012092 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12093 hddLog(VOS_TRACE_LEVEL_FATAL,
12094 "%s: STA + MON is in progress, cannot change interface",
12095 __func__);
12096 }
12097
Agarwal Ashish51325b52014-06-16 16:50:49 +053012098 if (vos_max_concurrent_connections_reached()) {
12099 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12100 return -EINVAL;
12101 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012102 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012103 wdev = ndev->ieee80211_ptr;
12104
12105#ifdef WLAN_BTAMP_FEATURE
12106 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12107 (NL80211_IFTYPE_ADHOC == type)||
12108 (NL80211_IFTYPE_AP == type)||
12109 (NL80211_IFTYPE_P2P_GO == type))
12110 {
12111 pHddCtx->isAmpAllowed = VOS_FALSE;
12112 // stop AMP traffic
12113 status = WLANBAP_StopAmp();
12114 if(VOS_STATUS_SUCCESS != status )
12115 {
12116 pHddCtx->isAmpAllowed = VOS_TRUE;
12117 hddLog(VOS_TRACE_LEVEL_FATAL,
12118 "%s: Failed to stop AMP", __func__);
12119 return -EINVAL;
12120 }
12121 }
12122#endif //WLAN_BTAMP_FEATURE
12123 /* Reset the current device mode bit mask*/
12124 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12125
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012126 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12127 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12128 (type == NL80211_IFTYPE_P2P_GO)))
12129 {
12130 /* Notify Mode change in case of concurrency.
12131 * Below function invokes TDLS teardown Functionality Since TDLS is
12132 * not Supported in case of concurrency i.e Once P2P session
12133 * is detected disable offchannel and teardown TDLS links
12134 */
12135 hddLog(LOG1,
12136 FL("Device mode = %d Interface type = %d"),
12137 pAdapter->device_mode, type);
12138 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12139 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012140
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012142 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012143 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 )
12145 {
12146 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012147 if (!pWextState)
12148 {
12149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12150 "%s: pWextState is null", __func__);
12151 return VOS_STATUS_E_FAILURE;
12152 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012153 pRoamProfile = &pWextState->roamProfile;
12154 LastBSSType = pRoamProfile->BSSType;
12155
12156 switch (type)
12157 {
12158 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012159 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012160 hddLog(VOS_TRACE_LEVEL_INFO,
12161 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12162 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012163#ifdef WLAN_FEATURE_11AC
12164 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12165 {
12166 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12167 }
12168#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012169 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012170 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012171 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012172 //Check for sub-string p2p to confirm its a p2p interface
12173 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012175#ifdef FEATURE_WLAN_TDLS
12176 mutex_lock(&pHddCtx->tdls_lock);
12177 wlan_hdd_tdls_exit(pAdapter, TRUE);
12178 mutex_unlock(&pHddCtx->tdls_lock);
12179#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012180 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12181 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12182 }
12183 else
12184 {
12185 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012186 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012187 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012189
Jeff Johnson295189b2012-06-20 16:38:30 -070012190 case NL80211_IFTYPE_ADHOC:
12191 hddLog(VOS_TRACE_LEVEL_INFO,
12192 "%s: setting interface Type to ADHOC", __func__);
12193 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12194 pRoamProfile->phyMode =
12195 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012196 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012197 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012198 hdd_set_ibss_ops( pAdapter );
12199 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012200
12201 status = hdd_sta_id_hash_attach(pAdapter);
12202 if (VOS_STATUS_SUCCESS != status) {
12203 hddLog(VOS_TRACE_LEVEL_ERROR,
12204 FL("Failed to initialize hash for IBSS"));
12205 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012206 break;
12207
12208 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 {
12211 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12212 "%s: setting interface Type to %s", __func__,
12213 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12214
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012215 //Cancel any remain on channel for GO mode
12216 if (NL80211_IFTYPE_P2P_GO == type)
12217 {
12218 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12219 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012220 if (NL80211_IFTYPE_AP == type)
12221 {
12222 /* As Loading WLAN Driver one interface being created for p2p device
12223 * address. This will take one HW STA and the max number of clients
12224 * that can connect to softAP will be reduced by one. so while changing
12225 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12226 * interface as it is not required in SoftAP mode.
12227 */
12228
12229 // Get P2P Adapter
12230 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12231
12232 if (pP2pAdapter)
12233 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012234 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012235 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012236 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12237 }
12238 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012239 //Disable IMPS & BMPS for SAP/GO
12240 if(VOS_STATUS_E_FAILURE ==
12241 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12242 {
12243 //Fail to Exit BMPS
12244 VOS_ASSERT(0);
12245 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012246
12247 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12248
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012249#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012250
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012251 /* A Mutex Lock is introduced while changing the mode to
12252 * protect the concurrent access for the Adapters by TDLS
12253 * module.
12254 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012255 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012256#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012258 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12261 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012262#ifdef FEATURE_WLAN_TDLS
12263 mutex_unlock(&pHddCtx->tdls_lock);
12264#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012265 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12266 (pConfig->apRandomBssidEnabled))
12267 {
12268 /* To meet Android requirements create a randomized
12269 MAC address of the form 02:1A:11:Fx:xx:xx */
12270 get_random_bytes(&ndev->dev_addr[3], 3);
12271 ndev->dev_addr[0] = 0x02;
12272 ndev->dev_addr[1] = 0x1A;
12273 ndev->dev_addr[2] = 0x11;
12274 ndev->dev_addr[3] |= 0xF0;
12275 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12276 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012277 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12278 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012279 }
12280
Jeff Johnson295189b2012-06-20 16:38:30 -070012281 hdd_set_ap_ops( pAdapter->dev );
12282
Kiet Lam10841362013-11-01 11:36:50 +053012283 /* This is for only SAP mode where users can
12284 * control country through ini.
12285 * P2P GO follows station country code
12286 * acquired during the STA scanning. */
12287 if((NL80211_IFTYPE_AP == type) &&
12288 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12289 {
12290 int status = 0;
12291 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12292 "%s: setting country code from INI ", __func__);
12293 init_completion(&pAdapter->change_country_code);
12294 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12295 (void *)(tSmeChangeCountryCallback)
12296 wlan_hdd_change_country_code_cb,
12297 pConfig->apCntryCode, pAdapter,
12298 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012299 eSIR_FALSE,
12300 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012301 if (eHAL_STATUS_SUCCESS == status)
12302 {
12303 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012304 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012305 &pAdapter->change_country_code,
12306 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012307 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012308 {
12309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012310 FL("SME Timed out while setting country code %ld"),
12311 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012312
12313 if (pHddCtx->isLogpInProgress)
12314 {
12315 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12316 "%s: LOGP in Progress. Ignore!!!", __func__);
12317 return -EAGAIN;
12318 }
Kiet Lam10841362013-11-01 11:36:50 +053012319 }
12320 }
12321 else
12322 {
12323 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012324 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012325 return -EINVAL;
12326 }
12327 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012328 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 if(status != VOS_STATUS_SUCCESS)
12330 {
12331 hddLog(VOS_TRACE_LEVEL_FATAL,
12332 "%s: Error initializing the ap mode", __func__);
12333 return -EINVAL;
12334 }
12335 hdd_set_conparam(1);
12336
Nirav Shah7e3c8132015-06-22 23:51:42 +053012337 status = hdd_sta_id_hash_attach(pAdapter);
12338 if (VOS_STATUS_SUCCESS != status)
12339 {
12340 hddLog(VOS_TRACE_LEVEL_ERROR,
12341 FL("Failed to initialize hash for AP"));
12342 return -EINVAL;
12343 }
12344
Jeff Johnson295189b2012-06-20 16:38:30 -070012345 /*interface type changed update in wiphy structure*/
12346 if(wdev)
12347 {
12348 wdev->iftype = type;
12349 pHddCtx->change_iface = type;
12350 }
12351 else
12352 {
12353 hddLog(VOS_TRACE_LEVEL_ERROR,
12354 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12355 return -EINVAL;
12356 }
12357 goto done;
12358 }
12359
12360 default:
12361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12362 __func__);
12363 return -EOPNOTSUPP;
12364 }
12365 }
12366 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012368 )
12369 {
12370 switch(type)
12371 {
12372 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012373 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012374 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012375
12376 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012377#ifdef FEATURE_WLAN_TDLS
12378
12379 /* A Mutex Lock is introduced while changing the mode to
12380 * protect the concurrent access for the Adapters by TDLS
12381 * module.
12382 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012383 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012384#endif
c_hpothu002231a2015-02-05 14:58:51 +053012385 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012387 //Check for sub-string p2p to confirm its a p2p interface
12388 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012389 {
12390 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12391 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12392 }
12393 else
12394 {
12395 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012396 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012397 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012398
12399 /* set con_mode to STA only when no SAP concurrency mode */
12400 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12401 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012402 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012403 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12404 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012405#ifdef FEATURE_WLAN_TDLS
12406 mutex_unlock(&pHddCtx->tdls_lock);
12407#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012408 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012409 if( VOS_STATUS_SUCCESS != status )
12410 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012411 /* In case of JB, for P2P-GO, only change interface will be called,
12412 * This is the right place to enable back bmps_imps()
12413 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012414 if (pHddCtx->hdd_wlan_suspended)
12415 {
12416 hdd_set_pwrparams(pHddCtx);
12417 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012418 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 goto done;
12420 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012421 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012423 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12424 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012425 goto done;
12426 default:
12427 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12428 __func__);
12429 return -EOPNOTSUPP;
12430
12431 }
12432
12433 }
12434 else
12435 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012436 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12437 __func__, hdd_device_modetoString(pAdapter->device_mode),
12438 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012439 return -EOPNOTSUPP;
12440 }
12441
12442
12443 if(pRoamProfile)
12444 {
12445 if ( LastBSSType != pRoamProfile->BSSType )
12446 {
12447 /*interface type changed update in wiphy structure*/
12448 wdev->iftype = type;
12449
12450 /*the BSS mode changed, We need to issue disconnect
12451 if connected or in IBSS disconnect state*/
12452 if ( hdd_connGetConnectedBssType(
12453 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12454 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12455 {
12456 /*need to issue a disconnect to CSR.*/
12457 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12458 if( eHAL_STATUS_SUCCESS ==
12459 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12460 pAdapter->sessionId,
12461 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12462 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012463 ret = wait_for_completion_interruptible_timeout(
12464 &pAdapter->disconnect_comp_var,
12465 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12466 if (ret <= 0)
12467 {
12468 hddLog(VOS_TRACE_LEVEL_ERROR,
12469 FL("wait on disconnect_comp_var failed %ld"), ret);
12470 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012471 }
12472 }
12473 }
12474 }
12475
12476done:
12477 /*set bitmask based on updated value*/
12478 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012479
12480 /* Only STA mode support TM now
12481 * all other mode, TM feature should be disabled */
12482 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12483 (~VOS_STA & pHddCtx->concurrency_mode) )
12484 {
12485 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12486 }
12487
Jeff Johnson295189b2012-06-20 16:38:30 -070012488#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012489 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012490 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012491 {
12492 //we are ok to do AMP
12493 pHddCtx->isAmpAllowed = VOS_TRUE;
12494 }
12495#endif //WLAN_BTAMP_FEATURE
12496 EXIT();
12497 return 0;
12498}
12499
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012500/*
12501 * FUNCTION: wlan_hdd_cfg80211_change_iface
12502 * wrapper function to protect the actual implementation from SSR.
12503 */
12504int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12505 struct net_device *ndev,
12506 enum nl80211_iftype type,
12507 u32 *flags,
12508 struct vif_params *params
12509 )
12510{
12511 int ret;
12512
12513 vos_ssr_protect(__func__);
12514 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12515 vos_ssr_unprotect(__func__);
12516
12517 return ret;
12518}
12519
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012520#ifdef FEATURE_WLAN_TDLS
12521static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012522 struct net_device *dev,
12523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12524 const u8 *mac,
12525#else
12526 u8 *mac,
12527#endif
12528 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012529{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012531 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012532 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012533 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012534 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012535 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012536
12537 ENTER();
12538
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012539 if (!dev) {
12540 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12541 return -EINVAL;
12542 }
12543
12544 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12545 if (!pAdapter) {
12546 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12547 return -EINVAL;
12548 }
12549
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012550 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012551 {
12552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12553 "Invalid arguments");
12554 return -EINVAL;
12555 }
Hoonki Lee27511902013-03-14 18:19:06 -070012556
12557 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12558 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12559 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012561 "%s: TDLS mode is disabled OR not enabled in FW."
12562 MAC_ADDRESS_STR " Request declined.",
12563 __func__, MAC_ADDR_ARRAY(mac));
12564 return -ENOTSUPP;
12565 }
12566
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012567 if (pHddCtx->isLogpInProgress)
12568 {
12569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12570 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012571 wlan_hdd_tdls_set_link_status(pAdapter,
12572 mac,
12573 eTDLS_LINK_IDLE,
12574 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012575 return -EBUSY;
12576 }
12577
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012578 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012579 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012580
12581 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012583 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12584 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012585 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012586 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012587 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012588
12589 /* in add station, we accept existing valid staId if there is */
12590 if ((0 == update) &&
12591 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12592 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012593 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012594 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012595 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012596 " link_status %d. staId %d. add station ignored.",
12597 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012598 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012599 return 0;
12600 }
12601 /* in change station, we accept only when staId is valid */
12602 if ((1 == update) &&
12603 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12604 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12605 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012606 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012608 "%s: " MAC_ADDRESS_STR
12609 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012610 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12611 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12612 mutex_unlock(&pHddCtx->tdls_lock);
12613 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012614 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012615 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012616
12617 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012618 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012619 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12621 "%s: " MAC_ADDRESS_STR
12622 " TDLS setup is ongoing. Request declined.",
12623 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012624 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012625 }
12626
12627 /* first to check if we reached to maximum supported TDLS peer.
12628 TODO: for now, return -EPERM looks working fine,
12629 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012630 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12631 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012632 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012633 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12634 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012635 " TDLS Max peer already connected. Request declined."
12636 " Num of peers (%d), Max allowed (%d).",
12637 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12638 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012639 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012640 }
12641 else
12642 {
12643 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012644 mutex_lock(&pHddCtx->tdls_lock);
12645 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012646 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012647 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012648 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12650 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12651 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012652 return -EPERM;
12653 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012654 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012655 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012656 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012657 wlan_hdd_tdls_set_link_status(pAdapter,
12658 mac,
12659 eTDLS_LINK_CONNECTING,
12660 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012661
Jeff Johnsond75fe012013-04-06 10:53:06 -070012662 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012663 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012664 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012666 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012667 if(StaParams->htcap_present)
12668 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012670 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012672 "ht_capa->extended_capabilities: %0x",
12673 StaParams->HTCap.extendedHtCapInfo);
12674 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012676 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012677 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012678 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012679 if(StaParams->vhtcap_present)
12680 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012682 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12683 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12684 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12685 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012686 {
12687 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012689 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012691 "[%d]: %x ", i, StaParams->supported_rates[i]);
12692 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012693 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012694 else if ((1 == update) && (NULL == StaParams))
12695 {
12696 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12697 "%s : update is true, but staParams is NULL. Error!", __func__);
12698 return -EPERM;
12699 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012700
12701 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12702
12703 if (!update)
12704 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012705 /*Before adding sta make sure that device exited from BMPS*/
12706 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12707 {
12708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12709 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12710 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12711 if (status != VOS_STATUS_SUCCESS) {
12712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12713 }
12714 }
12715
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012716 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012717 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012718 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012719 hddLog(VOS_TRACE_LEVEL_ERROR,
12720 FL("Failed to add TDLS peer STA. Enable Bmps"));
12721 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012722 return -EPERM;
12723 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012724 }
12725 else
12726 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012727 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012728 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012729 if (ret != eHAL_STATUS_SUCCESS) {
12730 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12731 return -EPERM;
12732 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012733 }
12734
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012735 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012736 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12737
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012738 mutex_lock(&pHddCtx->tdls_lock);
12739 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12740
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012741 if ((pTdlsPeer != NULL) &&
12742 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012743 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012744 hddLog(VOS_TRACE_LEVEL_ERROR,
12745 FL("peer link status %u"), pTdlsPeer->link_status);
12746 mutex_unlock(&pHddCtx->tdls_lock);
12747 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012748 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012749 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012750
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012751 if (ret <= 0)
12752 {
12753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12754 "%s: timeout waiting for tdls add station indication %ld",
12755 __func__, ret);
12756 goto error;
12757 }
12758
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012759 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12760 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012762 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012763 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012764 }
12765
12766 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012767
12768error:
Atul Mittal115287b2014-07-08 13:26:33 +053012769 wlan_hdd_tdls_set_link_status(pAdapter,
12770 mac,
12771 eTDLS_LINK_IDLE,
12772 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012773 return -EPERM;
12774
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012775}
12776#endif
12777
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012778VOS_STATUS wlan_hdd_send_sta_authorized_event(
12779 hdd_adapter_t *adapter,
12780 hdd_context_t *hdd_ctx,
12781 const v_MACADDR_t *mac_addr)
12782{
12783 struct sk_buff *vendor_event;
12784 uint32_t sta_flags = 0;
12785 VOS_STATUS status;
12786
12787 ENTER();
12788
12789 if (!hdd_ctx) {
12790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12791 return -EINVAL;
12792 }
12793
12794 vendor_event =
12795 cfg80211_vendor_event_alloc(
12796 hdd_ctx->wiphy, &adapter->wdev, sizeof(sta_flags) +
12797 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12798 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12799 GFP_KERNEL);
12800 if (!vendor_event) {
12801 hddLog(VOS_TRACE_LEVEL_ERROR,
12802 FL("cfg80211_vendor_event_alloc failed"));
12803 return -EINVAL;
12804 }
12805
12806 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12807
12808 status = nla_put_u32(vendor_event,
12809 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12810 sta_flags);
12811 if (status) {
12812 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
12813 kfree_skb(vendor_event);
12814 return VOS_STATUS_E_FAILURE;
12815 }
12816 status = nla_put(vendor_event,
12817 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
12818 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
12819 if (status) {
12820 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
12821 kfree_skb(vendor_event);
12822 return VOS_STATUS_E_FAILURE;
12823 }
12824
12825 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
12826
12827 EXIT();
12828 return 0;
12829}
12830
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012831static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012832 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012833#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12834 const u8 *mac,
12835#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012837#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012838 struct station_parameters *params)
12839{
12840 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012841 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012842 hdd_context_t *pHddCtx;
12843 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012844 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012845 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012846#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012847 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012848 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012849 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012850 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012851#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012852
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012853 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012854
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012855 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012856 if ((NULL == pAdapter))
12857 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012858 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012859 "invalid adapter ");
12860 return -EINVAL;
12861 }
12862
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12864 TRACE_CODE_HDD_CHANGE_STATION,
12865 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012866 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012867
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012868 ret = wlan_hdd_validate_context(pHddCtx);
12869 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012870 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012871 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012872 }
12873
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012874 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12875
12876 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012877 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12879 "invalid HDD station context");
12880 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012881 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012882 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12883
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012884 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12885 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012887 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012889 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012890 WLANTL_STA_AUTHENTICATED);
12891
Gopichand Nakkala29149562013-05-10 21:43:41 +053012892 if (status != VOS_STATUS_SUCCESS)
12893 {
12894 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12895 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12896 return -EINVAL;
12897 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012898 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
12899 &STAMacAddress);
12900 if (status != VOS_STATUS_SUCCESS)
12901 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 }
12903 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012904 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12905 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012906#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012907 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12908 StaParams.capability = params->capability;
12909 StaParams.uapsd_queues = params->uapsd_queues;
12910 StaParams.max_sp = params->max_sp;
12911
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012912 /* Convert (first channel , number of channels) tuple to
12913 * the total list of channels. This goes with the assumption
12914 * that if the first channel is < 14, then the next channels
12915 * are an incremental of 1 else an incremental of 4 till the number
12916 * of channels.
12917 */
12918 if (0 != params->supported_channels_len) {
12919 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12920 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12921 {
12922 int wifi_chan_index;
12923 StaParams.supported_channels[j] = params->supported_channels[i];
12924 wifi_chan_index =
12925 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12926 no_of_channels = params->supported_channels[i+1];
12927 for(k=1; k <= no_of_channels; k++)
12928 {
12929 StaParams.supported_channels[j+1] =
12930 StaParams.supported_channels[j] + wifi_chan_index;
12931 j+=1;
12932 }
12933 }
12934 StaParams.supported_channels_len = j;
12935 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012936 if (params->supported_oper_classes_len >
12937 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12938 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12939 "received oper classes:%d, resetting it to max supported %d",
12940 params->supported_oper_classes_len,
12941 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12942 params->supported_oper_classes_len =
12943 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12944 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012945 vos_mem_copy(StaParams.supported_oper_classes,
12946 params->supported_oper_classes,
12947 params->supported_oper_classes_len);
12948 StaParams.supported_oper_classes_len =
12949 params->supported_oper_classes_len;
12950
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012951 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12953 "received extn capabilities:%d, resetting it to max supported",
12954 params->ext_capab_len);
12955 params->ext_capab_len = sizeof(StaParams.extn_capability);
12956 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012957 if (0 != params->ext_capab_len)
12958 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012959 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012960
12961 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012962 {
12963 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012964 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012965 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012966
12967 StaParams.supported_rates_len = params->supported_rates_len;
12968
12969 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12970 * The supported_rates array , for all the structures propogating till Add Sta
12971 * to the firmware has to be modified , if the supplicant (ieee80211) is
12972 * modified to send more rates.
12973 */
12974
12975 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12976 */
12977 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12978 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12979
12980 if (0 != StaParams.supported_rates_len) {
12981 int i = 0;
12982 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12983 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012984 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012985 "Supported Rates with Length %d", StaParams.supported_rates_len);
12986 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012988 "[%d]: %0x", i, StaParams.supported_rates[i]);
12989 }
12990
12991 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012992 {
12993 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012994 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012995 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012996
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012997 if (0 != params->ext_capab_len ) {
12998 /*Define A Macro : TODO Sunil*/
12999 if ((1<<4) & StaParams.extn_capability[3]) {
13000 isBufSta = 1;
13001 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013002 /* TDLS Channel Switching Support */
13003 if ((1<<6) & StaParams.extn_capability[3]) {
13004 isOffChannelSupported = 1;
13005 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013006 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013007
13008 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013009 (params->ht_capa || params->vht_capa ||
13010 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013011 /* TDLS Peer is WME/QoS capable */
13012 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013013
13014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13015 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13016 __func__, isQosWmmSta, StaParams.htcap_present);
13017
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013018 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13019 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013020 isOffChannelSupported,
13021 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013022
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013023 if (VOS_STATUS_SUCCESS != status) {
13024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13025 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13026 return -EINVAL;
13027 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013028 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13029
13030 if (VOS_STATUS_SUCCESS != status) {
13031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13032 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13033 return -EINVAL;
13034 }
13035 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013036#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013037 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013038 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 return status;
13040}
13041
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13043static int wlan_hdd_change_station(struct wiphy *wiphy,
13044 struct net_device *dev,
13045 const u8 *mac,
13046 struct station_parameters *params)
13047#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013048static int wlan_hdd_change_station(struct wiphy *wiphy,
13049 struct net_device *dev,
13050 u8 *mac,
13051 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013052#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013053{
13054 int ret;
13055
13056 vos_ssr_protect(__func__);
13057 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13058 vos_ssr_unprotect(__func__);
13059
13060 return ret;
13061}
13062
Jeff Johnson295189b2012-06-20 16:38:30 -070013063/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013064 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 * This function is used to initialize the key information
13066 */
13067#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013068static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013069 struct net_device *ndev,
13070 u8 key_index, bool pairwise,
13071 const u8 *mac_addr,
13072 struct key_params *params
13073 )
13074#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013075static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013076 struct net_device *ndev,
13077 u8 key_index, const u8 *mac_addr,
13078 struct key_params *params
13079 )
13080#endif
13081{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013083 tCsrRoamSetKey setKey;
13084 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013085 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013086 v_U32_t roamId= 0xFF;
13087 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013088 hdd_hostapd_state_t *pHostapdState;
13089 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013090 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013091 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013092 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013093 v_MACADDR_t *peerMacAddr;
13094 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013095 uint8_t staid = HDD_MAX_STA_COUNT;
13096 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013097
13098 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013099
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013100 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13101 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13102 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013103 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13104 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013105 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013106 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013107 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013108 }
13109
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013110 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13111 __func__, hdd_device_modetoString(pAdapter->device_mode),
13112 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013113
13114 if (CSR_MAX_NUM_KEY <= key_index)
13115 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 key_index);
13118
13119 return -EINVAL;
13120 }
13121
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013122 if (CSR_MAX_KEY_LEN < params->key_len)
13123 {
13124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13125 params->key_len);
13126
13127 return -EINVAL;
13128 }
13129
Jingxiang Gec438aea2017-10-26 16:44:00 +080013130 if (CSR_MAX_RSC_LEN < params->seq_len)
13131 {
13132 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13133 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013134
13135 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013136 }
13137
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013138 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013139 "%s: called with key index = %d & key length %d & seq length %d",
13140 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013141
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013142 peerMacAddr = (v_MACADDR_t *)mac_addr;
13143
Jeff Johnson295189b2012-06-20 16:38:30 -070013144 /*extract key idx, key len and key*/
13145 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13146 setKey.keyId = key_index;
13147 setKey.keyLength = params->key_len;
13148 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013149 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013150
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013151 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013152 {
13153 case WLAN_CIPHER_SUITE_WEP40:
13154 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13155 break;
13156
13157 case WLAN_CIPHER_SUITE_WEP104:
13158 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13159 break;
13160
13161 case WLAN_CIPHER_SUITE_TKIP:
13162 {
13163 u8 *pKey = &setKey.Key[0];
13164 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13165
13166 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13167
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013168 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013169
13170 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013171 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013172 |--------------|----------|----------|
13173 <---16bytes---><--8bytes--><--8bytes-->
13174
13175 */
13176 /*Sme expects the 32 bytes key to be in the below order
13177
13178 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013179 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 |--------------|----------|----------|
13181 <---16bytes---><--8bytes--><--8bytes-->
13182 */
13183 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013184 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013185
13186 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013187 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013188
13189 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013190 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013191
13192
13193 break;
13194 }
13195
13196 case WLAN_CIPHER_SUITE_CCMP:
13197 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13198 break;
13199
13200#ifdef FEATURE_WLAN_WAPI
13201 case WLAN_CIPHER_SUITE_SMS4:
13202 {
13203 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13204 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13205 params->key, params->key_len);
13206 return 0;
13207 }
13208#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013209
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013210#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013211 case WLAN_CIPHER_SUITE_KRK:
13212 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13213 break;
13214#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013215
13216#ifdef WLAN_FEATURE_11W
13217 case WLAN_CIPHER_SUITE_AES_CMAC:
13218 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013219 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013220#endif
13221
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013223 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013225 status = -EOPNOTSUPP;
13226 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013227 }
13228
13229 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13230 __func__, setKey.encType);
13231
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013232 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013233#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13234 (!pairwise)
13235#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013236 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013237#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013238 )
13239 {
13240 /* set group key*/
13241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13242 "%s- %d: setting Broadcast key",
13243 __func__, __LINE__);
13244 setKey.keyDirection = eSIR_RX_ONLY;
13245 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13246 }
13247 else
13248 {
13249 /* set pairwise key*/
13250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13251 "%s- %d: setting pairwise key",
13252 __func__, __LINE__);
13253 setKey.keyDirection = eSIR_TX_RX;
13254 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013255 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013256 }
13257 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13258 {
13259 setKey.keyDirection = eSIR_TX_RX;
13260 /*Set the group key*/
13261 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13262 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013263
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013264 if ( 0 != status )
13265 {
13266 hddLog(VOS_TRACE_LEVEL_ERROR,
13267 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013268 status = -EINVAL;
13269 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013270 }
13271 /*Save the keys here and call sme_RoamSetKey for setting
13272 the PTK after peer joins the IBSS network*/
13273 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13274 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013275 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013276 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013277 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13278 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13279 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013280 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013281 if( pHostapdState->bssState == BSS_START )
13282 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013283 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13284 vos_status = wlan_hdd_check_ula_done(pAdapter);
13285
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013286 if (peerMacAddr && (pairwise_set_key == true))
13287 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013288
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013289 if ( vos_status != VOS_STATUS_SUCCESS )
13290 {
13291 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13292 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13293 __LINE__, vos_status );
13294
13295 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13296
13297 status = -EINVAL;
13298 goto end;
13299 }
13300
Jeff Johnson295189b2012-06-20 16:38:30 -070013301 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13302
13303 if ( status != eHAL_STATUS_SUCCESS )
13304 {
13305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13306 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13307 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013308 status = -EINVAL;
13309 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 }
13311 }
13312
13313 /* Saving WEP keys */
13314 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13315 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13316 {
13317 //Save the wep key in ap context. Issue setkey after the BSS is started.
13318 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13319 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13320 }
13321 else
13322 {
13323 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013324 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013325 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13326 }
13327 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013328 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13329 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013330 {
13331 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13332 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13333
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013334#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13335 if (!pairwise)
13336#else
13337 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13338#endif
13339 {
13340 /* set group key*/
13341 if (pHddStaCtx->roam_info.deferKeyComplete)
13342 {
13343 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13344 "%s- %d: Perform Set key Complete",
13345 __func__, __LINE__);
13346 hdd_PerformRoamSetKeyComplete(pAdapter);
13347 }
13348 }
13349
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013350 if (pairwise_set_key == true)
13351 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013352
Jeff Johnson295189b2012-06-20 16:38:30 -070013353 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13354
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013355 pWextState->roamProfile.Keys.defaultIndex = key_index;
13356
13357
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013358 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013359 params->key, params->key_len);
13360
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013361
Jeff Johnson295189b2012-06-20 16:38:30 -070013362 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13363
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013364 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013366 __func__, setKey.peerMac[0], setKey.peerMac[1],
13367 setKey.peerMac[2], setKey.peerMac[3],
13368 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013369 setKey.keyDirection);
13370
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013371 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013372
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013373 if ( vos_status != VOS_STATUS_SUCCESS )
13374 {
13375 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013376 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13377 __LINE__, vos_status );
13378
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013379 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013380
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013381 status = -EINVAL;
13382 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013383
13384 }
13385
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013386#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013387 /* The supplicant may attempt to set the PTK once pre-authentication
13388 is done. Save the key in the UMAC and include it in the ADD BSS
13389 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013390 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013391 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013392 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013393 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13394 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013395 status = 0;
13396 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013397 }
13398 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13399 {
13400 hddLog(VOS_TRACE_LEVEL_ERROR,
13401 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013402 status = -EINVAL;
13403 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013404 }
13405#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013406
13407 /* issue set key request to SME*/
13408 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13409 pAdapter->sessionId, &setKey, &roamId );
13410
13411 if ( 0 != status )
13412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013413 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013414 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13415 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013416 status = -EINVAL;
13417 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013418 }
13419
13420
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013421 /* in case of IBSS as there was no information available about WEP keys during
13422 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013423 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013424 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13425 !( ( IW_AUTH_KEY_MGMT_802_1X
13426 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013427 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13428 )
13429 &&
13430 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13431 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13432 )
13433 )
13434 {
13435 setKey.keyDirection = eSIR_RX_ONLY;
13436 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13437
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013438 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013440 __func__, setKey.peerMac[0], setKey.peerMac[1],
13441 setKey.peerMac[2], setKey.peerMac[3],
13442 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 setKey.keyDirection);
13444
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013445 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013446 pAdapter->sessionId, &setKey, &roamId );
13447
13448 if ( 0 != status )
13449 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013450 hddLog(VOS_TRACE_LEVEL_ERROR,
13451 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013452 __func__, status);
13453 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013454 status = -EINVAL;
13455 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 }
13457 }
13458 }
13459
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013460 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013461 for (i = 0; i < params->seq_len; i++) {
13462 rsc_counter |= (params->seq[i] << i*8);
13463 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013464 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13465 }
13466
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013467end:
13468 /* Need to clear any trace of key value in the memory.
13469 * Thus zero out the memory even though it is local
13470 * variable.
13471 */
13472 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013473 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013474 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013475}
13476
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013477#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13478static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13479 struct net_device *ndev,
13480 u8 key_index, bool pairwise,
13481 const u8 *mac_addr,
13482 struct key_params *params
13483 )
13484#else
13485static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13486 struct net_device *ndev,
13487 u8 key_index, const u8 *mac_addr,
13488 struct key_params *params
13489 )
13490#endif
13491{
13492 int ret;
13493 vos_ssr_protect(__func__);
13494#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13495 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13496 mac_addr, params);
13497#else
13498 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13499 params);
13500#endif
13501 vos_ssr_unprotect(__func__);
13502
13503 return ret;
13504}
13505
Jeff Johnson295189b2012-06-20 16:38:30 -070013506/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013507 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 * This function is used to get the key information
13509 */
13510#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013511static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013512 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013514 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 const u8 *mac_addr, void *cookie,
13516 void (*callback)(void *cookie, struct key_params*)
13517 )
13518#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013519static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013520 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013521 struct net_device *ndev,
13522 u8 key_index, const u8 *mac_addr, void *cookie,
13523 void (*callback)(void *cookie, struct key_params*)
13524 )
13525#endif
13526{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013527 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013528 hdd_wext_state_t *pWextState = NULL;
13529 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013530 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013531 hdd_context_t *pHddCtx;
13532 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013533
13534 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013535
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013536 if (NULL == pAdapter)
13537 {
13538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13539 "%s: HDD adapter is Null", __func__);
13540 return -ENODEV;
13541 }
13542
13543 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13544 ret = wlan_hdd_validate_context(pHddCtx);
13545 if (0 != ret)
13546 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013547 return ret;
13548 }
13549
13550 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13551 pRoamProfile = &(pWextState->roamProfile);
13552
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013553 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13554 __func__, hdd_device_modetoString(pAdapter->device_mode),
13555 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013556
Jeff Johnson295189b2012-06-20 16:38:30 -070013557 memset(&params, 0, sizeof(params));
13558
13559 if (CSR_MAX_NUM_KEY <= key_index)
13560 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013563 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013564
13565 switch(pRoamProfile->EncryptionType.encryptionType[0])
13566 {
13567 case eCSR_ENCRYPT_TYPE_NONE:
13568 params.cipher = IW_AUTH_CIPHER_NONE;
13569 break;
13570
13571 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13572 case eCSR_ENCRYPT_TYPE_WEP40:
13573 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13574 break;
13575
13576 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13577 case eCSR_ENCRYPT_TYPE_WEP104:
13578 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13579 break;
13580
13581 case eCSR_ENCRYPT_TYPE_TKIP:
13582 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13583 break;
13584
13585 case eCSR_ENCRYPT_TYPE_AES:
13586 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13587 break;
13588
13589 default:
13590 params.cipher = IW_AUTH_CIPHER_NONE;
13591 break;
13592 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013593
c_hpothuaaf19692014-05-17 17:01:48 +053013594 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13595 TRACE_CODE_HDD_CFG80211_GET_KEY,
13596 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013597
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13599 params.seq_len = 0;
13600 params.seq = NULL;
13601 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13602 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013603 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 return 0;
13605}
13606
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013607#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13608static int wlan_hdd_cfg80211_get_key(
13609 struct wiphy *wiphy,
13610 struct net_device *ndev,
13611 u8 key_index, bool pairwise,
13612 const u8 *mac_addr, void *cookie,
13613 void (*callback)(void *cookie, struct key_params*)
13614 )
13615#else
13616static int wlan_hdd_cfg80211_get_key(
13617 struct wiphy *wiphy,
13618 struct net_device *ndev,
13619 u8 key_index, const u8 *mac_addr, void *cookie,
13620 void (*callback)(void *cookie, struct key_params*)
13621 )
13622#endif
13623{
13624 int ret;
13625
13626 vos_ssr_protect(__func__);
13627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13628 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13629 mac_addr, cookie, callback);
13630#else
13631 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13632 callback);
13633#endif
13634 vos_ssr_unprotect(__func__);
13635
13636 return ret;
13637}
13638
Jeff Johnson295189b2012-06-20 16:38:30 -070013639/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013640 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013641 * This function is used to delete the key information
13642 */
13643#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013644static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013646 u8 key_index,
13647 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 const u8 *mac_addr
13649 )
13650#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013651static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013652 struct net_device *ndev,
13653 u8 key_index,
13654 const u8 *mac_addr
13655 )
13656#endif
13657{
13658 int status = 0;
13659
13660 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013661 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013662 //it is observed that this is invalidating peer
13663 //key index whenever re-key is done. This is affecting data link.
13664 //It should be ok to ignore del_key.
13665#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013666 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13667 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13669 tCsrRoamSetKey setKey;
13670 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013671
Jeff Johnson295189b2012-06-20 16:38:30 -070013672 ENTER();
13673
13674 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13675 __func__,pAdapter->device_mode);
13676
13677 if (CSR_MAX_NUM_KEY <= key_index)
13678 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013679 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013680 key_index);
13681
13682 return -EINVAL;
13683 }
13684
13685 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13686 setKey.keyId = key_index;
13687
13688 if (mac_addr)
13689 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13690 else
13691 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13692
13693 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13694
13695 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013696 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013697 )
13698 {
13699
13700 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013701 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13702 if( pHostapdState->bssState == BSS_START)
13703 {
13704 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013705
Jeff Johnson295189b2012-06-20 16:38:30 -070013706 if ( status != eHAL_STATUS_SUCCESS )
13707 {
13708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13709 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13710 __LINE__, status );
13711 }
13712 }
13713 }
13714 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013715 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 )
13717 {
13718 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13719
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013720 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13721
13722 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013724 __func__, setKey.peerMac[0], setKey.peerMac[1],
13725 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013727 if(pAdapter->sessionCtx.station.conn_info.connState ==
13728 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013729 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013730 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 if ( 0 != status )
13734 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013735 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013736 "%s: sme_RoamSetKey failure, returned %d",
13737 __func__, status);
13738 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13739 return -EINVAL;
13740 }
13741 }
13742 }
13743#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013744 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013745 return status;
13746}
13747
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13749static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13750 struct net_device *ndev,
13751 u8 key_index,
13752 bool pairwise,
13753 const u8 *mac_addr
13754 )
13755#else
13756static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13757 struct net_device *ndev,
13758 u8 key_index,
13759 const u8 *mac_addr
13760 )
13761#endif
13762{
13763 int ret;
13764
13765 vos_ssr_protect(__func__);
13766#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13767 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13768 mac_addr);
13769#else
13770 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13771#endif
13772 vos_ssr_unprotect(__func__);
13773
13774 return ret;
13775}
13776
Jeff Johnson295189b2012-06-20 16:38:30 -070013777/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013778 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 * This function is used to set the default tx key index
13780 */
13781#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013782static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 struct net_device *ndev,
13784 u8 key_index,
13785 bool unicast, bool multicast)
13786#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013787static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013788 struct net_device *ndev,
13789 u8 key_index)
13790#endif
13791{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013793 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013794 hdd_wext_state_t *pWextState;
13795 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013796 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013797
13798 ENTER();
13799
Gopichand Nakkala29149562013-05-10 21:43:41 +053013800 if ((NULL == pAdapter))
13801 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013802 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013803 "invalid adapter");
13804 return -EINVAL;
13805 }
13806
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013807 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13808 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13809 pAdapter->sessionId, key_index));
13810
Gopichand Nakkala29149562013-05-10 21:43:41 +053013811 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13812 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13813
13814 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13815 {
13816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13817 "invalid Wext state or HDD context");
13818 return -EINVAL;
13819 }
13820
Arif Hussain6d2a3322013-11-17 19:50:10 -080013821 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 if (CSR_MAX_NUM_KEY <= key_index)
13825 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013826 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013827 key_index);
13828
13829 return -EINVAL;
13830 }
13831
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013832 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13833 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013834 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013835 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013836 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013837 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013838
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013840 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013841 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013842 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013843 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013844 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013845#ifdef FEATURE_WLAN_WAPI
13846 (eCSR_ENCRYPT_TYPE_WPI !=
13847 pHddStaCtx->conn_info.ucEncryptionType) &&
13848#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013849 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013850 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013852 {
13853 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013854 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013855
Jeff Johnson295189b2012-06-20 16:38:30 -070013856 tCsrRoamSetKey setKey;
13857 v_U32_t roamId= 0xFF;
13858 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013859
13860 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013861 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013862
Jeff Johnson295189b2012-06-20 16:38:30 -070013863 Keys->defaultIndex = (u8)key_index;
13864 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13865 setKey.keyId = key_index;
13866 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013867
13868 vos_mem_copy(&setKey.Key[0],
13869 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013870 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013871
Gopichand Nakkala29149562013-05-10 21:43:41 +053013872 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013873
13874 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013875 &pHddStaCtx->conn_info.bssId[0],
13876 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013877
Gopichand Nakkala29149562013-05-10 21:43:41 +053013878 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13879 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13880 eCSR_ENCRYPT_TYPE_WEP104)
13881 {
13882 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13883 even though ap is configured for WEP-40 encryption. In this canse the key length
13884 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13885 type(104) and switching encryption type to 40*/
13886 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13887 eCSR_ENCRYPT_TYPE_WEP40;
13888 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13889 eCSR_ENCRYPT_TYPE_WEP40;
13890 }
13891
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013892 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013893 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013894
Jeff Johnson295189b2012-06-20 16:38:30 -070013895 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013896 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013897 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013898
Jeff Johnson295189b2012-06-20 16:38:30 -070013899 if ( 0 != status )
13900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013901 hddLog(VOS_TRACE_LEVEL_ERROR,
13902 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013903 status);
13904 return -EINVAL;
13905 }
13906 }
13907 }
13908
13909 /* In SoftAp mode setting key direction for default mode */
13910 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13911 {
13912 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13913 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13914 (eCSR_ENCRYPT_TYPE_AES !=
13915 pWextState->roamProfile.EncryptionType.encryptionType[0])
13916 )
13917 {
13918 /* Saving key direction for default key index to TX default */
13919 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13920 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13921 }
13922 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013923 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013924 return status;
13925}
13926
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13928static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13929 struct net_device *ndev,
13930 u8 key_index,
13931 bool unicast, bool multicast)
13932#else
13933static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13934 struct net_device *ndev,
13935 u8 key_index)
13936#endif
13937{
13938 int ret;
13939 vos_ssr_protect(__func__);
13940#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13941 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13942 multicast);
13943#else
13944 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13945#endif
13946 vos_ssr_unprotect(__func__);
13947
13948 return ret;
13949}
13950
Jeff Johnson295189b2012-06-20 16:38:30 -070013951/*
13952 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13953 * This function is used to inform the BSS details to nl80211 interface.
13954 */
13955static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13956 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13957{
13958 struct net_device *dev = pAdapter->dev;
13959 struct wireless_dev *wdev = dev->ieee80211_ptr;
13960 struct wiphy *wiphy = wdev->wiphy;
13961 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13962 int chan_no;
13963 int ie_length;
13964 const char *ie;
13965 unsigned int freq;
13966 struct ieee80211_channel *chan;
13967 int rssi = 0;
13968 struct cfg80211_bss *bss = NULL;
13969
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 if( NULL == pBssDesc )
13971 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013972 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013973 return bss;
13974 }
13975
13976 chan_no = pBssDesc->channelId;
13977 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13978 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13979
13980 if( NULL == ie )
13981 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013982 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013983 return bss;
13984 }
13985
13986#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13987 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13988 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013989 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 }
13991 else
13992 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013993 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 }
13995#else
13996 freq = ieee80211_channel_to_frequency(chan_no);
13997#endif
13998
13999 chan = __ieee80211_get_channel(wiphy, freq);
14000
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053014001 if (!chan) {
14002 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14003 return NULL;
14004 }
14005
Abhishek Singhaee43942014-06-16 18:55:47 +053014006 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014007
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014008 return cfg80211_inform_bss(wiphy, chan,
14009#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14010 CFG80211_BSS_FTYPE_UNKNOWN,
14011#endif
14012 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014013 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014014 pBssDesc->capabilityInfo,
14015 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014016 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014017}
14018
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014019/*
14020 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14021 * interface that BSS might have been lost.
14022 * @pAdapter: adaptor
14023 * @bssid: bssid which might have been lost
14024 *
14025 * Return: bss which is unlinked from kernel cache
14026 */
14027struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14028 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14029{
14030 struct net_device *dev = pAdapter->dev;
14031 struct wireless_dev *wdev = dev->ieee80211_ptr;
14032 struct wiphy *wiphy = wdev->wiphy;
14033 struct cfg80211_bss *bss = NULL;
14034
Abhishek Singh5a597e62016-12-05 15:16:30 +053014035 bss = hdd_get_bss_entry(wiphy,
14036 NULL, bssid,
14037 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014038 if (bss == NULL) {
14039 hddLog(LOGE, FL("BSS not present"));
14040 } else {
14041 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14042 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14043 cfg80211_unlink_bss(wiphy, bss);
14044 }
14045 return bss;
14046}
Jeff Johnson295189b2012-06-20 16:38:30 -070014047
14048
14049/*
14050 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14051 * This function is used to inform the BSS details to nl80211 interface.
14052 */
14053struct cfg80211_bss*
14054wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14055 tSirBssDescription *bss_desc
14056 )
14057{
14058 /*
14059 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14060 already exists in bss data base of cfg80211 for that particular BSS ID.
14061 Using cfg80211_inform_bss_frame to update the bss entry instead of
14062 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14063 now there is no possibility to get the mgmt(probe response) frame from PE,
14064 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14065 cfg80211_inform_bss_frame.
14066 */
14067 struct net_device *dev = pAdapter->dev;
14068 struct wireless_dev *wdev = dev->ieee80211_ptr;
14069 struct wiphy *wiphy = wdev->wiphy;
14070 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014071#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14072 qcom_ie_age *qie_age = NULL;
14073 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14074#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014075 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014076#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014077 const char *ie =
14078 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14079 unsigned int freq;
14080 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014081 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 struct cfg80211_bss *bss_status = NULL;
14083 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
14084 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014085 hdd_context_t *pHddCtx;
14086 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014087#ifdef WLAN_OPEN_SOURCE
14088 struct timespec ts;
14089#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014090
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014091
Wilson Yangf80a0542013-10-07 13:02:37 -070014092 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14093 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014094 if (0 != status)
14095 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014096 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014097 }
14098
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014099 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014100 if (!mgmt)
14101 {
14102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14103 "%s: memory allocation failed ", __func__);
14104 return NULL;
14105 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014106
Jeff Johnson295189b2012-06-20 16:38:30 -070014107 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014108
14109#ifdef WLAN_OPEN_SOURCE
14110 /* Android does not want the timestamp from the frame.
14111 Instead it wants a monotonic increasing value */
14112 get_monotonic_boottime(&ts);
14113 mgmt->u.probe_resp.timestamp =
14114 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14115#else
14116 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014117 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14118 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014119
14120#endif
14121
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14123 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014124
14125#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14126 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14127 /* Assuming this is the last IE, copy at the end */
14128 ie_length -=sizeof(qcom_ie_age);
14129 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14130 qie_age->element_id = QCOM_VENDOR_IE_ID;
14131 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14132 qie_age->oui_1 = QCOM_OUI1;
14133 qie_age->oui_2 = QCOM_OUI2;
14134 qie_age->oui_3 = QCOM_OUI3;
14135 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014136 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14137 * bss related timestamp is in units of ms. Due to this when scan results
14138 * are sent to lowi the scan age is high.To address this, send age in units
14139 * of 1/10 ms.
14140 */
14141 qie_age->age = (vos_timer_get_system_time() -
14142 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014143#endif
14144
Jeff Johnson295189b2012-06-20 16:38:30 -070014145 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014146 if (bss_desc->fProbeRsp)
14147 {
14148 mgmt->frame_control |=
14149 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14150 }
14151 else
14152 {
14153 mgmt->frame_control |=
14154 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14155 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014156
14157#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014158 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014159 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014160 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014161 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014162 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014163 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014164 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014165
14166 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014167 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014168 }
14169 else
14170 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014171 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14172 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014173 kfree(mgmt);
14174 return NULL;
14175 }
14176#else
14177 freq = ieee80211_channel_to_frequency(chan_no);
14178#endif
14179 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014180 /*when the band is changed on the fly using the GUI, three things are done
14181 * 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)
14182 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14183 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14184 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14185 * and discards the channels correponding to previous band and calls back with zero bss results.
14186 * 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
14187 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14188 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14189 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14190 * So drop the bss and continue to next bss.
14191 */
14192 if(chan == NULL)
14193 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014194 hddLog(VOS_TRACE_LEVEL_ERROR,
14195 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14196 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014197 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014198 return NULL;
14199 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014200 /*To keep the rssi icon of the connected AP in the scan window
14201 *and the rssi icon of the wireless networks in sync
14202 * */
14203 if (( eConnectionState_Associated ==
14204 pAdapter->sessionCtx.station.conn_info.connState ) &&
14205 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14206 pAdapter->sessionCtx.station.conn_info.bssId,
14207 WNI_CFG_BSSID_LEN)) &&
14208 (pHddCtx->hdd_wlan_suspended == FALSE))
14209 {
14210 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14211 rssi = (pAdapter->rssi * 100);
14212 }
14213 else
14214 {
14215 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14216 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014217
Nirav Shah20ac06f2013-12-12 18:14:06 +053014218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014219 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14220 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014221
Jeff Johnson295189b2012-06-20 16:38:30 -070014222 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14223 frame_len, rssi, GFP_KERNEL);
14224 kfree(mgmt);
14225 return bss_status;
14226}
14227
14228/*
14229 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14230 * This function is used to update the BSS data base of CFG8011
14231 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014232struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014233 tCsrRoamInfo *pRoamInfo
14234 )
14235{
14236 tCsrRoamConnectedProfile roamProfile;
14237 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14238 struct cfg80211_bss *bss = NULL;
14239
14240 ENTER();
14241
14242 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14243 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14244
14245 if (NULL != roamProfile.pBssDesc)
14246 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014247 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14248 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014249
14250 if (NULL == bss)
14251 {
14252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14253 __func__);
14254 }
14255
14256 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14257 }
14258 else
14259 {
14260 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14261 __func__);
14262 }
14263 return bss;
14264}
14265
14266/*
14267 * FUNCTION: wlan_hdd_cfg80211_update_bss
14268 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014269static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14270 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014272{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014273 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014274 tCsrScanResultInfo *pScanResult;
14275 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014276 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014277 tScanResultHandle pResult;
14278 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014279 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014280 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014282
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014283 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14284 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14285 NO_SESSION, pAdapter->sessionId));
14286
Wilson Yangf80a0542013-10-07 13:02:37 -070014287 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014288 ret = wlan_hdd_validate_context(pHddCtx);
14289 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014290 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014291 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014292 }
14293
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014294 if (pAdapter->request != NULL)
14295 {
14296 if ((pAdapter->request->n_ssids == 1)
14297 && (pAdapter->request->ssids != NULL)
14298 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14299 is_p2p_scan = true;
14300 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014301 /*
14302 * start getting scan results and populate cgf80211 BSS database
14303 */
14304 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14305
14306 /* no scan results */
14307 if (NULL == pResult)
14308 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014309 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14310 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014311 wlan_hdd_get_frame_logs(pAdapter,
14312 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 return status;
14314 }
14315
14316 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14317
14318 while (pScanResult)
14319 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014320 /*
14321 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14322 * entry already exists in bss data base of cfg80211 for that
14323 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14324 * bss entry instead of cfg80211_inform_bss, But this call expects
14325 * mgmt packet as input. As of now there is no possibility to get
14326 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014327 * ieee80211_mgmt(probe response) and passing to c
14328 * fg80211_inform_bss_frame.
14329 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014330 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14331 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14332 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014333 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14334 continue; //Skip the non p2p bss entries
14335 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014336 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14337 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014338
Jeff Johnson295189b2012-06-20 16:38:30 -070014339
14340 if (NULL == bss_status)
14341 {
14342 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014343 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014344 }
14345 else
14346 {
Yue Maf49ba872013-08-19 12:04:25 -070014347 cfg80211_put_bss(
14348#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14349 wiphy,
14350#endif
14351 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 }
14353
14354 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14355 }
14356
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014357 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014358 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014359 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014360}
14361
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014362void
14363hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14364{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014365 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014366 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014367} /****** end hddPrintMacAddr() ******/
14368
14369void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014370hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014371{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014372 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014373 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014374 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14375 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14376 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014377} /****** end hddPrintPmkId() ******/
14378
14379//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14380//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14381
14382//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14383//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14384
14385#define dump_bssid(bssid) \
14386 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014387 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14388 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014389 }
14390
14391#define dump_pmkid(pMac, pmkid) \
14392 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014393 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14394 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014395 }
14396
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014397#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014398/*
14399 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14400 * This function is used to notify the supplicant of a new PMKSA candidate.
14401 */
14402int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014403 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014404 int index, bool preauth )
14405{
Jeff Johnsone7245742012-09-05 17:12:55 -070014406#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014407 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014408 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014409
14410 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014411 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014412
14413 if( NULL == pRoamInfo )
14414 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014415 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014416 return -EINVAL;
14417 }
14418
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014419 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14420 {
14421 dump_bssid(pRoamInfo->bssid);
14422 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014423 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014424 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014425#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014426 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014427}
14428#endif //FEATURE_WLAN_LFR
14429
Yue Maef608272013-04-08 23:09:17 -070014430#ifdef FEATURE_WLAN_LFR_METRICS
14431/*
14432 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14433 * 802.11r/LFR metrics reporting function to report preauth initiation
14434 *
14435 */
14436#define MAX_LFR_METRICS_EVENT_LENGTH 100
14437VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14438 tCsrRoamInfo *pRoamInfo)
14439{
14440 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14441 union iwreq_data wrqu;
14442
14443 ENTER();
14444
14445 if (NULL == pAdapter)
14446 {
14447 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14448 return VOS_STATUS_E_FAILURE;
14449 }
14450
14451 /* create the event */
14452 memset(&wrqu, 0, sizeof(wrqu));
14453 memset(metrics_notification, 0, sizeof(metrics_notification));
14454
14455 wrqu.data.pointer = metrics_notification;
14456 wrqu.data.length = scnprintf(metrics_notification,
14457 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14458 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14459
14460 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14461
14462 EXIT();
14463
14464 return VOS_STATUS_SUCCESS;
14465}
14466
14467/*
14468 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14469 * 802.11r/LFR metrics reporting function to report preauth completion
14470 * or failure
14471 */
14472VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14473 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14474{
14475 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14476 union iwreq_data wrqu;
14477
14478 ENTER();
14479
14480 if (NULL == pAdapter)
14481 {
14482 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14483 return VOS_STATUS_E_FAILURE;
14484 }
14485
14486 /* create the event */
14487 memset(&wrqu, 0, sizeof(wrqu));
14488 memset(metrics_notification, 0, sizeof(metrics_notification));
14489
14490 scnprintf(metrics_notification, sizeof(metrics_notification),
14491 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14492 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14493
14494 if (1 == preauth_status)
14495 strncat(metrics_notification, " TRUE", 5);
14496 else
14497 strncat(metrics_notification, " FALSE", 6);
14498
14499 wrqu.data.pointer = metrics_notification;
14500 wrqu.data.length = strlen(metrics_notification);
14501
14502 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14503
14504 EXIT();
14505
14506 return VOS_STATUS_SUCCESS;
14507}
14508
14509/*
14510 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14511 * 802.11r/LFR metrics reporting function to report handover initiation
14512 *
14513 */
14514VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14515 tCsrRoamInfo *pRoamInfo)
14516{
14517 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14518 union iwreq_data wrqu;
14519
14520 ENTER();
14521
14522 if (NULL == pAdapter)
14523 {
14524 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14525 return VOS_STATUS_E_FAILURE;
14526 }
14527
14528 /* create the event */
14529 memset(&wrqu, 0, sizeof(wrqu));
14530 memset(metrics_notification, 0, sizeof(metrics_notification));
14531
14532 wrqu.data.pointer = metrics_notification;
14533 wrqu.data.length = scnprintf(metrics_notification,
14534 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14535 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14536
14537 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14538
14539 EXIT();
14540
14541 return VOS_STATUS_SUCCESS;
14542}
14543#endif
14544
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014545
14546/**
14547 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14548 * @scan_req: scan request to be checked
14549 *
14550 * Return: true or false
14551 */
14552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14553static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14554 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014555 *scan_req, hdd_context_t
14556 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014557{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014558 if (!scan_req || !scan_req->wiphy ||
14559 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014560 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14561 return false;
14562 }
14563 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14564 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14565 return false;
14566 }
14567 return true;
14568}
14569#else
14570static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14571 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014572 *scan_req, hdd_context_t
14573 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014574{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014575 if (!scan_req || !scan_req->wiphy ||
14576 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014577 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14578 return false;
14579 }
14580 return true;
14581}
14582#endif
14583
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14585/**
14586 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14587 * @adapter: Pointer to the adapter
14588 * @req : Scan request
14589 * @aborted : true scan aborted false scan success
14590 *
14591 * This function notifies scan done to cfg80211
14592 *
14593 * Return: none
14594 */
14595static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14596 struct cfg80211_scan_request *req,
14597 bool aborted)
14598{
14599 struct cfg80211_scan_info info = {
14600 .aborted = aborted
14601 };
14602
14603 if (adapter->dev->flags & IFF_UP)
14604 cfg80211_scan_done(req, &info);
14605 else
14606 hddLog(LOGW,
14607 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14608}
14609#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14610/**
14611 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14612 * @adapter: Pointer to the adapter
14613 * @req : Scan request
14614 * @aborted : true scan aborted false scan success
14615 *
14616 * This function notifies scan done to cfg80211
14617 *
14618 * Return: none
14619 */
14620static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14621 struct cfg80211_scan_request *req,
14622 bool aborted)
14623{
14624 if (adapter->dev->flags & IFF_UP)
14625 cfg80211_scan_done(req, aborted);
14626 else
14627 hddLog(LOGW,
14628 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14629}
14630#else
14631/**
14632 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14633 * @adapter: Pointer to the adapter
14634 * @req : Scan request
14635 * @aborted : true scan aborted false scan success
14636 *
14637 * This function notifies scan done to cfg80211
14638 *
14639 * Return: none
14640 */
14641static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14642 struct cfg80211_scan_request *req,
14643 bool aborted)
14644{
14645 cfg80211_scan_done(req, aborted);
14646}
14647#endif
14648
Mukul Sharmab392b642017-08-17 17:45:29 +053014649#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014650/*
14651 * FUNCTION: hdd_cfg80211_scan_done_callback
14652 * scanning callback function, called after finishing scan
14653 *
14654 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014655static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014656 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14657{
14658 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014659 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014660 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014661 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014662 struct cfg80211_scan_request *req = NULL;
14663 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014664 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014665 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014666 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014667
14668 ENTER();
14669
c_manjee1b4ab9a2016-10-26 11:36:55 +053014670 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14671 !pAdapter->dev) {
14672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14673 return 0;
14674 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014675 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014676 if (NULL == pHddCtx) {
14677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014678 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014679 }
14680
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014681#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014682 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014683 {
14684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014685 }
14686#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014687 pScanInfo = &pHddCtx->scan_info;
14688
Jeff Johnson295189b2012-06-20 16:38:30 -070014689 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014690 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014691 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014692 __func__, halHandle, pContext, (int) scanId, (int) status);
14693
Kiet Lamac06e2c2013-10-23 16:25:07 +053014694 pScanInfo->mScanPendingCounter = 0;
14695
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014697 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 &pScanInfo->scan_req_completion_event,
14699 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014700 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014702 hddLog(VOS_TRACE_LEVEL_ERROR,
14703 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014704 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014705 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014706 }
14707
Yue Maef608272013-04-08 23:09:17 -070014708 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014709 {
14710 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014711 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014712 }
14713
14714 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014715 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014716 {
14717 hddLog(VOS_TRACE_LEVEL_INFO,
14718 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014719 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014720 (int) scanId);
14721 }
14722
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014723#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014724 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014725#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014726 {
14727 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14728 pAdapter);
14729 if (0 > ret)
14730 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014731 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014732
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 /* If any client wait scan result through WEXT
14734 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014735 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014736 {
14737 /* The other scan request waiting for current scan finish
14738 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014739 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014740 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014741 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 }
14743 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014744 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014745 {
14746 struct net_device *dev = pAdapter->dev;
14747 union iwreq_data wrqu;
14748 int we_event;
14749 char *msg;
14750
14751 memset(&wrqu, '\0', sizeof(wrqu));
14752 we_event = SIOCGIWSCAN;
14753 msg = NULL;
14754 wireless_send_event(dev, we_event, &wrqu, msg);
14755 }
14756 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014757 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014758
14759 /* Get the Scan Req */
14760 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014761 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014762
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014763 /* Scan is no longer pending */
14764 pScanInfo->mScanPending = VOS_FALSE;
14765
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014766 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014767 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014770 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014771#endif
14772
14773 if (pAdapter->dev) {
14774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14775 pAdapter->dev->name);
14776 }
mukul sharmae7041822015-12-03 15:09:21 +053014777 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014778 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014779 }
14780
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014781 /* last_scan_timestamp is used to decide if new scan
14782 * is needed or not on station interface. If last station
14783 * scan time and new station scan time is less then
14784 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014785 * Also only last_scan_timestamp is updated here last_scan_channellist
14786 * is updated on receiving scan request itself to make sure kernel
14787 * allocated scan request(scan_req) object is not dereferenced here,
14788 * because interface down, where kernel frees scan_req, may happen any
14789 * time while driver is processing scan_done_callback. So it's better
14790 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014791 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014792 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14793 if (status == eCSR_SCAN_SUCCESS)
14794 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14795 else {
14796 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14797 sizeof(pHddCtx->scan_info.last_scan_channelList));
14798 pHddCtx->scan_info.last_scan_numChannels = 0;
14799 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014800 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014801 }
14802
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014803 /*
14804 * cfg80211_scan_done informing NL80211 about completion
14805 * of scanning
14806 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014807 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14808 {
14809 aborted = true;
14810 }
mukul sharmae7041822015-12-03 15:09:21 +053014811
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014812#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014813 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14814 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014815#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014816 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014817
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014818 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014819
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014820allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014821 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14822 ) && (pHddCtx->spoofMacAddr.isEnabled
14823 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014824 /* Generate new random mac addr for next scan */
14825 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014826
14827 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14828 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014829 }
14830
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014831 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014832 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014833
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014834 /* Acquire wakelock to handle the case where APP's tries to suspend
14835 * immediatly after the driver gets connect request(i.e after scan)
14836 * from supplicant, this result in app's is suspending and not able
14837 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014838 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014839
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014840#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014841 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014842#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014843#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014844 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014845#endif
14846
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 EXIT();
14848 return 0;
14849}
14850
14851/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014852 * FUNCTION: hdd_isConnectionInProgress
14853 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014854 *
14855 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014856v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14857 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014858{
14859 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14860 hdd_station_ctx_t *pHddStaCtx = NULL;
14861 hdd_adapter_t *pAdapter = NULL;
14862 VOS_STATUS status = 0;
14863 v_U8_t staId = 0;
14864 v_U8_t *staMac = NULL;
14865
14866 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14867
14868 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14869 {
14870 pAdapter = pAdapterNode->pAdapter;
14871
14872 if( pAdapter )
14873 {
14874 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014875 "%s: Adapter with device mode %s (%d) exists",
14876 __func__, hdd_device_modetoString(pAdapter->device_mode),
14877 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014878 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014879 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14880 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14881 (eConnectionState_Connecting ==
14882 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14883 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014884 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014885 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014886 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014887 if (session_id && reason)
14888 {
14889 *session_id = pAdapter->sessionId;
14890 *reason = eHDD_CONNECTION_IN_PROGRESS;
14891 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014892 return VOS_TRUE;
14893 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014894 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014895 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014896 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014897 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014898 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014899 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014900 if (session_id && reason)
14901 {
14902 *session_id = pAdapter->sessionId;
14903 *reason = eHDD_REASSOC_IN_PROGRESS;
14904 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014905 return VOS_TRUE;
14906 }
14907 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014908 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14909 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014910 {
14911 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14912 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014913 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014914 {
14915 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014916 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014917 "%s: client " MAC_ADDRESS_STR
14918 " is in the middle of WPS/EAPOL exchange.", __func__,
14919 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014920 if (session_id && reason)
14921 {
14922 *session_id = pAdapter->sessionId;
14923 *reason = eHDD_EAPOL_IN_PROGRESS;
14924 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014925 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014926 }
14927 }
14928 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14929 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14930 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014931 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14932 ptSapContext pSapCtx = NULL;
14933 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14934 if(pSapCtx == NULL){
14935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14936 FL("psapCtx is NULL"));
14937 return VOS_FALSE;
14938 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014939 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14940 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014941 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14942 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014943 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014944 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014945
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014946 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014947 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14948 "middle of WPS/EAPOL exchange.", __func__,
14949 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014950 if (session_id && reason)
14951 {
14952 *session_id = pAdapter->sessionId;
14953 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14954 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014955 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014956 }
14957 }
14958 }
14959 }
14960 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14961 pAdapterNode = pNext;
14962 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014963 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014964}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014965
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014966/**
14967 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14968 * to the Scan request
14969 * @scanRequest: Pointer to the csr scan request
14970 * @request: Pointer to the scan request from supplicant
14971 *
14972 * Return: None
14973 */
14974#ifdef CFG80211_SCAN_BSSID
14975static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14976 struct cfg80211_scan_request *request)
14977{
14978 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14979}
14980#else
14981static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14982 struct cfg80211_scan_request *request)
14983{
14984}
14985#endif
14986
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014987/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014988 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014989 * this scan respond to scan trigger and update cfg80211 scan database
14990 * later, scan dump command can be used to recieve scan results
14991 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014992int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014993#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14994 struct net_device *dev,
14995#endif
14996 struct cfg80211_scan_request *request)
14997{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014998 hdd_adapter_t *pAdapter = NULL;
14999 hdd_context_t *pHddCtx = NULL;
15000 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015001 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015002 tCsrScanRequest scanRequest;
15003 tANI_U8 *channelList = NULL, i;
15004 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015005 int status;
15006 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015007 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015008 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015009 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015010 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015011 v_U8_t curr_session_id;
15012 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015013
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15015 struct net_device *dev = NULL;
15016 if (NULL == request)
15017 {
15018 hddLog(VOS_TRACE_LEVEL_ERROR,
15019 "%s: scan req param null", __func__);
15020 return -EINVAL;
15021 }
15022 dev = request->wdev->netdev;
15023#endif
15024
15025 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15026 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15027 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15028
Jeff Johnson295189b2012-06-20 16:38:30 -070015029 ENTER();
15030
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015031 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15032 __func__, hdd_device_modetoString(pAdapter->device_mode),
15033 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015034
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015035 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015036 if (0 != status)
15037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015038 return status;
15039 }
15040
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015041 if (NULL == pwextBuf)
15042 {
15043 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15044 __func__);
15045 return -EIO;
15046 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015047 cfg_param = pHddCtx->cfg_ini;
15048 pScanInfo = &pHddCtx->scan_info;
15049
Jeff Johnson295189b2012-06-20 16:38:30 -070015050#ifdef WLAN_BTAMP_FEATURE
15051 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015052 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015053 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015054 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015055 "%s: No scanning when AMP is on", __func__);
15056 return -EOPNOTSUPP;
15057 }
15058#endif
15059 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015060 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015061 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015062 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015063 "%s: Not scanning on device_mode = %s (%d)",
15064 __func__, hdd_device_modetoString(pAdapter->device_mode),
15065 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015066 return -EOPNOTSUPP;
15067 }
15068
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015069 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15070 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15071 return -EOPNOTSUPP;
15072 }
15073
Jeff Johnson295189b2012-06-20 16:38:30 -070015074 if (TRUE == pScanInfo->mScanPending)
15075 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015076 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15077 {
15078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15079 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015080 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015081 }
15082
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015083 // Don't allow scan if PNO scan is going on.
15084 if (pHddCtx->isPnoEnable)
15085 {
15086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15087 FL("pno scan in progress"));
15088 return -EBUSY;
15089 }
15090
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015091 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015092 //Channel and action frame is pending
15093 //Otherwise Cancel Remain On Channel and allow Scan
15094 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015095 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015096 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015098 return -EBUSY;
15099 }
15100
Jeff Johnson295189b2012-06-20 16:38:30 -070015101 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15102 {
15103 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015104 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015105 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015106 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015107 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15108 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015109 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015110 "%s: MAX TM Level Scan not allowed", __func__);
15111 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015112 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015113 }
15114 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15115
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015116 /* Check if scan is allowed at this point of time.
15117 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015118 if (TRUE == pHddCtx->btCoexModeSet)
15119 {
15120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15121 FL("BTCoex Mode operation in progress"));
15122 return -EBUSY;
15123 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015124 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015125 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015126
15127 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15128 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15129 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015130 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15131 pHddCtx->last_scan_reject_reason != curr_reason ||
15132 !pHddCtx->last_scan_reject_timestamp)
15133 {
15134 pHddCtx->last_scan_reject_session_id = curr_session_id;
15135 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015136 pHddCtx->last_scan_reject_timestamp =
15137 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015138 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015139 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015140 else
15141 {
15142 pHddCtx->scan_reject_cnt++;
15143
Abhishek Singhe4b12562017-06-20 16:53:39 +053015144 if ((pHddCtx->scan_reject_cnt >=
15145 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015146 vos_system_time_after(jiffies_to_msecs(jiffies),
15147 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015148 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015149 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15150 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15151 vos_system_time_after(jiffies_to_msecs(jiffies),
15152 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015153 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015154 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015155 if (pHddCtx->cfg_ini->enableFatalEvent)
15156 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15157 WLAN_LOG_INDICATOR_HOST_DRIVER,
15158 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15159 FALSE, FALSE);
15160 else
15161 {
15162 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015163 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015164 }
15165 }
15166 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015167 return -EBUSY;
15168 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015169 pHddCtx->last_scan_reject_timestamp = 0;
15170 pHddCtx->last_scan_reject_session_id = 0xFF;
15171 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015172 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015173
Jeff Johnson295189b2012-06-20 16:38:30 -070015174 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15175
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015176 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15177 * Becasue of this, driver is assuming that this is not wildcard scan and so
15178 * is not aging out the scan results.
15179 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015180 if ((request->ssids) && (request->n_ssids == 1) &&
15181 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015182 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015183 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015184
15185 if ((request->ssids) && (0 < request->n_ssids))
15186 {
15187 tCsrSSIDInfo *SsidInfo;
15188 int j;
15189 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15190 /* Allocate num_ssid tCsrSSIDInfo structure */
15191 SsidInfo = scanRequest.SSIDs.SSIDList =
15192 ( tCsrSSIDInfo *)vos_mem_malloc(
15193 request->n_ssids*sizeof(tCsrSSIDInfo));
15194
15195 if(NULL == scanRequest.SSIDs.SSIDList)
15196 {
15197 hddLog(VOS_TRACE_LEVEL_ERROR,
15198 "%s: memory alloc failed SSIDInfo buffer", __func__);
15199 return -ENOMEM;
15200 }
15201
15202 /* copy all the ssid's and their length */
15203 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15204 {
15205 /* get the ssid length */
15206 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15207 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15208 SsidInfo->SSID.length);
15209 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15210 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15211 j, SsidInfo->SSID.ssId);
15212 }
15213 /* set the scan type to active */
15214 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15215 }
15216 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015217 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015218 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15219 TRACE_CODE_HDD_CFG80211_SCAN,
15220 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 /* set the scan type to active */
15222 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015223 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015224 else
15225 {
15226 /*Set the scan type to default type, in this case it is ACTIVE*/
15227 scanRequest.scanType = pScanInfo->scan_mode;
15228 }
15229 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15230 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015231
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015232 csr_scan_request_assign_bssid(&scanRequest, request);
15233
Jeff Johnson295189b2012-06-20 16:38:30 -070015234 /* set BSSType to default type */
15235 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15236
15237 /*TODO: scan the requested channels only*/
15238
15239 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015240 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015241 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015242 hddLog(VOS_TRACE_LEVEL_WARN,
15243 "No of Scan Channels exceeded limit: %d", request->n_channels);
15244 request->n_channels = MAX_CHANNEL;
15245 }
15246
15247 hddLog(VOS_TRACE_LEVEL_INFO,
15248 "No of Scan Channels: %d", request->n_channels);
15249
15250
15251 if( request->n_channels )
15252 {
15253 char chList [(request->n_channels*5)+1];
15254 int len;
15255 channelList = vos_mem_malloc( request->n_channels );
15256 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015257 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015258 hddLog(VOS_TRACE_LEVEL_ERROR,
15259 "%s: memory alloc failed channelList", __func__);
15260 status = -ENOMEM;
15261 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015262 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015263
15264 for( i = 0, len = 0; i < request->n_channels ; i++ )
15265 {
15266 channelList[i] = request->channels[i]->hw_value;
15267 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15268 }
15269
Nirav Shah20ac06f2013-12-12 18:14:06 +053015270 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015271 "Channel-List: %s ", chList);
15272 }
c_hpothu53512302014-04-15 18:49:53 +053015273
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015274 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15275 scanRequest.ChannelInfo.ChannelList = channelList;
15276
15277 /* set requestType to full scan */
15278 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15279
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015280 /* if there is back to back scan happening in driver with in
15281 * nDeferScanTimeInterval interval driver should defer new scan request
15282 * and should provide last cached scan results instead of new channel list.
15283 * This rule is not applicable if scan is p2p scan.
15284 * This condition will work only in case when last request no of channels
15285 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015286 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015287 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015288 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015289
Sushant Kaushik86592172015-04-27 16:35:03 +053015290 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15291 /* if wps ie is NULL , then only defer scan */
15292 if ( pWpsIe == NULL &&
15293 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015294 {
15295 if ( pScanInfo->last_scan_timestamp !=0 &&
15296 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15297 {
15298 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15299 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15300 vos_mem_compare(pScanInfo->last_scan_channelList,
15301 channelList, pScanInfo->last_scan_numChannels))
15302 {
15303 hddLog(VOS_TRACE_LEVEL_WARN,
15304 " New and old station scan time differ is less then %u",
15305 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15306
15307 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015308 pAdapter);
15309
Agarwal Ashish57e84372014-12-05 18:26:53 +053015310 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015311 "Return old cached scan as all channels and no of channels are same");
15312
Agarwal Ashish57e84372014-12-05 18:26:53 +053015313 if (0 > ret)
15314 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015315
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015316 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015317
15318 status = eHAL_STATUS_SUCCESS;
15319 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015320 }
15321 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015322 }
15323
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015324 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15325 * search (Flush on both full scan and social scan but not on single
15326 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15327 */
15328
15329 /* Supplicant does single channel scan after 8-way handshake
15330 * and in that case driver shoudnt flush scan results. If
15331 * driver flushes the scan results here and unfortunately if
15332 * the AP doesnt respond to our probe req then association
15333 * fails which is not desired
15334 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015335 if ((request->n_ssids == 1)
15336 && (request->ssids != NULL)
15337 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15338 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015339
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015340 if( is_p2p_scan ||
15341 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015342 {
15343 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15344 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15345 pAdapter->sessionId );
15346 }
15347
15348 if( request->ie_len )
15349 {
15350 /* save this for future association (join requires this) */
15351 /*TODO: Array needs to be converted to dynamic allocation,
15352 * as multiple ie.s can be sent in cfg80211_scan_request structure
15353 * CR 597966
15354 */
15355 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15356 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15357 pScanInfo->scanAddIE.length = request->ie_len;
15358
15359 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15360 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15361 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015362 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015363 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015364 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015365 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15366 memcpy( pwextBuf->roamProfile.addIEScan,
15367 request->ie, request->ie_len);
15368 }
15369 else
15370 {
15371 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15372 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015373 }
15374
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015375 }
15376 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15377 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15378
15379 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15380 request->ie_len);
15381 if (pP2pIe != NULL)
15382 {
15383#ifdef WLAN_FEATURE_P2P_DEBUG
15384 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15385 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15386 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015387 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015388 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15389 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15390 "Go nego completed to Connection is started");
15391 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15392 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015393 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015394 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15395 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015396 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015397 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15398 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15399 "Disconnected state to Connection is started");
15400 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15401 "for 4way Handshake");
15402 }
15403#endif
15404
15405 /* no_cck will be set during p2p find to disable 11b rates */
15406 if(TRUE == request->no_cck)
15407 {
15408 hddLog(VOS_TRACE_LEVEL_INFO,
15409 "%s: This is a P2P Search", __func__);
15410 scanRequest.p2pSearch = 1;
15411
15412 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015413 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015414 /* set requestType to P2P Discovery */
15415 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15416 }
15417
15418 /*
15419 Skip Dfs Channel in case of P2P Search
15420 if it is set in ini file
15421 */
15422 if(cfg_param->skipDfsChnlInP2pSearch)
15423 {
15424 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015425 }
15426 else
15427 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015428 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015429 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015430
Agarwal Ashish4f616132013-12-30 23:32:50 +053015431 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015432 }
15433 }
15434
15435 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15436
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015437#ifdef FEATURE_WLAN_TDLS
15438 /* if tdls disagree scan right now, return immediately.
15439 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15440 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15441 */
15442 status = wlan_hdd_tdls_scan_callback (pAdapter,
15443 wiphy,
15444#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15445 dev,
15446#endif
15447 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015448 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015449 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015450 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15452 "scan rejected %d", __func__, status);
15453 else
15454 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15455 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015456 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015457 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015458 }
15459#endif
15460
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015461 /* acquire the wakelock to avoid the apps suspend during the scan. To
15462 * address the following issues.
15463 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15464 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15465 * for long time, this result in apps running at full power for long time.
15466 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15467 * be stuck in full power because of resume BMPS
15468 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015469 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015470
Nirav Shah20ac06f2013-12-12 18:14:06 +053015471 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15472 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015473 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15474 scanRequest.requestType, scanRequest.scanType,
15475 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015476 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15477
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015478 if (pHddCtx->spoofMacAddr.isEnabled &&
15479 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015480 {
15481 hddLog(VOS_TRACE_LEVEL_INFO,
15482 "%s: MAC Spoofing enabled for current scan", __func__);
15483 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15484 * to fill TxBds for probe request during current scan
15485 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015486 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015487 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015488
15489 if(status != VOS_STATUS_SUCCESS)
15490 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015491 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015492 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015493#ifdef FEATURE_WLAN_TDLS
15494 wlan_hdd_tdls_scan_done_callback(pAdapter);
15495#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015496 goto free_mem;
15497 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015498 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015499 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015500 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015501 pAdapter->sessionId, &scanRequest, &scanId,
15502 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015503
Jeff Johnson295189b2012-06-20 16:38:30 -070015504 if (eHAL_STATUS_SUCCESS != status)
15505 {
15506 hddLog(VOS_TRACE_LEVEL_ERROR,
15507 "%s: sme_ScanRequest returned error %d", __func__, status);
15508 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015509 if(eHAL_STATUS_RESOURCES == status)
15510 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15512 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015513 status = -EBUSY;
15514 } else {
15515 status = -EIO;
15516 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015517 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015518
15519#ifdef FEATURE_WLAN_TDLS
15520 wlan_hdd_tdls_scan_done_callback(pAdapter);
15521#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015522 goto free_mem;
15523 }
15524
15525 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015526 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 pAdapter->request = request;
15528 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015529 pScanInfo->no_cck = request->no_cck;
15530 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15531 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15532 pHddCtx->scan_info.last_scan_channelList[i] =
15533 request->channels[i]->hw_value;
15534 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015535
15536 complete(&pScanInfo->scan_req_completion_event);
15537
15538free_mem:
15539 if( scanRequest.SSIDs.SSIDList )
15540 {
15541 vos_mem_free(scanRequest.SSIDs.SSIDList);
15542 }
15543
15544 if( channelList )
15545 vos_mem_free( channelList );
15546
15547 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015548 return status;
15549}
15550
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015551int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15552#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15553 struct net_device *dev,
15554#endif
15555 struct cfg80211_scan_request *request)
15556{
15557 int ret;
15558
15559 vos_ssr_protect(__func__);
15560 ret = __wlan_hdd_cfg80211_scan(wiphy,
15561#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15562 dev,
15563#endif
15564 request);
15565 vos_ssr_unprotect(__func__);
15566
15567 return ret;
15568}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015569
15570void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15571{
15572 v_U8_t iniDot11Mode =
15573 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15574 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15575
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015576 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15577 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015578 switch ( iniDot11Mode )
15579 {
15580 case eHDD_DOT11_MODE_AUTO:
15581 case eHDD_DOT11_MODE_11ac:
15582 case eHDD_DOT11_MODE_11ac_ONLY:
15583#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015584 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15585 sme_IsFeatureSupportedByFW(DOT11AC) )
15586 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15587 else
15588 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015589#else
15590 hddDot11Mode = eHDD_DOT11_MODE_11n;
15591#endif
15592 break;
15593 case eHDD_DOT11_MODE_11n:
15594 case eHDD_DOT11_MODE_11n_ONLY:
15595 hddDot11Mode = eHDD_DOT11_MODE_11n;
15596 break;
15597 default:
15598 hddDot11Mode = iniDot11Mode;
15599 break;
15600 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015601#ifdef WLAN_FEATURE_AP_HT40_24G
15602 if (operationChannel > SIR_11B_CHANNEL_END)
15603#endif
15604 {
15605 /* This call decides required channel bonding mode */
15606 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015607 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015608 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015609 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015610}
15611
Jeff Johnson295189b2012-06-20 16:38:30 -070015612/*
15613 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015614 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015615 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015616int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015617 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15618 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015619{
15620 int status = 0;
15621 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015622 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015623 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015624 v_U32_t roamId;
15625 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015626 eCsrAuthType RSNAuthType;
15627
15628 ENTER();
15629
15630 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015631 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015632 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015633
15634 status = wlan_hdd_validate_context(pHddCtx);
15635 if (status)
15636 {
Yue Mae36e3552014-03-05 17:06:20 -080015637 return status;
15638 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015639
Jeff Johnson295189b2012-06-20 16:38:30 -070015640 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15641 {
15642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15643 return -EINVAL;
15644 }
15645
Nitesh Shah9b066282017-06-06 18:05:52 +053015646 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15647
Jeff Johnson295189b2012-06-20 16:38:30 -070015648 pRoamProfile = &pWextState->roamProfile;
15649
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015650 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015651 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015652 hdd_station_ctx_t *pHddStaCtx;
15653 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015654 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015655
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015656 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15657
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015658 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015659 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15660 {
15661 /*QoS not enabled in cfg file*/
15662 pRoamProfile->uapsd_mask = 0;
15663 }
15664 else
15665 {
15666 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015667 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015668 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15669 }
15670
15671 pRoamProfile->SSIDs.numOfSSIDs = 1;
15672 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15673 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015674 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015675 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15676 ssid, ssid_len);
15677
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015678 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15679 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15680
Jeff Johnson295189b2012-06-20 16:38:30 -070015681 if (bssid)
15682 {
15683 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015684 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015685 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015686 /* Save BSSID in seperate variable as well, as RoamProfile
15687 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015688 case of join failure we should send valid BSSID to supplicant
15689 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015690 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015691 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015692
Jeff Johnson295189b2012-06-20 16:38:30 -070015693 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015694 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015695 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015696 /* Store bssid_hint to use in the scan filter. */
15697 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15698 WNI_CFG_BSSID_LEN);
15699 /*
15700 * Save BSSID in seperate variable as well, as RoamProfile
15701 * BSSID is getting zeroed out in the association process. And in
15702 * case of join failure we should send valid BSSID to supplicant
15703 */
15704 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15705 WNI_CFG_BSSID_LEN);
15706 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15707 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015708 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015709
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015710
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015711 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15712 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015713 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15714 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015715 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015716 /*set gen ie*/
15717 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15718 /*set auth*/
15719 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15720 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015721#ifdef FEATURE_WLAN_WAPI
15722 if (pAdapter->wapi_info.nWapiMode)
15723 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015724 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015725 switch (pAdapter->wapi_info.wapiAuthMode)
15726 {
15727 case WAPI_AUTH_MODE_PSK:
15728 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015729 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015730 pAdapter->wapi_info.wapiAuthMode);
15731 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15732 break;
15733 }
15734 case WAPI_AUTH_MODE_CERT:
15735 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015736 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015737 pAdapter->wapi_info.wapiAuthMode);
15738 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15739 break;
15740 }
15741 } // End of switch
15742 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15743 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15744 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015745 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015746 pRoamProfile->AuthType.numEntries = 1;
15747 pRoamProfile->EncryptionType.numEntries = 1;
15748 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15749 pRoamProfile->mcEncryptionType.numEntries = 1;
15750 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15751 }
15752 }
15753#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015754#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015755 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015756 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15757 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15758 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015759 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15760 sizeof (tSirGtkOffloadParams));
15761 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015762 }
15763#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015764 pRoamProfile->csrPersona = pAdapter->device_mode;
15765
Jeff Johnson32d95a32012-09-10 13:15:23 -070015766 if( operatingChannel )
15767 {
15768 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15769 pRoamProfile->ChannelInfo.numOfChannels = 1;
15770 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015771 else
15772 {
15773 pRoamProfile->ChannelInfo.ChannelList = NULL;
15774 pRoamProfile->ChannelInfo.numOfChannels = 0;
15775 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015776 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15777 {
15778 hdd_select_cbmode(pAdapter,operatingChannel);
15779 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015780
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015781 /*
15782 * Change conn_state to connecting before sme_RoamConnect(),
15783 * because sme_RoamConnect() has a direct path to call
15784 * hdd_smeRoamCallback(), which will change the conn_state
15785 * If direct path, conn_state will be accordingly changed
15786 * to NotConnected or Associated by either
15787 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15788 * in sme_RoamCallback()
15789 * if sme_RomConnect is to be queued,
15790 * Connecting state will remain until it is completed.
15791 * If connection state is not changed,
15792 * connection state will remain in eConnectionState_NotConnected state.
15793 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15794 * if conn state is eConnectionState_NotConnected.
15795 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15796 * informed of connect result indication which is an issue.
15797 */
15798
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015799 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15800 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015801 {
15802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015803 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015804 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15805 eConnectionState_Connecting);
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015806 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
15807 hdd_wait_for_ecsa_complete(pHddCtx);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015808 }
Abhishek Singh10e17cf2018-03-12 14:34:22 +053015809
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015810 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015811 pAdapter->sessionId, pRoamProfile, &roamId);
15812
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015813 if ((eHAL_STATUS_SUCCESS != status) &&
15814 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15815 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015816
15817 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015818 hddLog(VOS_TRACE_LEVEL_ERROR,
15819 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15820 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015821 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015822 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015823 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015824 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015825
15826 pRoamProfile->ChannelInfo.ChannelList = NULL;
15827 pRoamProfile->ChannelInfo.numOfChannels = 0;
15828
Jeff Johnson295189b2012-06-20 16:38:30 -070015829 }
15830 else
15831 {
15832 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15833 return -EINVAL;
15834 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015835 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015836 return status;
15837}
15838
15839/*
15840 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15841 * This function is used to set the authentication type (OPEN/SHARED).
15842 *
15843 */
15844static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15845 enum nl80211_auth_type auth_type)
15846{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015847 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015848 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15849
15850 ENTER();
15851
15852 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015853 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015854 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015855 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015856 hddLog(VOS_TRACE_LEVEL_INFO,
15857 "%s: set authentication type to AUTOSWITCH", __func__);
15858 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15859 break;
15860
15861 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015862#ifdef WLAN_FEATURE_VOWIFI_11R
15863 case NL80211_AUTHTYPE_FT:
15864#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015865 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015866 "%s: set authentication type to OPEN", __func__);
15867 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15868 break;
15869
15870 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015871 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015872 "%s: set authentication type to SHARED", __func__);
15873 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15874 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015875#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015876 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015877 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015878 "%s: set authentication type to CCKM WPA", __func__);
15879 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15880 break;
15881#endif
15882
15883
15884 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015885 hddLog(VOS_TRACE_LEVEL_ERROR,
15886 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015887 auth_type);
15888 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15889 return -EINVAL;
15890 }
15891
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015892 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015893 pHddStaCtx->conn_info.authType;
15894 return 0;
15895}
15896
15897/*
15898 * FUNCTION: wlan_hdd_set_akm_suite
15899 * This function is used to set the key mgmt type(PSK/8021x).
15900 *
15901 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015902static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015903 u32 key_mgmt
15904 )
15905{
15906 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15907 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015908 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015909#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015910#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015911#endif
15912#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015913#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015914#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015915 /*set key mgmt type*/
15916 switch(key_mgmt)
15917 {
15918 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015919 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015920#ifdef WLAN_FEATURE_VOWIFI_11R
15921 case WLAN_AKM_SUITE_FT_PSK:
15922#endif
15923 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015924 __func__);
15925 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15926 break;
15927
15928 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015929 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015930#ifdef WLAN_FEATURE_VOWIFI_11R
15931 case WLAN_AKM_SUITE_FT_8021X:
15932#endif
15933 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015934 __func__);
15935 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15936 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015937#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015938#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15939#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15940 case WLAN_AKM_SUITE_CCKM:
15941 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15942 __func__);
15943 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15944 break;
15945#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015946#ifndef WLAN_AKM_SUITE_OSEN
15947#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15948 case WLAN_AKM_SUITE_OSEN:
15949 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15950 __func__);
15951 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15952 break;
15953#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015954
15955 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015957 __func__, key_mgmt);
15958 return -EINVAL;
15959
15960 }
15961 return 0;
15962}
15963
15964/*
15965 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015966 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015967 * (NONE/WEP40/WEP104/TKIP/CCMP).
15968 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015969static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15970 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015971 bool ucast
15972 )
15973{
15974 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015975 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015976 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15977
15978 ENTER();
15979
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015980 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015981 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015982 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015983 __func__, cipher);
15984 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15985 }
15986 else
15987 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015988
Jeff Johnson295189b2012-06-20 16:38:30 -070015989 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015990 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015991 {
15992 case IW_AUTH_CIPHER_NONE:
15993 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15994 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015995
Jeff Johnson295189b2012-06-20 16:38:30 -070015996 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015997 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015998 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015999
Jeff Johnson295189b2012-06-20 16:38:30 -070016000 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053016001 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016003
Jeff Johnson295189b2012-06-20 16:38:30 -070016004 case WLAN_CIPHER_SUITE_TKIP:
16005 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16006 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016007
Jeff Johnson295189b2012-06-20 16:38:30 -070016008 case WLAN_CIPHER_SUITE_CCMP:
16009 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16010 break;
16011#ifdef FEATURE_WLAN_WAPI
16012 case WLAN_CIPHER_SUITE_SMS4:
16013 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16014 break;
16015#endif
16016
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016017#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 case WLAN_CIPHER_SUITE_KRK:
16019 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16020 break;
16021#endif
16022 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016023 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016024 __func__, cipher);
16025 return -EOPNOTSUPP;
16026 }
16027 }
16028
16029 if (ucast)
16030 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016031 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016032 __func__, encryptionType);
16033 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16034 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016035 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016036 encryptionType;
16037 }
16038 else
16039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016040 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016041 __func__, encryptionType);
16042 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16043 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16044 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16045 }
16046
16047 return 0;
16048}
16049
16050
16051/*
16052 * FUNCTION: wlan_hdd_cfg80211_set_ie
16053 * This function is used to parse WPA/RSN IE's.
16054 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016055int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016056#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16057 const u8 *ie,
16058#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016059 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016060#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016061 size_t ie_len
16062 )
16063{
16064 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16066 const u8 *genie = ie;
16067#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016068 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016069#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016070 v_U16_t remLen = ie_len;
16071#ifdef FEATURE_WLAN_WAPI
16072 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16073 u16 *tmp;
16074 v_U16_t akmsuiteCount;
16075 int *akmlist;
16076#endif
16077 ENTER();
16078
16079 /* clear previous assocAddIE */
16080 pWextState->assocAddIE.length = 0;
16081 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016082 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016083
16084 while (remLen >= 2)
16085 {
16086 v_U16_t eLen = 0;
16087 v_U8_t elementId;
16088 elementId = *genie++;
16089 eLen = *genie++;
16090 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016091
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016092 /* Sanity check on eLen */
16093 if (eLen > remLen) {
16094 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16095 __func__, eLen, elementId);
16096 VOS_ASSERT(0);
16097 return -EINVAL;
16098 }
16099
Arif Hussain6d2a3322013-11-17 19:50:10 -080016100 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016101 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016102
16103 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016104 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016105 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016106 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 -070016107 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016108 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016109 "%s: Invalid WPA IE", __func__);
16110 return -EINVAL;
16111 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016112 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016113 {
16114 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016115 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016116 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016117
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016118 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016119 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016120 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16121 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016122 VOS_ASSERT(0);
16123 return -ENOMEM;
16124 }
16125 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16126 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16127 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016128
Jeff Johnson295189b2012-06-20 16:38:30 -070016129 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16130 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16131 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16132 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016133 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16134 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016135 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16136 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16137 __func__, eLen);
16138 VOS_ASSERT(0);
16139 return -EINVAL;
16140 }
16141
Jeff Johnson295189b2012-06-20 16:38:30 -070016142 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16143 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16144 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16145 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16146 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16147 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016148 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016149 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016150 {
16151 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016152 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016153 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016154
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016155 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016156 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016157 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16158 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016159 VOS_ASSERT(0);
16160 return -ENOMEM;
16161 }
16162 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16163 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16164 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016165
Jeff Johnson295189b2012-06-20 16:38:30 -070016166 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16167 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16168 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016169#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016170 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16171 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016172 /*Consider WFD IE, only for P2P Client */
16173 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16174 {
16175 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016176 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016177 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016178
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016179 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016180 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016181 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16182 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016183 VOS_ASSERT(0);
16184 return -ENOMEM;
16185 }
16186 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16187 // WPS IE + P2P IE + WFD IE
16188 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16189 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016190
Jeff Johnson295189b2012-06-20 16:38:30 -070016191 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16192 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16193 }
16194#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016195 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016196 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016197 HS20_OUI_TYPE_SIZE)) )
16198 {
16199 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016200 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016201 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016202
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016203 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016204 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016205 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16206 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016207 VOS_ASSERT(0);
16208 return -ENOMEM;
16209 }
16210 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16211 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016212
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016213 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16214 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16215 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016216 /* Appending OSEN Information Element in Assiciation Request */
16217 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16218 OSEN_OUI_TYPE_SIZE)) )
16219 {
16220 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16221 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16222 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016223
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016224 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016225 {
16226 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16227 "Need bigger buffer space");
16228 VOS_ASSERT(0);
16229 return -ENOMEM;
16230 }
16231 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16232 pWextState->assocAddIE.length += eLen + 2;
16233
16234 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16235 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16236 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16237 }
16238
Abhishek Singh4322e622015-06-10 15:42:54 +053016239 /* Update only for WPA IE */
16240 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16241 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016242
16243 /* populating as ADDIE in beacon frames */
16244 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016245 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016246 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16247 {
16248 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16249 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16250 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16251 {
16252 hddLog(LOGE,
16253 "Coldn't pass "
16254 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16255 }
16256 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16257 else
16258 hddLog(LOGE,
16259 "Could not pass on "
16260 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16261
16262 /* IBSS mode doesn't contain params->proberesp_ies still
16263 beaconIE's need to be populated in probe response frames */
16264 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16265 {
16266 u16 rem_probe_resp_ie_len = eLen + 2;
16267 u8 probe_rsp_ie_len[3] = {0};
16268 u8 counter = 0;
16269
16270 /* Check Probe Resp Length if it is greater then 255 then
16271 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16272 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16273 not able Store More then 255 bytes into One Variable */
16274
16275 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16276 {
16277 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16278 {
16279 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16280 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16281 }
16282 else
16283 {
16284 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16285 rem_probe_resp_ie_len = 0;
16286 }
16287 }
16288
16289 rem_probe_resp_ie_len = 0;
16290
16291 if (probe_rsp_ie_len[0] > 0)
16292 {
16293 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16294 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16295 (tANI_U8*)(genie - 2),
16296 probe_rsp_ie_len[0], NULL,
16297 eANI_BOOLEAN_FALSE)
16298 == eHAL_STATUS_FAILURE)
16299 {
16300 hddLog(LOGE,
16301 "Could not pass"
16302 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16303 }
16304 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16305 }
16306
16307 if (probe_rsp_ie_len[1] > 0)
16308 {
16309 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16310 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16311 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16312 probe_rsp_ie_len[1], NULL,
16313 eANI_BOOLEAN_FALSE)
16314 == eHAL_STATUS_FAILURE)
16315 {
16316 hddLog(LOGE,
16317 "Could not pass"
16318 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16319 }
16320 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16321 }
16322
16323 if (probe_rsp_ie_len[2] > 0)
16324 {
16325 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16326 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16327 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16328 probe_rsp_ie_len[2], NULL,
16329 eANI_BOOLEAN_FALSE)
16330 == eHAL_STATUS_FAILURE)
16331 {
16332 hddLog(LOGE,
16333 "Could not pass"
16334 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16335 }
16336 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16337 }
16338
16339 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16340 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16341 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16342 {
16343 hddLog(LOGE,
16344 "Could not pass"
16345 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16346 }
16347 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016348 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016349 break;
16350 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016351 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16352 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16353 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16354 VOS_ASSERT(0);
16355 return -EINVAL;
16356 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016357 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16358 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16359 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16360 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16361 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16362 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016363
Abhishek Singhb16f3562016-01-20 11:08:32 +053016364 /* Appending extended capabilities with Interworking or
16365 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016366 *
16367 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016368 * interworkingService or bsstransition bit is set to 1.
16369 * Driver is only interested in interworkingService and
16370 * bsstransition capability from supplicant.
16371 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016372 * required from supplicat, it needs to be handled while
16373 * sending Assoc Req in LIM.
16374 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016375 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016376 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016377 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016378 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016379 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016380
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016381 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016382 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016383 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16384 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016385 VOS_ASSERT(0);
16386 return -ENOMEM;
16387 }
16388 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16389 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016390
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016391 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16392 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16393 break;
16394 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016395#ifdef FEATURE_WLAN_WAPI
16396 case WLAN_EID_WAPI:
16397 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016398 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016399 pAdapter->wapi_info.nWapiMode);
16400 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016401 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016402 akmsuiteCount = WPA_GET_LE16(tmp);
16403 tmp = tmp + 1;
16404 akmlist = (int *)(tmp);
16405 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16406 {
16407 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16408 }
16409 else
16410 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016411 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016412 VOS_ASSERT(0);
16413 return -EINVAL;
16414 }
16415
16416 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16417 {
16418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016419 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016420 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016422 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016423 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016424 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016425 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016426 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
16427 }
16428 break;
16429#endif
16430 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016431 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016432 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016433 /* when Unknown IE is received we should break and continue
16434 * to the next IE in the buffer instead we were returning
16435 * so changing this to break */
16436 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016437 }
16438 genie += eLen;
16439 remLen -= eLen;
16440 }
16441 EXIT();
16442 return 0;
16443}
16444
16445/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016446 * FUNCTION: hdd_isWPAIEPresent
16447 * Parse the received IE to find the WPA IE
16448 *
16449 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016450static bool hdd_isWPAIEPresent(
16451#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16452 const u8 *ie,
16453#else
16454 u8 *ie,
16455#endif
16456 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016457{
16458 v_U8_t eLen = 0;
16459 v_U16_t remLen = ie_len;
16460 v_U8_t elementId = 0;
16461
16462 while (remLen >= 2)
16463 {
16464 elementId = *ie++;
16465 eLen = *ie++;
16466 remLen -= 2;
16467 if (eLen > remLen)
16468 {
16469 hddLog(VOS_TRACE_LEVEL_ERROR,
16470 "%s: IE length is wrong %d", __func__, eLen);
16471 return FALSE;
16472 }
16473 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16474 {
16475 /* OUI - 0x00 0X50 0XF2
16476 WPA Information Element - 0x01
16477 WPA version - 0x01*/
16478 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16479 return TRUE;
16480 }
16481 ie += eLen;
16482 remLen -= eLen;
16483 }
16484 return FALSE;
16485}
16486
16487/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016488 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016489 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016490 * parameters during connect operation.
16491 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016492int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016493 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016494 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016495{
16496 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016497 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016498 ENTER();
16499
16500 /*set wpa version*/
16501 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16502
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016503 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016504 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016505 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016506 {
16507 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16508 }
16509 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16510 {
16511 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16512 }
16513 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016514
16515 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016516 pWextState->wpaVersion);
16517
16518 /*set authentication type*/
16519 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16520
16521 if (0 > status)
16522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016523 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016524 "%s: failed to set authentication type ", __func__);
16525 return status;
16526 }
16527
16528 /*set key mgmt type*/
16529 if (req->crypto.n_akm_suites)
16530 {
16531 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16532 if (0 > status)
16533 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016534 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016535 __func__);
16536 return status;
16537 }
16538 }
16539
16540 /*set pairwise cipher type*/
16541 if (req->crypto.n_ciphers_pairwise)
16542 {
16543 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16544 req->crypto.ciphers_pairwise[0], true);
16545 if (0 > status)
16546 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016547 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016548 "%s: failed to set unicast cipher type", __func__);
16549 return status;
16550 }
16551 }
16552 else
16553 {
16554 /*Reset previous cipher suite to none*/
16555 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16556 if (0 > status)
16557 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016558 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016559 "%s: failed to set unicast cipher type", __func__);
16560 return status;
16561 }
16562 }
16563
16564 /*set group cipher type*/
16565 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16566 false);
16567
16568 if (0 > status)
16569 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016571 __func__);
16572 return status;
16573 }
16574
Chet Lanctot186b5732013-03-18 10:26:30 -070016575#ifdef WLAN_FEATURE_11W
16576 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16577#endif
16578
Jeff Johnson295189b2012-06-20 16:38:30 -070016579 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16580 if (req->ie_len)
16581 {
16582 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16583 if ( 0 > status)
16584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016586 __func__);
16587 return status;
16588 }
16589 }
16590
16591 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016592 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016593 {
16594 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16595 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16596 )
16597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016598 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016599 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016602 __func__);
16603 return -EOPNOTSUPP;
16604 }
16605 else
16606 {
16607 u8 key_len = req->key_len;
16608 u8 key_idx = req->key_idx;
16609
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016610 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016611 && (CSR_MAX_NUM_KEY > key_idx)
16612 )
16613 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016614 hddLog(VOS_TRACE_LEVEL_INFO,
16615 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016616 __func__, key_idx, key_len);
16617 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016618 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016619 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016620 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016621 (u8)key_len;
16622 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16623 }
16624 }
16625 }
16626 }
16627
16628 return status;
16629}
16630
16631/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016632 * FUNCTION: wlan_hdd_try_disconnect
16633 * This function is used to disconnect from previous
16634 * connection
16635 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016636int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016637{
16638 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016639 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016640 hdd_station_ctx_t *pHddStaCtx;
16641 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016642 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016643
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016644 ret = wlan_hdd_validate_context(pHddCtx);
16645 if (0 != ret)
16646 {
16647 return ret;
16648 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016649 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16650
16651 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16652
16653 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16654 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016655 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016656 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16657 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016658 /* Indicate disconnect to SME so that in-progress connection or preauth
16659 * can be aborted
16660 */
16661 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16662 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016663 spin_lock_bh(&pAdapter->lock_for_active_session);
16664 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16665 {
16666 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16667 }
16668 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016669 hdd_connSetConnectionState(pHddStaCtx,
16670 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016671 /* Issue disconnect to CSR */
16672 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016673 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016674 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016675 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16676 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16677 hddLog(LOG1,
16678 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16679 } else if ( 0 != status ) {
16680 hddLog(LOGE,
16681 FL("csrRoamDisconnect failure, returned %d"),
16682 (int)status );
16683 result = -EINVAL;
16684 goto disconnected;
16685 }
16686 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016687 &pAdapter->disconnect_comp_var,
16688 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016689 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16690 hddLog(LOGE,
16691 "%s: Failed to disconnect, timed out", __func__);
16692 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016693 }
16694 }
16695 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16696 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016697 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016698 &pAdapter->disconnect_comp_var,
16699 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016700 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016701 {
16702 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016703 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016704 }
16705 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016706disconnected:
16707 hddLog(LOG1,
16708 FL("Set HDD connState to eConnectionState_NotConnected"));
16709 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16710 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016711}
16712
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016713/**
16714 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16715 * @adapter: Pointer to the HDD adapter
16716 * @req: Pointer to the structure cfg_connect_params receieved from user space
16717 *
16718 * This function will start reassociation if bssid hint, channel hint and
16719 * previous bssid parameters are present in the connect request
16720 *
16721 * Return: success if reassociation is happening
16722 * Error code if reassociation is not permitted or not happening
16723 */
16724#ifdef CFG80211_CONNECT_PREV_BSSID
16725static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16726 struct cfg80211_connect_params *req)
16727{
16728 int status = -EPERM;
16729 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16730 hddLog(VOS_TRACE_LEVEL_INFO,
16731 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16732 req->channel_hint->hw_value,
16733 MAC_ADDR_ARRAY(req->bssid_hint));
16734 status = hdd_reassoc(adapter, req->bssid_hint,
16735 req->channel_hint->hw_value,
16736 CONNECT_CMD_USERSPACE);
16737 }
16738 return status;
16739}
16740#else
16741static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16742 struct cfg80211_connect_params *req)
16743{
16744 return -EPERM;
16745}
16746#endif
16747
Abhishek Singhe3beee22017-07-31 15:35:40 +053016748/**
16749 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16750 * connect in HT20 mode
16751 * @hdd_ctx: hdd context
16752 * @adapter: Pointer to the HDD adapter
16753 * @req: Pointer to the structure cfg_connect_params receieved from user space
16754 *
16755 * This function will check if supplicant has indicated to to connect in HT20
16756 * mode. this is currently applicable only for 2.4Ghz mode only.
16757 * if feature is enabled and supplicant indicate HT20 set
16758 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16759 *
16760 * Return: void
16761 */
16762#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16763static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16764 hdd_adapter_t *adapter,
16765 struct cfg80211_connect_params *req)
16766{
16767 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16768 tCsrRoamProfile *roam_profile;
16769
16770 roam_profile = &wext_state->roamProfile;
16771 roam_profile->force_24ghz_in_ht20 = false;
16772 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16773 !(req->ht_capa.cap_info &
16774 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16775 roam_profile->force_24ghz_in_ht20 = true;
16776
16777 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16778 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16779}
16780#else
16781static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16782 hdd_adapter_t *adapter,
16783 struct cfg80211_connect_params *req)
16784{
16785 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16786 tCsrRoamProfile *roam_profile;
16787
16788 roam_profile = &wext_state->roamProfile;
16789 roam_profile->force_24ghz_in_ht20 = false;
16790}
16791#endif
16792
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016793/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016794 * FUNCTION: __wlan_hdd_cfg80211_connect
16795 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016796 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016797static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016798 struct net_device *ndev,
16799 struct cfg80211_connect_params *req
16800 )
16801{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016802 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016803 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016804#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16805 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016806 const u8 *bssid_hint = req->bssid_hint;
16807#else
16808 const u8 *bssid_hint = NULL;
16809#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016810 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016811 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016812 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016813
16814 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016815
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016816 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16817 TRACE_CODE_HDD_CFG80211_CONNECT,
16818 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016819 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016820 "%s: device_mode = %s (%d)", __func__,
16821 hdd_device_modetoString(pAdapter->device_mode),
16822 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016823
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016824 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016825 if (!pHddCtx)
16826 {
16827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16828 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016829 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016830 }
16831
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016832 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016833 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016835 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016836 }
16837
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016838 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16839 return -EINVAL;
16840
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016841 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16842 if (0 == status)
16843 return status;
16844
Agarwal Ashish51325b52014-06-16 16:50:49 +053016845
Jeff Johnson295189b2012-06-20 16:38:30 -070016846#ifdef WLAN_BTAMP_FEATURE
16847 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016848 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016849 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016850 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016851 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016852 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016853 }
16854#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016855
16856 //If Device Mode is Station Concurrent Sessions Exit BMps
16857 //P2P Mode will be taken care in Open/close adapter
16858 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016859 (vos_concurrent_open_sessions_running())) {
16860 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16861 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016862 }
16863
16864 /*Try disconnecting if already in connected state*/
16865 status = wlan_hdd_try_disconnect(pAdapter);
16866 if ( 0 > status)
16867 {
16868 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16869 " connection"));
16870 return -EALREADY;
16871 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016872 /* Check for max concurrent connections after doing disconnect if any*/
16873 if (vos_max_concurrent_connections_reached()) {
16874 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16875 return -ECONNREFUSED;
16876 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016877
Jeff Johnson295189b2012-06-20 16:38:30 -070016878 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016879 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016880
16881 if ( 0 > status)
16882 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016884 __func__);
16885 return status;
16886 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016887
16888 if (pHddCtx->spoofMacAddr.isEnabled)
16889 {
16890 hddLog(VOS_TRACE_LEVEL_INFO,
16891 "%s: MAC Spoofing enabled ", __func__);
16892 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16893 * to fill TxBds for probe request during SSID scan which may happen
16894 * as part of connect command
16895 */
16896 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16897 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16898 if (status != VOS_STATUS_SUCCESS)
16899 return -ECONNREFUSED;
16900 }
16901
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016902 if (req->channel)
16903 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016904 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016905 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016906
16907 /* Abort if any scan is going on */
16908 status = wlan_hdd_scan_abort(pAdapter);
16909 if (0 != status)
16910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16911
Abhishek Singhe3beee22017-07-31 15:35:40 +053016912 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16913
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016914 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16915 req->ssid_len, req->bssid,
16916 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016917
Sushant Kaushikd7083982015-03-18 14:33:24 +053016918 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016919 {
16920 //ReEnable BMPS if disabled
16921 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16922 (NULL != pHddCtx))
16923 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016924 if (pHddCtx->hdd_wlan_suspended)
16925 {
16926 hdd_set_pwrparams(pHddCtx);
16927 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016928 //ReEnable Bmps and Imps back
16929 hdd_enable_bmps_imps(pHddCtx);
16930 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016931 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016932 return status;
16933 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016934 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016935 EXIT();
16936 return status;
16937}
16938
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016939static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16940 struct net_device *ndev,
16941 struct cfg80211_connect_params *req)
16942{
16943 int ret;
16944 vos_ssr_protect(__func__);
16945 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16946 vos_ssr_unprotect(__func__);
16947
16948 return ret;
16949}
Jeff Johnson295189b2012-06-20 16:38:30 -070016950
16951/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016952 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016953 * This function is used to issue a disconnect request to SME
16954 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016955static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016956 struct net_device *dev,
16957 u16 reason
16958 )
16959{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016960 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016961 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016962 tCsrRoamProfile *pRoamProfile;
16963 hdd_station_ctx_t *pHddStaCtx;
16964 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016965#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016966 tANI_U8 staIdx;
16967#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016968
Jeff Johnson295189b2012-06-20 16:38:30 -070016969 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016970
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016971 if (!pAdapter) {
16972 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16973 return -EINVAL;
16974 }
16975
16976 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16977 if (!pHddStaCtx) {
16978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16979 return -EINVAL;
16980 }
16981
16982 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16983 status = wlan_hdd_validate_context(pHddCtx);
16984 if (0 != status)
16985 {
16986 return status;
16987 }
16988
16989 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16990
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016991 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16992 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16993 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016994 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16995 __func__, hdd_device_modetoString(pAdapter->device_mode),
16996 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016997
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016998 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16999 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070017000
Jeff Johnson295189b2012-06-20 16:38:30 -070017001 if (NULL != pRoamProfile)
17002 {
17003 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017004 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
17005 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017006 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017007 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017008 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017009 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017010 switch(reason)
17011 {
17012 case WLAN_REASON_MIC_FAILURE:
17013 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17014 break;
17015
17016 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17017 case WLAN_REASON_DISASSOC_AP_BUSY:
17018 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17019 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17020 break;
17021
17022 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17023 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017024 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017025 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17026 break;
17027
Jeff Johnson295189b2012-06-20 16:38:30 -070017028 default:
17029 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17030 break;
17031 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017032 pScanInfo = &pHddCtx->scan_info;
17033 if (pScanInfo->mScanPending)
17034 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017035 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017036 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017037 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017038 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017039 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017040 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017041#ifdef FEATURE_WLAN_TDLS
17042 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017043 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017044 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017045 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17046 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017047 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017048 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017049 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017050 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017051 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017052 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017053 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017054 status = sme_DeleteTdlsPeerSta(
17055 WLAN_HDD_GET_HAL_CTX(pAdapter),
17056 pAdapter->sessionId,
17057 mac);
17058 if (status != eHAL_STATUS_SUCCESS) {
17059 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17060 return -EPERM;
17061 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017062 }
17063 }
17064#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017065
17066 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17067 reasonCode,
17068 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017069 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17070 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017071 {
17072 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017073 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017074 __func__, (int)status );
17075 return -EINVAL;
17076 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017077 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017078 else
17079 {
17080 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17081 "called while in %d state", __func__,
17082 pHddStaCtx->conn_info.connState);
17083 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017084 }
17085 else
17086 {
17087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17088 }
17089
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017090 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017091 return status;
17092}
17093
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017094static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17095 struct net_device *dev,
17096 u16 reason
17097 )
17098{
17099 int ret;
17100 vos_ssr_protect(__func__);
17101 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17102 vos_ssr_unprotect(__func__);
17103
17104 return ret;
17105}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017106
Jeff Johnson295189b2012-06-20 16:38:30 -070017107/*
17108 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017109 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017110 * settings in IBSS mode.
17111 */
17112static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017113 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017114 struct cfg80211_ibss_params *params
17115 )
17116{
17117 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017118 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017119 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17120 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017121
Jeff Johnson295189b2012-06-20 16:38:30 -070017122 ENTER();
17123
17124 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017125 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017126
17127 if (params->ie_len && ( NULL != params->ie) )
17128 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017129 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17130 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017131 {
17132 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17133 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17134 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017135 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017136 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017137 tDot11fIEWPA dot11WPAIE;
17138 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017139 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017140
Wilson Yang00256342013-10-10 23:13:38 -070017141 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017142 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17143 params->ie_len, DOT11F_EID_WPA);
17144 if ( NULL != ie )
17145 {
17146 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17147 // Unpack the WPA IE
17148 //Skip past the EID byte and length byte - and four byte WiFi OUI
17149 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
17150 &ie[2+4],
17151 ie[1] - 4,
17152 &dot11WPAIE);
17153 /*Extract the multicast cipher, the encType for unicast
17154 cipher for wpa-none is none*/
17155 encryptionType =
17156 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17157 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017158 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017159
Jeff Johnson295189b2012-06-20 16:38:30 -070017160 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17161
17162 if (0 > status)
17163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017165 __func__);
17166 return status;
17167 }
17168 }
17169
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017170 pWextState->roamProfile.AuthType.authType[0] =
17171 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017172 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017173 if (params->privacy)
17174 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017175 /* Security enabled IBSS, At this time there is no information available
17176 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017177 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017178 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017179 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017180 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017181 *enable privacy bit in beacons */
17182
17183 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17184 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017185 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17186 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017187 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17188 pWextState->roamProfile.EncryptionType.numEntries = 1;
17189 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017190 return status;
17191}
17192
17193/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017194 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017195 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017196 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017197static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017198 struct net_device *dev,
17199 struct cfg80211_ibss_params *params
17200 )
17201{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017203 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17204 tCsrRoamProfile *pRoamProfile;
17205 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017206 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17207 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017208 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017209
17210 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017211
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017212 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17213 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17214 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017215 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017216 "%s: device_mode = %s (%d)", __func__,
17217 hdd_device_modetoString(pAdapter->device_mode),
17218 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017219
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017220 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017221 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017222 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017223 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017224 }
17225
17226 if (NULL == pWextState)
17227 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017228 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017229 __func__);
17230 return -EIO;
17231 }
17232
Agarwal Ashish51325b52014-06-16 16:50:49 +053017233 if (vos_max_concurrent_connections_reached()) {
17234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17235 return -ECONNREFUSED;
17236 }
17237
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017238 /*Try disconnecting if already in connected state*/
17239 status = wlan_hdd_try_disconnect(pAdapter);
17240 if ( 0 > status)
17241 {
17242 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17243 " IBSS connection"));
17244 return -EALREADY;
17245 }
17246
Jeff Johnson295189b2012-06-20 16:38:30 -070017247 pRoamProfile = &pWextState->roamProfile;
17248
17249 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17250 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017251 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017252 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017253 return -EINVAL;
17254 }
17255
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017256 /* BSSID is provided by upper layers hence no need to AUTO generate */
17257 if (NULL != params->bssid) {
17258 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17259 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17260 hddLog (VOS_TRACE_LEVEL_ERROR,
17261 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17262 return -EIO;
17263 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017264 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017265 }
krunal sonie9002db2013-11-25 14:24:17 -080017266 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17267 {
17268 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17269 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17270 {
17271 hddLog (VOS_TRACE_LEVEL_ERROR,
17272 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17273 return -EIO;
17274 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017275
17276 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017277 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017278 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017279 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017280
Jeff Johnson295189b2012-06-20 16:38:30 -070017281 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017282 if (NULL !=
17283#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17284 params->chandef.chan)
17285#else
17286 params->channel)
17287#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017288 {
17289 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017290 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17291 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17292 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17293 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017294
17295 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017296 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017297 ieee80211_frequency_to_channel(
17298#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17299 params->chandef.chan->center_freq);
17300#else
17301 params->channel->center_freq);
17302#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017303
17304 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17305 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017306 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017307 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17308 __func__);
17309 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017310 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017311
17312 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017313 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017314 if (channelNum == validChan[indx])
17315 {
17316 break;
17317 }
17318 }
17319 if (indx >= numChans)
17320 {
17321 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017322 __func__, channelNum);
17323 return -EINVAL;
17324 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017325 /* Set the Operational Channel */
17326 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17327 channelNum);
17328 pRoamProfile->ChannelInfo.numOfChannels = 1;
17329 pHddStaCtx->conn_info.operationChannel = channelNum;
17330 pRoamProfile->ChannelInfo.ChannelList =
17331 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017332 }
17333
17334 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017335 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017336 if (status < 0)
17337 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017339 __func__);
17340 return status;
17341 }
17342
17343 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017344 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017345 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017346 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017347
17348 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017350
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017351 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017352 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017353}
17354
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017355static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17356 struct net_device *dev,
17357 struct cfg80211_ibss_params *params
17358 )
17359{
17360 int ret = 0;
17361
17362 vos_ssr_protect(__func__);
17363 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17364 vos_ssr_unprotect(__func__);
17365
17366 return ret;
17367}
17368
Jeff Johnson295189b2012-06-20 16:38:30 -070017369/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017370 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017371 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017372 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017373static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017374 struct net_device *dev
17375 )
17376{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017377 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017378 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17379 tCsrRoamProfile *pRoamProfile;
17380 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017381 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017382 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017383#ifdef WLAN_FEATURE_RMC
17384 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17385#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017386
17387 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017388
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017389 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17390 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17391 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017392 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017393 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017394 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017395 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017396 }
17397
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017398 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17399 hdd_device_modetoString(pAdapter->device_mode),
17400 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017401 if (NULL == pWextState)
17402 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017403 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017404 __func__);
17405 return -EIO;
17406 }
17407
17408 pRoamProfile = &pWextState->roamProfile;
17409
17410 /* Issue disconnect only if interface type is set to IBSS */
17411 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17412 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017413 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017414 __func__);
17415 return -EINVAL;
17416 }
17417
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017418#ifdef WLAN_FEATURE_RMC
17419 /* Clearing add IE of beacon */
17420 if (ccmCfgSetStr(pHddCtx->hHal,
17421 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17422 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17423 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17424 {
17425 hddLog (VOS_TRACE_LEVEL_ERROR,
17426 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17427 return -EINVAL;
17428 }
17429 if (ccmCfgSetInt(pHddCtx->hHal,
17430 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17431 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17432 {
17433 hddLog (VOS_TRACE_LEVEL_ERROR,
17434 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17435 __func__);
17436 return -EINVAL;
17437 }
17438
17439 // Reset WNI_CFG_PROBE_RSP Flags
17440 wlan_hdd_reset_prob_rspies(pAdapter);
17441
17442 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17443 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17444 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17445 {
17446 hddLog (VOS_TRACE_LEVEL_ERROR,
17447 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17448 __func__);
17449 return -EINVAL;
17450 }
17451#endif
17452
Jeff Johnson295189b2012-06-20 16:38:30 -070017453 /* Issue Disconnect request */
17454 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017455 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17456 pAdapter->sessionId,
17457 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17458 if (!HAL_STATUS_SUCCESS(hal_status)) {
17459 hddLog(LOGE,
17460 FL("sme_RoamDisconnect failed hal_status(%d)"),
17461 hal_status);
17462 return -EAGAIN;
17463 }
17464 status = wait_for_completion_timeout(
17465 &pAdapter->disconnect_comp_var,
17466 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17467 if (!status) {
17468 hddLog(LOGE,
17469 FL("wait on disconnect_comp_var failed"));
17470 return -ETIMEDOUT;
17471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017472
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017473 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017474 return 0;
17475}
17476
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017477static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17478 struct net_device *dev
17479 )
17480{
17481 int ret = 0;
17482
17483 vos_ssr_protect(__func__);
17484 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17485 vos_ssr_unprotect(__func__);
17486
17487 return ret;
17488}
17489
Jeff Johnson295189b2012-06-20 16:38:30 -070017490/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017491 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017492 * This function is used to set the phy parameters
17493 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17494 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017495static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017496 u32 changed)
17497{
17498 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17499 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017500 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017501
17502 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017503
17504 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017505 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17506 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017507
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017508 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017509 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017510 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017511 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017512 }
17513
Jeff Johnson295189b2012-06-20 16:38:30 -070017514 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17515 {
17516 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17517 WNI_CFG_RTS_THRESHOLD_STAMAX :
17518 wiphy->rts_threshold;
17519
17520 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017521 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017522 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017523 hddLog(VOS_TRACE_LEVEL_ERROR,
17524 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017525 __func__, rts_threshold);
17526 return -EINVAL;
17527 }
17528
17529 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17530 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017531 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017532 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017533 hddLog(VOS_TRACE_LEVEL_ERROR,
17534 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017535 __func__, rts_threshold);
17536 return -EIO;
17537 }
17538
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017539 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017540 rts_threshold);
17541 }
17542
17543 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17544 {
17545 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17546 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17547 wiphy->frag_threshold;
17548
17549 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017550 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017552 hddLog(VOS_TRACE_LEVEL_ERROR,
17553 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017554 frag_threshold);
17555 return -EINVAL;
17556 }
17557
17558 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17559 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017560 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017561 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017562 hddLog(VOS_TRACE_LEVEL_ERROR,
17563 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017564 __func__, frag_threshold);
17565 return -EIO;
17566 }
17567
17568 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17569 frag_threshold);
17570 }
17571
17572 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17573 || (changed & WIPHY_PARAM_RETRY_LONG))
17574 {
17575 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17576 wiphy->retry_short :
17577 wiphy->retry_long;
17578
17579 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17580 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17581 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017582 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017583 __func__, retry_value);
17584 return -EINVAL;
17585 }
17586
17587 if (changed & WIPHY_PARAM_RETRY_SHORT)
17588 {
17589 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17590 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017591 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017593 hddLog(VOS_TRACE_LEVEL_ERROR,
17594 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017595 __func__, retry_value);
17596 return -EIO;
17597 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017598 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017599 __func__, retry_value);
17600 }
17601 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17602 {
17603 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17604 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017605 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017606 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017607 hddLog(VOS_TRACE_LEVEL_ERROR,
17608 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017609 __func__, retry_value);
17610 return -EIO;
17611 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017612 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017613 __func__, retry_value);
17614 }
17615 }
17616
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017617 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017618 return 0;
17619}
17620
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017621static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17622 u32 changed)
17623{
17624 int ret;
17625
17626 vos_ssr_protect(__func__);
17627 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17628 vos_ssr_unprotect(__func__);
17629
17630 return ret;
17631}
17632
Jeff Johnson295189b2012-06-20 16:38:30 -070017633/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017634 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017635 * This function is used to set the txpower
17636 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017637static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017638#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17639 struct wireless_dev *wdev,
17640#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017641#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017642 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017643#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017644 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017645#endif
17646 int dbm)
17647{
17648 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017649 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017650 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17651 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017652 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017653
17654 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017655
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017656 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17657 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17658 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017659 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017660 if (0 != status)
17661 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017662 return status;
17663 }
17664
17665 hHal = pHddCtx->hHal;
17666
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017667 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17668 dbm, ccmCfgSetCallback,
17669 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017670 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017671 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017672 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17673 return -EIO;
17674 }
17675
17676 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17677 dbm);
17678
17679 switch(type)
17680 {
17681 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17682 /* Fall through */
17683 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17684 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17685 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017686 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17687 __func__);
17688 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017689 }
17690 break;
17691 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017692 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017693 __func__);
17694 return -EOPNOTSUPP;
17695 break;
17696 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017697 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17698 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017699 return -EIO;
17700 }
17701
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017702 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017703 return 0;
17704}
17705
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017706static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17707#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17708 struct wireless_dev *wdev,
17709#endif
17710#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17711 enum tx_power_setting type,
17712#else
17713 enum nl80211_tx_power_setting type,
17714#endif
17715 int dbm)
17716{
17717 int ret;
17718 vos_ssr_protect(__func__);
17719 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17720#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17721 wdev,
17722#endif
17723#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17724 type,
17725#else
17726 type,
17727#endif
17728 dbm);
17729 vos_ssr_unprotect(__func__);
17730
17731 return ret;
17732}
17733
Jeff Johnson295189b2012-06-20 16:38:30 -070017734/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017735 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017736 * This function is used to read the txpower
17737 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017738static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017739#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17740 struct wireless_dev *wdev,
17741#endif
17742 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017743{
17744
17745 hdd_adapter_t *pAdapter;
17746 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017747 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017748
Jeff Johnsone7245742012-09-05 17:12:55 -070017749 ENTER();
17750
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017751 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017752 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017753 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017754 *dbm = 0;
17755 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017756 }
17757
Jeff Johnson295189b2012-06-20 16:38:30 -070017758 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17759 if (NULL == pAdapter)
17760 {
17761 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17762 return -ENOENT;
17763 }
17764
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17766 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17767 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017768 wlan_hdd_get_classAstats(pAdapter);
17769 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17770
Jeff Johnsone7245742012-09-05 17:12:55 -070017771 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017772 return 0;
17773}
17774
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017775static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17776#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17777 struct wireless_dev *wdev,
17778#endif
17779 int *dbm)
17780{
17781 int ret;
17782
17783 vos_ssr_protect(__func__);
17784 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17785#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17786 wdev,
17787#endif
17788 dbm);
17789 vos_ssr_unprotect(__func__);
17790
17791 return ret;
17792}
17793
Dustin Brown8c1d4092017-07-28 18:08:01 +053017794/*
17795 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17796 * @stats: summary stats to use as a source
17797 * @info: kernel station_info struct to use as a destination
17798 *
17799 * Return: None
17800 */
17801static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17802 struct station_info *info)
17803{
17804 int i;
17805
17806 info->rx_packets = stats->rx_frm_cnt;
17807 info->tx_packets = 0;
17808 info->tx_retries = 0;
17809 info->tx_failed = 0;
17810
17811 for (i = 0; i < 4; ++i) {
17812 info->tx_packets += stats->tx_frm_cnt[i];
17813 info->tx_retries += stats->multiple_retry_cnt[i];
17814 info->tx_failed += stats->fail_cnt[i];
17815 }
17816
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017817#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17818 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017819 info->filled |= STATION_INFO_TX_PACKETS |
17820 STATION_INFO_TX_RETRIES |
17821 STATION_INFO_TX_FAILED |
17822 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017823#else
17824 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17825 BIT(NL80211_STA_INFO_TX_RETRIES) |
17826 BIT(NL80211_STA_INFO_TX_FAILED) |
17827 BIT(NL80211_STA_INFO_RX_PACKETS);
17828#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017829}
17830
17831/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017832 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17833 * @adapter: sap adapter pointer
17834 * @staid: station id of the client
17835 * @rssi: rssi value to fill
17836 *
17837 * Return: None
17838 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017839void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017840wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17841{
17842 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17843
17844 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17845}
17846
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017847#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17848 !defined(WITH_BACKPORTS)
17849static inline void wlan_hdd_fill_station_info_signal(struct station_info
17850 *sinfo)
17851{
17852 sinfo->filled |= STATION_INFO_SIGNAL;
17853}
17854#else
17855static inline void wlan_hdd_fill_station_info_signal(struct station_info
17856 *sinfo)
17857{
17858 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17859}
17860#endif
17861
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017862/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017863 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17864 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017865 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017866 * @info: kernel station_info struct to populate
17867 *
17868 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17869 * support "station dump" and "station get" for SAP vdevs, even though they
17870 * aren't technically stations.
17871 *
17872 * Return: errno
17873 */
17874static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017875wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17877 const u8* mac,
17878#else
17879 u8* mac,
17880#endif
17881 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017882{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017883 v_MACADDR_t *peerMacAddr;
17884 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017885 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017886 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017887
17888 status = wlan_hdd_get_station_stats(adapter);
17889 if (!VOS_IS_STATUS_SUCCESS(status)) {
17890 hddLog(VOS_TRACE_LEVEL_ERROR,
17891 "Failed to get SAP stats; status:%d", status);
17892 return 0;
17893 }
17894
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017895 peerMacAddr = (v_MACADDR_t *)mac;
17896 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17897 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17898 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17899
17900 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17901 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017902 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017903 }
17904
Dustin Brown8c1d4092017-07-28 18:08:01 +053017905 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17906
17907 return 0;
17908}
17909
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017910static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17912 const u8* mac,
17913#else
17914 u8* mac,
17915#endif
17916 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017917{
17918 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17919 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17920 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017921 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017922
17923 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17924 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017925
17926 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17927 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17928 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17929 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17930 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17931 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17932 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017933 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017934 tANI_U16 myRate;
17935 tANI_U16 currentRate = 0;
17936 tANI_U8 maxSpeedMCS = 0;
17937 tANI_U8 maxMCSIdx = 0;
17938 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017939 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017940 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017941 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017942
Leo Chang6f8870f2013-03-26 18:11:36 -070017943#ifdef WLAN_FEATURE_11AC
17944 tANI_U32 vht_mcs_map;
17945 eDataRate11ACMaxMcs vhtMaxMcs;
17946#endif /* WLAN_FEATURE_11AC */
17947
Jeff Johnsone7245742012-09-05 17:12:55 -070017948 ENTER();
17949
Dustin Brown8c1d4092017-07-28 18:08:01 +053017950 status = wlan_hdd_validate_context(pHddCtx);
17951 if (0 != status)
17952 {
17953 return status;
17954 }
17955
17956 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017957 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017958
Jeff Johnson295189b2012-06-20 16:38:30 -070017959 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17960 (0 == ssidlen))
17961 {
17962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17963 " Invalid ssidlen, %d", __func__, ssidlen);
17964 /*To keep GUI happy*/
17965 return 0;
17966 }
17967
Mukul Sharma811205f2014-07-09 21:07:30 +053017968 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17969 {
17970 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17971 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017972 /* return a cached value */
17973 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017974 return 0;
17975 }
17976
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017977 wlan_hdd_get_station_stats(pAdapter);
17978 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017979
Kiet Lam3b17fc82013-09-27 05:24:08 +053017980 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017981 wlan_hdd_get_snr(pAdapter, &snr);
17982 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017983 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017984 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017985 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017986 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017987
c_hpothu09f19542014-05-30 21:53:31 +053017988 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017989 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17990 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017991 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017992 {
17993 rate_flags = pAdapter->maxRateFlags;
17994 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017995
Jeff Johnson295189b2012-06-20 16:38:30 -070017996 //convert to the UI units of 100kbps
17997 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17998
17999#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070018000 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 -070018001 sinfo->signal,
18002 pCfg->reportMaxLinkSpeed,
18003 myRate,
18004 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018005 (int) pCfg->linkSpeedRssiMid,
18006 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018007 (int) rate_flags,
18008 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018009#endif //LINKSPEED_DEBUG_ENABLED
18010
18011 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18012 {
18013 // we do not want to necessarily report the current speed
18014 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18015 {
18016 // report the max possible speed
18017 rssidx = 0;
18018 }
18019 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18020 {
18021 // report the max possible speed with RSSI scaling
18022 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18023 {
18024 // report the max possible speed
18025 rssidx = 0;
18026 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018027 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018028 {
18029 // report middle speed
18030 rssidx = 1;
18031 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018032 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18033 {
18034 // report middle speed
18035 rssidx = 2;
18036 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018037 else
18038 {
18039 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018040 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018041 }
18042 }
18043 else
18044 {
18045 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18046 hddLog(VOS_TRACE_LEVEL_ERROR,
18047 "%s: Invalid value for reportMaxLinkSpeed: %u",
18048 __func__, pCfg->reportMaxLinkSpeed);
18049 rssidx = 0;
18050 }
18051
18052 maxRate = 0;
18053
18054 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018055 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18056 OperationalRates, &ORLeng))
18057 {
18058 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18059 /*To keep GUI happy*/
18060 return 0;
18061 }
18062
Jeff Johnson295189b2012-06-20 16:38:30 -070018063 for (i = 0; i < ORLeng; i++)
18064 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018065 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018066 {
18067 /* Validate Rate Set */
18068 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18069 {
18070 currentRate = supported_data_rate[j].supported_rate[rssidx];
18071 break;
18072 }
18073 }
18074 /* Update MAX rate */
18075 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18076 }
18077
18078 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018079 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18080 ExtendedRates, &ERLeng))
18081 {
18082 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18083 /*To keep GUI happy*/
18084 return 0;
18085 }
18086
Jeff Johnson295189b2012-06-20 16:38:30 -070018087 for (i = 0; i < ERLeng; i++)
18088 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018089 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018090 {
18091 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18092 {
18093 currentRate = supported_data_rate[j].supported_rate[rssidx];
18094 break;
18095 }
18096 }
18097 /* Update MAX rate */
18098 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18099 }
c_hpothu79aab322014-07-14 21:11:01 +053018100
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018101 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018102 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018103 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018104 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018105 {
c_hpothu79aab322014-07-14 21:11:01 +053018106 if (rate_flags & eHAL_TX_RATE_VHT80)
18107 mode = 2;
18108 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18109 mode = 1;
18110 else
18111 mode = 0;
18112
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018113 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18114 MCSRates, &MCSLeng))
18115 {
18116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18117 /*To keep GUI happy*/
18118 return 0;
18119 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018120 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018121#ifdef WLAN_FEATURE_11AC
18122 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018123 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018124 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018125 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018126 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018127 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018128 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018129 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018130 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018131 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018132 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018133 maxMCSIdx = 7;
18134 }
18135 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18136 {
18137 maxMCSIdx = 8;
18138 }
18139 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18140 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018141 //VHT20 is supporting 0~8
18142 if (rate_flags & eHAL_TX_RATE_VHT20)
18143 maxMCSIdx = 8;
18144 else
18145 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018146 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018147
c_hpothu79aab322014-07-14 21:11:01 +053018148 if (0 != rssidx)/*check for scaled */
18149 {
18150 //get middle rate MCS index if rssi=1/2
18151 for (i=0; i <= maxMCSIdx; i++)
18152 {
18153 if (sinfo->signal <= rssiMcsTbl[mode][i])
18154 {
18155 maxMCSIdx = i;
18156 break;
18157 }
18158 }
18159 }
18160
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018161 if (rate_flags & eHAL_TX_RATE_VHT80)
18162 {
18163 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18164 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18165 }
18166 else if (rate_flags & eHAL_TX_RATE_VHT40)
18167 {
18168 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18169 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18170 }
18171 else if (rate_flags & eHAL_TX_RATE_VHT20)
18172 {
18173 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18174 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18175 }
18176
Leo Chang6f8870f2013-03-26 18:11:36 -070018177 maxSpeedMCS = 1;
18178 if (currentRate > maxRate)
18179 {
18180 maxRate = currentRate;
18181 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018182
Leo Chang6f8870f2013-03-26 18:11:36 -070018183 }
18184 else
18185#endif /* WLAN_FEATURE_11AC */
18186 {
18187 if (rate_flags & eHAL_TX_RATE_HT40)
18188 {
18189 rateFlag |= 1;
18190 }
18191 if (rate_flags & eHAL_TX_RATE_SGI)
18192 {
18193 rateFlag |= 2;
18194 }
18195
Girish Gowli01abcee2014-07-31 20:18:55 +053018196 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018197 if (rssidx == 1 || rssidx == 2)
18198 {
18199 //get middle rate MCS index if rssi=1/2
18200 for (i=0; i <= 7; i++)
18201 {
18202 if (sinfo->signal <= rssiMcsTbl[mode][i])
18203 {
18204 temp = i+1;
18205 break;
18206 }
18207 }
18208 }
c_hpothu79aab322014-07-14 21:11:01 +053018209
18210 for (i = 0; i < MCSLeng; i++)
18211 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018212 for (j = 0; j < temp; j++)
18213 {
18214 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18215 {
18216 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018217 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018218 break;
18219 }
18220 }
18221 if ((j < temp) && (currentRate > maxRate))
18222 {
18223 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018224 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018225 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018226 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018227 }
18228 }
18229
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018230 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18231 {
18232 maxRate = myRate;
18233 maxSpeedMCS = 1;
18234 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18235 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018236 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018237 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018238 {
18239 maxRate = myRate;
18240 if (rate_flags & eHAL_TX_RATE_LEGACY)
18241 {
18242 maxSpeedMCS = 0;
18243 }
18244 else
18245 {
18246 maxSpeedMCS = 1;
18247 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18248 }
18249 }
18250
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018251 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018252 {
18253 sinfo->txrate.legacy = maxRate;
18254#ifdef LINKSPEED_DEBUG_ENABLED
18255 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18256#endif //LINKSPEED_DEBUG_ENABLED
18257 }
18258 else
18259 {
18260 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018261#ifdef WLAN_FEATURE_11AC
18262 sinfo->txrate.nss = 1;
18263 if (rate_flags & eHAL_TX_RATE_VHT80)
18264 {
18265 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018266#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18267 defined(WITH_BACKPORTS)
18268 sinfo->txrate.bw = RATE_INFO_BW_80;
18269#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018270 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018271#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018272 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018273 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018274 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018275 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018276#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18277 defined(WITH_BACKPORTS)
18278 sinfo->txrate.bw = RATE_INFO_BW_40;
18279#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018280 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018281#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018282 }
18283 else if (rate_flags & eHAL_TX_RATE_VHT20)
18284 {
18285 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18286 }
18287#endif /* WLAN_FEATURE_11AC */
18288 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18289 {
18290 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18291 if (rate_flags & eHAL_TX_RATE_HT40)
18292 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018293#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18294 defined(WITH_BACKPORTS)
18295 sinfo->txrate.bw = RATE_INFO_BW_40;
18296#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018297 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018298#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018299 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018300 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018301 if (rate_flags & eHAL_TX_RATE_SGI)
18302 {
18303 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18304 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018305
Jeff Johnson295189b2012-06-20 16:38:30 -070018306#ifdef LINKSPEED_DEBUG_ENABLED
18307 pr_info("Reporting MCS rate %d flags %x\n",
18308 sinfo->txrate.mcs,
18309 sinfo->txrate.flags );
18310#endif //LINKSPEED_DEBUG_ENABLED
18311 }
18312 }
18313 else
18314 {
18315 // report current rate instead of max rate
18316
18317 if (rate_flags & eHAL_TX_RATE_LEGACY)
18318 {
18319 //provide to the UI in units of 100kbps
18320 sinfo->txrate.legacy = myRate;
18321#ifdef LINKSPEED_DEBUG_ENABLED
18322 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18323#endif //LINKSPEED_DEBUG_ENABLED
18324 }
18325 else
18326 {
18327 //must be MCS
18328 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018329#ifdef WLAN_FEATURE_11AC
18330 sinfo->txrate.nss = 1;
18331 if (rate_flags & eHAL_TX_RATE_VHT80)
18332 {
18333 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18334 }
18335 else
18336#endif /* WLAN_FEATURE_11AC */
18337 {
18338 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18339 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018340 if (rate_flags & eHAL_TX_RATE_SGI)
18341 {
18342 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18343 }
18344 if (rate_flags & eHAL_TX_RATE_HT40)
18345 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018346#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18347 defined(WITH_BACKPORTS)
18348 sinfo->txrate.bw = RATE_INFO_BW_40;
18349#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018350 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018351#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018352 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018353#ifdef WLAN_FEATURE_11AC
18354 else if (rate_flags & eHAL_TX_RATE_VHT80)
18355 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018356#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18357 defined(WITH_BACKPORTS)
18358 sinfo->txrate.bw = RATE_INFO_BW_80;
18359#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018360 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018361#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018362 }
18363#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018364#ifdef LINKSPEED_DEBUG_ENABLED
18365 pr_info("Reporting actual MCS rate %d flags %x\n",
18366 sinfo->txrate.mcs,
18367 sinfo->txrate.flags );
18368#endif //LINKSPEED_DEBUG_ENABLED
18369 }
18370 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018371
18372#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18373 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018374 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018375#else
18376 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018378
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018379 sinfo->tx_packets =
18380 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18381 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18382 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18383 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18384
18385 sinfo->tx_retries =
18386 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18387 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18388 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18389 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18390
18391 sinfo->tx_failed =
18392 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18393 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18394 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18395 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18396
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018397#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18398 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018399 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018400 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018401 STATION_INFO_TX_PACKETS |
18402 STATION_INFO_TX_RETRIES |
18403 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018404#else
18405 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18406 BIT(NL80211_STA_INFO_TX_PACKETS) |
18407 BIT(NL80211_STA_INFO_TX_RETRIES) |
18408 BIT(NL80211_STA_INFO_TX_FAILED);
18409#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018410
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018411 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018412
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018413 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18414 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018415 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18416 &sinfo->txrate, sizeof(sinfo->txrate));
18417
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018418 if (rate_flags & eHAL_TX_RATE_LEGACY)
18419 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18420 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18421 sinfo->rx_packets);
18422 else
18423 hddLog(LOG1,
18424 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18425 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18426 sinfo->tx_packets, sinfo->rx_packets);
18427
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018428 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18429 TRACE_CODE_HDD_CFG80211_GET_STA,
18430 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018431 EXIT();
18432 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018433}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18435static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18436 const u8* mac, struct station_info *sinfo)
18437#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018438static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18439 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018440#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018441{
18442 int ret;
18443
18444 vos_ssr_protect(__func__);
18445 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18446 vos_ssr_unprotect(__func__);
18447
18448 return ret;
18449}
18450
18451static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018452 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018453{
18454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018455 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018456 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018457 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018458
Jeff Johnsone7245742012-09-05 17:12:55 -070018459 ENTER();
18460
Jeff Johnson295189b2012-06-20 16:38:30 -070018461 if (NULL == pAdapter)
18462 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018464 return -ENODEV;
18465 }
18466
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018467 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18468 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18469 pAdapter->sessionId, timeout));
18470
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018471 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018472 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018473 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018474 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018475 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018476 }
18477
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018478 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18479 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18480 (pHddCtx->cfg_ini->fhostArpOffload) &&
18481 (eConnectionState_Associated ==
18482 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18483 {
Amar Singhald53568e2013-09-26 11:03:45 -070018484
18485 hddLog(VOS_TRACE_LEVEL_INFO,
18486 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018487 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018488 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18489 {
18490 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018491 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018492 __func__, vos_status);
18493 }
18494 }
18495
Jeff Johnson295189b2012-06-20 16:38:30 -070018496 /**The get power cmd from the supplicant gets updated by the nl only
18497 *on successful execution of the function call
18498 *we are oppositely mapped w.r.t mode in the driver
18499 **/
18500 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18501
18502 if (VOS_STATUS_E_FAILURE == vos_status)
18503 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18505 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018506 return -EINVAL;
18507 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018508 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018509 return 0;
18510}
18511
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018512static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18513 struct net_device *dev, bool mode, int timeout)
18514{
18515 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018516
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018517 vos_ssr_protect(__func__);
18518 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18519 vos_ssr_unprotect(__func__);
18520
18521 return ret;
18522}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018523
Jeff Johnson295189b2012-06-20 16:38:30 -070018524#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018525static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18526 struct net_device *netdev,
18527 u8 key_index)
18528{
18529 ENTER();
18530 return 0;
18531}
18532
Jeff Johnson295189b2012-06-20 16:38:30 -070018533static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018534 struct net_device *netdev,
18535 u8 key_index)
18536{
18537 int ret;
18538 vos_ssr_protect(__func__);
18539 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18540 vos_ssr_unprotect(__func__);
18541 return ret;
18542}
18543#endif //LINUX_VERSION_CODE
18544
18545#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18546static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18547 struct net_device *dev,
18548 struct ieee80211_txq_params *params)
18549{
18550 ENTER();
18551 return 0;
18552}
18553#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18554static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18555 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018556{
Jeff Johnsone7245742012-09-05 17:12:55 -070018557 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018558 return 0;
18559}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018560#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018561
18562#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18563static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018564 struct net_device *dev,
18565 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018566{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018567 int ret;
18568
18569 vos_ssr_protect(__func__);
18570 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18571 vos_ssr_unprotect(__func__);
18572 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018573}
18574#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18575static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18576 struct ieee80211_txq_params *params)
18577{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018578 int ret;
18579
18580 vos_ssr_protect(__func__);
18581 ret = __wlan_hdd_set_txq_params(wiphy, params);
18582 vos_ssr_unprotect(__func__);
18583 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018584}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018585#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018586
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018587static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018588 struct net_device *dev,
18589 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018590{
18591 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018592 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018593 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018594 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018595 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018596 v_CONTEXT_t pVosContext = NULL;
18597 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018598
Jeff Johnsone7245742012-09-05 17:12:55 -070018599 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018600
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018601 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018602 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018603 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018604 return -EINVAL;
18605 }
18606
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018607 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18608 TRACE_CODE_HDD_CFG80211_DEL_STA,
18609 pAdapter->sessionId, pAdapter->device_mode));
18610
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018611 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18612 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018613 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018614 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018615 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018616 }
18617
Jeff Johnson295189b2012-06-20 16:38:30 -070018618 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018619 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018620 )
18621 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018622 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18623 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18624 if(pSapCtx == NULL){
18625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18626 FL("psapCtx is NULL"));
18627 return -ENOENT;
18628 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018629 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18630 {
18631 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18632 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18633 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18634 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018635 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018636 {
18637 v_U16_t i;
18638 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18639 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018640 if ((pSapCtx->aStaInfo[i].isUsed) &&
18641 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018642 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018643 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018644 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018645 ETHER_ADDR_LEN);
18646
Jeff Johnson295189b2012-06-20 16:38:30 -070018647 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018648 "%s: Delete STA with MAC::"
18649 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018650 __func__,
18651 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18652 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018653 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018654 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018655 }
18656 }
18657 }
18658 else
18659 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018660
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018661 vos_status = hdd_softap_GetStaId(pAdapter,
18662 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018663 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18664 {
18665 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018666 "%s: Skip this DEL STA as this is not used::"
18667 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018668 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018669 return -ENOENT;
18670 }
18671
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018672 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018673 {
18674 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018675 "%s: Skip this DEL STA as deauth is in progress::"
18676 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018677 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018678 return -ENOENT;
18679 }
18680
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018681 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018682
Jeff Johnson295189b2012-06-20 16:38:30 -070018683 hddLog(VOS_TRACE_LEVEL_INFO,
18684 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018685 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018686 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018687 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018688
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018689 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018690 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18691 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018692 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018693 hddLog(VOS_TRACE_LEVEL_INFO,
18694 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018695 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018696 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018697 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018698 return -ENOENT;
18699 }
18700
Jeff Johnson295189b2012-06-20 16:38:30 -070018701 }
18702 }
18703
18704 EXIT();
18705
18706 return 0;
18707}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018708
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018709#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018710int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018711 struct net_device *dev,
18712 struct station_del_parameters *param)
18713#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018714#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018715int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018716 struct net_device *dev, const u8 *mac)
18717#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018718int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018719 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018720#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018721#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018722{
18723 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018724 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018725
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018726 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018727
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018728#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018729 if (NULL == param) {
18730 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018731 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018732 return -EINVAL;
18733 }
18734
18735 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18736 param->subtype, &delStaParams);
18737
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018738#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018739 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018740 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018741#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018742 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18743
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018744 vos_ssr_unprotect(__func__);
18745
18746 return ret;
18747}
18748
18749static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018750 struct net_device *dev,
18751#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18752 const u8 *mac,
18753#else
18754 u8 *mac,
18755#endif
18756 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018757{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018758 hdd_adapter_t *pAdapter;
18759 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018760 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018761#ifdef FEATURE_WLAN_TDLS
18762 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018763
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018764 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018765
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018766 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18767 if (NULL == pAdapter)
18768 {
18769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18770 "%s: Adapter is NULL",__func__);
18771 return -EINVAL;
18772 }
18773 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18774 status = wlan_hdd_validate_context(pHddCtx);
18775 if (0 != status)
18776 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018777 return status;
18778 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018779
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018780 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18781 TRACE_CODE_HDD_CFG80211_ADD_STA,
18782 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018783 mask = params->sta_flags_mask;
18784
18785 set = params->sta_flags_set;
18786
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018788 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18789 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018790
18791 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18792 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018793 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018794 }
18795 }
18796#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018797 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018798 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018799}
18800
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018801#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18802static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18803 struct net_device *dev, const u8 *mac,
18804 struct station_parameters *params)
18805#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018806static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18807 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018808#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018809{
18810 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018811
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018812 vos_ssr_protect(__func__);
18813 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18814 vos_ssr_unprotect(__func__);
18815
18816 return ret;
18817}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018818#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018819
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018820static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018821 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018822{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018823 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18824 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018825 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018826 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018827 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018828 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018830 ENTER();
18831
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018832 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018833 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018836 return -EINVAL;
18837 }
18838
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018839 if (!pmksa) {
18840 hddLog(LOGE, FL("pmksa is NULL"));
18841 return -EINVAL;
18842 }
18843
18844 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018845 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018846 pmksa->bssid, pmksa->pmkid);
18847 return -EINVAL;
18848 }
18849
18850 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18851 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18852
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018853 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18854 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018855 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018856 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018857 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018858 }
18859
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018860 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018861 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18862
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018863 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18864 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018865
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018866 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018867 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018868 &pmk_id, 1, FALSE);
18869
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018870 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18871 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18872 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018873
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018874 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018875 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018876}
18877
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018878static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18879 struct cfg80211_pmksa *pmksa)
18880{
18881 int ret;
18882
18883 vos_ssr_protect(__func__);
18884 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18885 vos_ssr_unprotect(__func__);
18886
18887 return ret;
18888}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018889
Wilson Yang6507c4e2013-10-01 20:11:19 -070018890
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018891static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018892 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018893{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18895 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018896 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018897 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018898
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018899 ENTER();
18900
Wilson Yang6507c4e2013-10-01 20:11:19 -070018901 /* Validate pAdapter */
18902 if (NULL == pAdapter)
18903 {
18904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18905 return -EINVAL;
18906 }
18907
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018908 if (!pmksa) {
18909 hddLog(LOGE, FL("pmksa is NULL"));
18910 return -EINVAL;
18911 }
18912
18913 if (!pmksa->bssid) {
18914 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18915 return -EINVAL;
18916 }
18917
Kiet Lam98c46a12014-10-31 15:34:57 -070018918 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18919 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18920
Wilson Yang6507c4e2013-10-01 20:11:19 -070018921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18922 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018923 if (0 != status)
18924 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018925 return status;
18926 }
18927
18928 /*Retrieve halHandle*/
18929 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18930
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018931 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18932 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18933 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018934 /* Delete the PMKID CSR cache */
18935 if (eHAL_STATUS_SUCCESS !=
18936 sme_RoamDelPMKIDfromCache(halHandle,
18937 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18938 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18939 MAC_ADDR_ARRAY(pmksa->bssid));
18940 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018941 }
18942
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018943 EXIT();
18944 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018945}
18946
Wilson Yang6507c4e2013-10-01 20:11:19 -070018947
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018948static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18949 struct cfg80211_pmksa *pmksa)
18950{
18951 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018952
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018953 vos_ssr_protect(__func__);
18954 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18955 vos_ssr_unprotect(__func__);
18956
18957 return ret;
18958
18959}
18960
18961static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018962{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018963 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18964 tHalHandle halHandle;
18965 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018966 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018967
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018968 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018969
18970 /* Validate pAdapter */
18971 if (NULL == pAdapter)
18972 {
18973 hddLog(VOS_TRACE_LEVEL_ERROR,
18974 "%s: Invalid Adapter" ,__func__);
18975 return -EINVAL;
18976 }
18977
18978 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18979 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018980 if (0 != status)
18981 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018982 return status;
18983 }
18984
18985 /*Retrieve halHandle*/
18986 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18987
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018988 /* Flush the PMKID cache in CSR */
18989 if (eHAL_STATUS_SUCCESS !=
18990 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18991 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18992 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018993 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018994 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018995 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018996}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018997
18998static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18999{
19000 int ret;
19001
19002 vos_ssr_protect(__func__);
19003 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
19004 vos_ssr_unprotect(__func__);
19005
19006 return ret;
19007}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019008#endif
19009
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019010#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019011static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19012 struct net_device *dev,
19013 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019014{
19015 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19016 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019017 hdd_context_t *pHddCtx;
19018 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019020 ENTER();
19021
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019022 if (NULL == pAdapter)
19023 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019024 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019025 return -ENODEV;
19026 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019027 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19028 ret = wlan_hdd_validate_context(pHddCtx);
19029 if (0 != ret)
19030 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019031 return ret;
19032 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019033 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019034 if (NULL == pHddStaCtx)
19035 {
19036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19037 return -EINVAL;
19038 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019039
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019040 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19041 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19042 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019043 // Added for debug on reception of Re-assoc Req.
19044 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19045 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019046 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019047 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019048 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019049 }
19050
19051#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019052 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019053 ftie->ie_len);
19054#endif
19055
19056 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019057 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19058 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019059 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019060
19061 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019062 return 0;
19063}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019064
19065static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19066 struct net_device *dev,
19067 struct cfg80211_update_ft_ies_params *ftie)
19068{
19069 int ret;
19070
19071 vos_ssr_protect(__func__);
19072 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19073 vos_ssr_unprotect(__func__);
19074
19075 return ret;
19076}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019077#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019078
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019079#ifdef FEATURE_WLAN_SCAN_PNO
19080
19081void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19082 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19083{
19084 int ret;
19085 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19086 hdd_context_t *pHddCtx;
19087
Nirav Shah80830bf2013-12-31 16:35:12 +053019088 ENTER();
19089
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019090 if (NULL == pAdapter)
19091 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019092 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019093 "%s: HDD adapter is Null", __func__);
19094 return ;
19095 }
19096
19097 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19098 if (NULL == pHddCtx)
19099 {
19100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19101 "%s: HDD context is Null!!!", __func__);
19102 return ;
19103 }
19104
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019105 spin_lock(&pHddCtx->schedScan_lock);
19106 if (TRUE == pHddCtx->isWiphySuspended)
19107 {
19108 pHddCtx->isSchedScanUpdatePending = TRUE;
19109 spin_unlock(&pHddCtx->schedScan_lock);
19110 hddLog(VOS_TRACE_LEVEL_INFO,
19111 "%s: Update cfg80211 scan database after it resume", __func__);
19112 return ;
19113 }
19114 spin_unlock(&pHddCtx->schedScan_lock);
19115
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019116 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19117
19118 if (0 > ret)
19119 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019120 else
19121 {
19122 /* Acquire wakelock to handle the case where APP's tries to suspend
19123 * immediatly after the driver gets connect request(i.e after pno)
19124 * from supplicant, this result in app's is suspending and not able
19125 * to process the connect request to AP */
19126 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19127 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019128 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19130 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019131}
19132
19133/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019134 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019135 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019136 */
19137static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19138{
19139 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19140 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019141 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019142 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19143 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019144
19145 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19146 {
19147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19148 "%s: PNO is allowed only in STA interface", __func__);
19149 return eHAL_STATUS_FAILURE;
19150 }
19151
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019152 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19153
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019154 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019155 * active sessions. PNO is allowed only in case when sap session
19156 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019157 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019158 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19159 {
19160 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019161 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019162
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019163 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19164 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19165 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19166 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019167 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19168 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019169 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019170 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019171 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019172 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019173 }
19174 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19175 pAdapterNode = pNext;
19176 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019177 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019178}
19179
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019180void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19181{
19182 hdd_adapter_t *pAdapter = callbackContext;
19183 hdd_context_t *pHddCtx;
19184
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019185 ENTER();
19186
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019187 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19188 {
19189 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19190 FL("Invalid adapter or adapter has invalid magic"));
19191 return;
19192 }
19193
19194 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19195 if (0 != wlan_hdd_validate_context(pHddCtx))
19196 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019197 return;
19198 }
19199
c_hpothub53c45d2014-08-18 16:53:14 +053019200 if (VOS_STATUS_SUCCESS != status)
19201 {
19202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019203 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019204 pHddCtx->isPnoEnable = FALSE;
19205 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019206
19207 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19208 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019209 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019210}
19211
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019212#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19213 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19214/**
19215 * hdd_config_sched_scan_plan() - configures the sched scan plans
19216 * from the framework.
19217 * @pno_req: pointer to PNO scan request
19218 * @request: pointer to scan request from framework
19219 *
19220 * Return: None
19221 */
19222static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19223 struct cfg80211_sched_scan_request *request,
19224 hdd_context_t *hdd_ctx)
19225{
19226 v_U32_t i = 0;
19227
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019228 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019229 for (i = 0; i < request->n_scan_plans; i++)
19230 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019231 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19232 request->scan_plans[i].iterations;
19233 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19234 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019235 }
19236}
19237#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019238static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019239 struct cfg80211_sched_scan_request *request,
19240 hdd_context_t *hdd_ctx)
19241{
19242 v_U32_t i, temp_int;
19243 /* Driver gets only one time interval which is hardcoded in
19244 * supplicant for 10000ms. Taking power consumption into account 6
19245 * timers will be used, Timervalue is increased exponentially
19246 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19247 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19248 * If it is set to 0 only one timer will be used and PNO scan cycle
19249 * will be repeated after each interval specified by supplicant
19250 * till PNO is disabled.
19251 */
19252 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019253 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019254 HDD_PNO_SCAN_TIMERS_SET_ONE;
19255 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019256 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019257 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19258
19259 temp_int = (request->interval)/1000;
19260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19261 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19262 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019263 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019264 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019265 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019266 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019267 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019268 temp_int *= 2;
19269 }
19270 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019271 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019272}
19273#endif
19274
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019275/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019276 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19277 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019278 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019279static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019280 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19281{
19282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019283 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019284 hdd_context_t *pHddCtx;
19285 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019286 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019287 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19288 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019289 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19290 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019291 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019292 hdd_config_t *pConfig = NULL;
19293 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019294
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019295 ENTER();
19296
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019297 if (NULL == pAdapter)
19298 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019300 "%s: HDD adapter is Null", __func__);
19301 return -ENODEV;
19302 }
19303
19304 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019305 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019306
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019307 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019308 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019309 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019310 }
19311
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019312 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019313 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19314 if (NULL == hHal)
19315 {
19316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19317 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019318 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019319 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019320 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19321 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19322 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019323 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019324 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019325 {
19326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19327 "%s: aborting the existing scan is unsuccessfull", __func__);
19328 return -EBUSY;
19329 }
19330
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019331 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019332 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019334 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019335 return -EBUSY;
19336 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019337
c_hpothu37f21312014-04-09 21:49:54 +053019338 if (TRUE == pHddCtx->isPnoEnable)
19339 {
19340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19341 FL("already PNO is enabled"));
19342 return -EBUSY;
19343 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019344
19345 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19346 {
19347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19348 "%s: abort ROC failed ", __func__);
19349 return -EBUSY;
19350 }
19351
c_hpothu37f21312014-04-09 21:49:54 +053019352 pHddCtx->isPnoEnable = TRUE;
19353
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019354 pnoRequest.enable = 1; /*Enable PNO */
19355 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019356
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019357 if (( !pnoRequest.ucNetworksCount ) ||
19358 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019359 {
19360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019361 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019362 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019363 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019364 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019365 goto error;
19366 }
19367
19368 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19369 {
19370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019371 "%s: Incorrect number of channels %d",
19372 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019373 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019374 goto error;
19375 }
19376
19377 /* Framework provides one set of channels(all)
19378 * common for all saved profile */
19379 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19380 channels_allowed, &num_channels_allowed))
19381 {
19382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19383 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019384 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019385 goto error;
19386 }
19387 /* Checking each channel against allowed channel list */
19388 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019389 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019390 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019391 char chList [(request->n_channels*5)+1];
19392 int len;
19393 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019394 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019395 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019396 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019397 if (request->channels[i]->hw_value == channels_allowed[indx])
19398 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019399 if ((!pConfig->enableDFSPnoChnlScan) &&
19400 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19401 {
19402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19403 "%s : Dropping DFS channel : %d",
19404 __func__,channels_allowed[indx]);
19405 num_ignore_dfs_ch++;
19406 break;
19407 }
19408
Nirav Shah80830bf2013-12-31 16:35:12 +053019409 valid_ch[num_ch++] = request->channels[i]->hw_value;
19410 len += snprintf(chList+len, 5, "%d ",
19411 request->channels[i]->hw_value);
19412 break ;
19413 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019414 }
19415 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019416 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019417
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019418 /*If all channels are DFS and dropped, then ignore the PNO request*/
19419 if (num_ignore_dfs_ch == request->n_channels)
19420 {
19421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19422 "%s : All requested channels are DFS channels", __func__);
19423 ret = -EINVAL;
19424 goto error;
19425 }
19426 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019427
19428 pnoRequest.aNetworks =
19429 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19430 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019431 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019432 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19433 FL("failed to allocate memory aNetworks %u"),
19434 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19435 goto error;
19436 }
19437 vos_mem_zero(pnoRequest.aNetworks,
19438 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19439
19440 /* Filling per profile params */
19441 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19442 {
19443 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019444 request->match_sets[i].ssid.ssid_len;
19445
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019446 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19447 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019448 {
19449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019450 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019451 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019452 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019453 goto error;
19454 }
19455
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019456 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019457 request->match_sets[i].ssid.ssid,
19458 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19460 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019461 i, pnoRequest.aNetworks[i].ssId.ssId);
19462 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19463 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19464 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019465
19466 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019467 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19468 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019469
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019470 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019471 }
19472
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019473 for (i = 0; i < request->n_ssids; i++)
19474 {
19475 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019476 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019477 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019478 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019479 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019480 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019481 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019482 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019483 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019484 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019485 break;
19486 }
19487 j++;
19488 }
19489 }
19490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19491 "Number of hidden networks being Configured = %d",
19492 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019494 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019495
19496 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19497 if (pnoRequest.p24GProbeTemplate == NULL)
19498 {
19499 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19500 FL("failed to allocate memory p24GProbeTemplate %u"),
19501 SIR_PNO_MAX_PB_REQ_SIZE);
19502 goto error;
19503 }
19504
19505 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19506 if (pnoRequest.p5GProbeTemplate == NULL)
19507 {
19508 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19509 FL("failed to allocate memory p5GProbeTemplate %u"),
19510 SIR_PNO_MAX_PB_REQ_SIZE);
19511 goto error;
19512 }
19513
19514 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19515 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19516
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019517 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19518 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019519 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019520 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19521 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19522 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019523
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019524 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19525 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19526 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019527 }
19528
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019529 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019530
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019531 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019532
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019533 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019534 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19535 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019536 pAdapter->pno_req_status = 0;
19537
Nirav Shah80830bf2013-12-31 16:35:12 +053019538 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19539 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019540 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19541 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019542
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019543 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019544 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019545 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19546 if (eHAL_STATUS_SUCCESS != status)
19547 {
19548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019549 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019550 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019551 goto error;
19552 }
19553
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019554 ret = wait_for_completion_timeout(
19555 &pAdapter->pno_comp_var,
19556 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19557 if (0 >= ret)
19558 {
19559 // Did not receive the response for PNO enable in time.
19560 // Assuming the PNO enable was success.
19561 // Returning error from here, because we timeout, results
19562 // in side effect of Wifi (Wifi Setting) not to work.
19563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19564 FL("Timed out waiting for PNO to be Enabled"));
19565 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019566 }
19567
19568 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019569 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019570
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019571error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19573 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019574 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019575 if (pnoRequest.aNetworks)
19576 vos_mem_free(pnoRequest.aNetworks);
19577 if (pnoRequest.p24GProbeTemplate)
19578 vos_mem_free(pnoRequest.p24GProbeTemplate);
19579 if (pnoRequest.p5GProbeTemplate)
19580 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019581
19582 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019583 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019584}
19585
19586/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019587 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19588 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019589 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019590static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19591 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19592{
19593 int ret;
19594
19595 vos_ssr_protect(__func__);
19596 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19597 vos_ssr_unprotect(__func__);
19598
19599 return ret;
19600}
19601
19602/*
19603 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19604 * Function to disable PNO
19605 */
19606static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019607 struct net_device *dev)
19608{
19609 eHalStatus status = eHAL_STATUS_FAILURE;
19610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19611 hdd_context_t *pHddCtx;
19612 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019613 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019614 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019615
19616 ENTER();
19617
19618 if (NULL == pAdapter)
19619 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019621 "%s: HDD adapter is Null", __func__);
19622 return -ENODEV;
19623 }
19624
19625 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019626
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019627 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019628 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019629 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019630 "%s: HDD context is Null", __func__);
19631 return -ENODEV;
19632 }
19633
19634 /* The return 0 is intentional when isLogpInProgress and
19635 * isLoadUnloadInProgress. We did observe a crash due to a return of
19636 * failure in sched_scan_stop , especially for a case where the unload
19637 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19638 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19639 * success. If it returns a failure , then its next invocation due to the
19640 * clean up of the second interface will have the dev pointer corresponding
19641 * to the first one leading to a crash.
19642 */
19643 if (pHddCtx->isLogpInProgress)
19644 {
19645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19646 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019647 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019648 return ret;
19649 }
19650
Mihir Shete18156292014-03-11 15:38:30 +053019651 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019652 {
19653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19654 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19655 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019656 }
19657
19658 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19659 if (NULL == hHal)
19660 {
19661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19662 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019663 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019664 }
19665
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019666 pnoRequest.enable = 0; /* Disable PNO */
19667 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019668
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019669 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19670 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19671 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019672
19673 INIT_COMPLETION(pAdapter->pno_comp_var);
19674 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19675 pnoRequest.callbackContext = pAdapter;
19676 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019677 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019678 pAdapter->sessionId,
19679 NULL, pAdapter);
19680 if (eHAL_STATUS_SUCCESS != status)
19681 {
19682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19683 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019684 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019685 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019686 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019687 ret = wait_for_completion_timeout(
19688 &pAdapter->pno_comp_var,
19689 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19690 if (0 >= ret)
19691 {
19692 // Did not receive the response for PNO disable in time.
19693 // Assuming the PNO disable was success.
19694 // Returning error from here, because we timeout, results
19695 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019697 FL("Timed out waiting for PNO to be disabled"));
19698 ret = 0;
19699 }
19700
19701 ret = pAdapter->pno_req_status;
19702 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019703
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019704error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019706 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019707
19708 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019709 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019710}
19711
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019712/*
19713 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19714 * NL interface to disable PNO
19715 */
19716static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19717 struct net_device *dev)
19718{
19719 int ret;
19720
19721 vos_ssr_protect(__func__);
19722 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19723 vos_ssr_unprotect(__func__);
19724
19725 return ret;
19726}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019727#endif /*FEATURE_WLAN_SCAN_PNO*/
19728
19729
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019730#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019731#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019732static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19733 struct net_device *dev,
19734 u8 *peer, u8 action_code,
19735 u8 dialog_token,
19736 u16 status_code, u32 peer_capability,
19737 const u8 *buf, size_t len)
19738#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019739#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19740 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019741static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19742 struct net_device *dev,
19743 const u8 *peer, u8 action_code,
19744 u8 dialog_token, u16 status_code,
19745 u32 peer_capability, bool initiator,
19746 const u8 *buf, size_t len)
19747#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19748static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19749 struct net_device *dev,
19750 const u8 *peer, u8 action_code,
19751 u8 dialog_token, u16 status_code,
19752 u32 peer_capability, const u8 *buf,
19753 size_t len)
19754#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19755static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19756 struct net_device *dev,
19757 u8 *peer, u8 action_code,
19758 u8 dialog_token,
19759 u16 status_code, u32 peer_capability,
19760 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019761#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019762static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19763 struct net_device *dev,
19764 u8 *peer, u8 action_code,
19765 u8 dialog_token,
19766 u16 status_code, const u8 *buf,
19767 size_t len)
19768#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019769#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019770{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019771 hdd_adapter_t *pAdapter;
19772 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019773 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019774 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019775 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019776 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019777 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019778 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019779#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019780 u32 peer_capability = 0;
19781#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019782 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019783 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019784 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019785
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019786 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19787 if (NULL == pAdapter)
19788 {
19789 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19790 "%s: Adapter is NULL",__func__);
19791 return -EINVAL;
19792 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019793 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19794 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19795 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019796
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019797 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019798 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019799 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019800 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019801 "Invalid arguments");
19802 return -EINVAL;
19803 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019804
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019805 if (pHddCtx->isLogpInProgress)
19806 {
19807 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19808 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019809 wlan_hdd_tdls_set_link_status(pAdapter,
19810 peer,
19811 eTDLS_LINK_IDLE,
19812 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019813 return -EBUSY;
19814 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019815
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019816 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19817 {
19818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19819 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19820 return -EAGAIN;
19821 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019822
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019823 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19824 if (!pHddTdlsCtx) {
19825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19826 "%s: pHddTdlsCtx not valid.", __func__);
Hanumanth Reddy Pothula36dfa522018-03-12 16:42:08 +053019827 return -EINVAL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019828 }
19829
Hoonki Lee27511902013-03-14 18:19:06 -070019830 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019831 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019832 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019833 "%s: TDLS mode is disabled OR not enabled in FW."
19834 MAC_ADDRESS_STR " action %d declined.",
19835 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019836 return -ENOTSUPP;
19837 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019838
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019839 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19840
19841 if( NULL == pHddStaCtx )
19842 {
19843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19844 "%s: HDD station context NULL ",__func__);
19845 return -EINVAL;
19846 }
19847
19848 /* STA should be connected and authenticated
19849 * before sending any TDLS frames
19850 */
19851 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19852 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19853 {
19854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19855 "STA is not connected or unauthenticated. "
19856 "connState %u, uIsAuthenticated %u",
19857 pHddStaCtx->conn_info.connState,
19858 pHddStaCtx->conn_info.uIsAuthenticated);
19859 return -EAGAIN;
19860 }
19861
Hoonki Lee27511902013-03-14 18:19:06 -070019862 /* other than teardown frame, other mgmt frames are not sent if disabled */
19863 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19864 {
19865 /* if tdls_mode is disabled to respond to peer's request */
19866 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19867 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019868 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019869 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019870 " TDLS mode is disabled. action %d declined.",
19871 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019872
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019873 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019874 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019875
19876 if (vos_max_concurrent_connections_reached())
19877 {
19878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19879 return -EINVAL;
19880 }
Hoonki Lee27511902013-03-14 18:19:06 -070019881 }
19882
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019883 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19884 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019885 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019886 {
19887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019888 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019889 " TDLS setup is ongoing. action %d declined.",
19890 __func__, MAC_ADDR_ARRAY(peer), action_code);
19891 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019892 }
19893 }
19894
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019895 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19896 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019897 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019898 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19899 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019900 {
19901 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19902 we return error code at 'add_station()'. Hence we have this
19903 check again in addtion to add_station().
19904 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019905 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019906 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19908 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019909 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19910 __func__, MAC_ADDR_ARRAY(peer), action_code,
19911 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019912 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019913 }
19914 else
19915 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019916 /* maximum reached. tweak to send error code to peer and return
19917 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019918 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19920 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019921 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19922 __func__, MAC_ADDR_ARRAY(peer), status_code,
19923 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019924 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019925 /* fall through to send setup resp with failure status
19926 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019927 }
19928 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019929 else
19930 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019931 mutex_lock(&pHddCtx->tdls_lock);
19932 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019933 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019934 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019935 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019936 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019937 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19938 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019939 return -EPERM;
19940 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019941 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019942 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019943 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019944
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019945 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019946 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019947 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19948 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019949
Hoonki Leea34dd892013-02-05 22:56:02 -080019950 /*Except teardown responder will not be used so just make 0*/
19951 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019952 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019953 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019954
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019955 mutex_lock(&pHddCtx->tdls_lock);
19956 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019957
19958 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19959 responder = pTdlsPeer->is_responder;
19960 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019961 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019962 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019963 "%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 -070019964 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19965 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019966 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019967 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019968 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019969 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019970 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019971
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019972 /* Discard TDLS setup if peer is removed by user app */
19973 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19974 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19975 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19976 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19977
19978 mutex_lock(&pHddCtx->tdls_lock);
19979 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19980 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19981 mutex_unlock(&pHddCtx->tdls_lock);
19982 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19983 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19984 MAC_ADDR_ARRAY(peer), action_code);
19985 return -EINVAL;
19986 }
19987 mutex_unlock(&pHddCtx->tdls_lock);
19988 }
19989
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019990 /* For explicit trigger of DIS_REQ come out of BMPS for
19991 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019992 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019993 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019994 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19995 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019996 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019997 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019999 "%s: Sending frame action_code %u.Disable BMPS", __func__,
20000 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020001 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
20002 if (status != VOS_STATUS_SUCCESS) {
20003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053020004 } else {
20005 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020006 }
Hoonki Lee14621352013-04-16 17:51:19 -070020007 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020008 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020009 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20011 }
20012 }
Hoonki Lee14621352013-04-16 17:51:19 -070020013 }
20014
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020015 /* make sure doesn't call send_mgmt() while it is pending */
20016 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20017 {
20018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020019 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020020 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020021 ret = -EBUSY;
20022 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020023 }
20024
20025 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020026 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20027
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020028 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20029 pAdapter->sessionId, peer, action_code, dialog_token,
20030 status_code, peer_capability, (tANI_U8 *)buf, len,
20031 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020032
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020033 if (VOS_STATUS_SUCCESS != status)
20034 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20036 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020037 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020038 ret = -EINVAL;
20039 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020040 }
20041
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020042 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20043 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20044 WAIT_TIME_TDLS_MGMT);
20045
Hoonki Leed37cbb32013-04-20 00:31:14 -070020046 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20047 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20048
20049 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020050 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020052 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020053 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020054 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020055
20056 if (pHddCtx->isLogpInProgress)
20057 {
20058 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20059 "%s: LOGP in Progress. Ignore!!!", __func__);
20060 return -EAGAIN;
20061 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020062 if (rc <= 0)
20063 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20064 WLAN_LOG_INDICATOR_HOST_DRIVER,
20065 WLAN_LOG_REASON_HDD_TIME_OUT,
20066 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020067
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020068 ret = -EINVAL;
20069 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020070 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020071 else
20072 {
20073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20074 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20075 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20076 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020077
Gopichand Nakkala05922802013-03-14 12:23:19 -070020078 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020079 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020080 ret = max_sta_failed;
20081 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020082 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020083
Hoonki Leea34dd892013-02-05 22:56:02 -080020084 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20085 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020086 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020087 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20088 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020089 }
20090 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20091 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020092 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20094 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020095 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020096
20097 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020098
20099tx_failed:
20100 /* add_station will be called before sending TDLS_SETUP_REQ and
20101 * TDLS_SETUP_RSP and as part of add_station driver will enable
20102 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20103 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20104 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20105 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20106 */
20107
20108 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20109 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20110 wlan_hdd_tdls_check_bmps(pAdapter);
20111 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020112}
20113
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020114#if TDLS_MGMT_VERSION2
20115static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20116 u8 *peer, u8 action_code, u8 dialog_token,
20117 u16 status_code, u32 peer_capability,
20118 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020119#else /* TDLS_MGMT_VERSION2 */
20120#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20121static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20122 struct net_device *dev,
20123 const u8 *peer, u8 action_code,
20124 u8 dialog_token, u16 status_code,
20125 u32 peer_capability, bool initiator,
20126 const u8 *buf, size_t len)
20127#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20128static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20129 struct net_device *dev,
20130 const u8 *peer, u8 action_code,
20131 u8 dialog_token, u16 status_code,
20132 u32 peer_capability, const u8 *buf,
20133 size_t len)
20134#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20135static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20136 struct net_device *dev,
20137 u8 *peer, u8 action_code,
20138 u8 dialog_token,
20139 u16 status_code, u32 peer_capability,
20140 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020141#else
20142static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20143 u8 *peer, u8 action_code, u8 dialog_token,
20144 u16 status_code, const u8 *buf, size_t len)
20145#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020146#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020147{
20148 int ret;
20149
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020150 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020151#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020152 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20153 dialog_token, status_code,
20154 peer_capability, buf, len);
20155#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020156#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20157 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020158 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20159 dialog_token, status_code,
20160 peer_capability, initiator,
20161 buf, len);
20162#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20163 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20164 dialog_token, status_code,
20165 peer_capability, buf, len);
20166#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20167 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20168 dialog_token, status_code,
20169 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020170#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020171 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20172 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020173#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020174#endif
20175 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020176
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020177 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020178}
Atul Mittal115287b2014-07-08 13:26:33 +053020179
20180int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20182 const u8 *peer,
20183#else
Atul Mittal115287b2014-07-08 13:26:33 +053020184 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020185#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020186 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020187 cfg80211_exttdls_callback callback)
20188{
20189
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020190 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020191 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020192 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20194 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20195 __func__, MAC_ADDR_ARRAY(peer));
20196
20197 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20198 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20199
20200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020201 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20202 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20203 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020204 return -ENOTSUPP;
20205 }
20206
20207 /* To cater the requirement of establishing the TDLS link
20208 * irrespective of the data traffic , get an entry of TDLS peer.
20209 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020210 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020211 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20212 if (pTdlsPeer == NULL) {
20213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20214 "%s: peer " MAC_ADDRESS_STR " not existing",
20215 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020216 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020217 return -EINVAL;
20218 }
20219
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020220 /* check FW TDLS Off Channel capability */
20221 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020222 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020223 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020224 {
20225 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20226 pTdlsPeer->peerParams.global_operating_class =
20227 tdls_peer_params->global_operating_class;
20228 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20229 pTdlsPeer->peerParams.min_bandwidth_kbps =
20230 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020231 /* check configured channel is valid, non dfs and
20232 * not current operating channel */
20233 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20234 tdls_peer_params->channel)) &&
20235 (pHddStaCtx) &&
20236 (tdls_peer_params->channel !=
20237 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020238 {
20239 pTdlsPeer->isOffChannelConfigured = TRUE;
20240 }
20241 else
20242 {
20243 pTdlsPeer->isOffChannelConfigured = FALSE;
20244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20245 "%s: Configured Tdls Off Channel is not valid", __func__);
20246
20247 }
20248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020249 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20250 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020251 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020252 pTdlsPeer->isOffChannelConfigured,
20253 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020254 }
20255 else
20256 {
20257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020258 "%s: TDLS off channel FW capability %d, "
20259 "host capab %d or Invalid TDLS Peer Params", __func__,
20260 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20261 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020262 }
20263
Atul Mittal115287b2014-07-08 13:26:33 +053020264 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20265
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020266 mutex_unlock(&pHddCtx->tdls_lock);
20267
Atul Mittal115287b2014-07-08 13:26:33 +053020268 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20269 " %s TDLS Add Force Peer Failed",
20270 __func__);
20271 return -EINVAL;
20272 }
20273 /*EXT TDLS*/
20274
20275 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020276 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20278 " %s TDLS set callback Failed",
20279 __func__);
20280 return -EINVAL;
20281 }
20282
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020283 mutex_unlock(&pHddCtx->tdls_lock);
20284
Atul Mittal115287b2014-07-08 13:26:33 +053020285 return(0);
20286
20287}
20288
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020289int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20290#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20291 const u8 *peer
20292#else
20293 u8 *peer
20294#endif
20295)
Atul Mittal115287b2014-07-08 13:26:33 +053020296{
20297
20298 hddTdlsPeer_t *pTdlsPeer;
20299 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020300
Atul Mittal115287b2014-07-08 13:26:33 +053020301 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20302 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20303 __func__, MAC_ADDR_ARRAY(peer));
20304
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020305 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20307 return -EINVAL;
20308 }
20309
Atul Mittal115287b2014-07-08 13:26:33 +053020310 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20311 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20312
20313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020314 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20315 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20316 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020317 return -ENOTSUPP;
20318 }
20319
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020320 mutex_lock(&pHddCtx->tdls_lock);
20321 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020322
20323 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020324 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020325 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020326 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020327 __func__, MAC_ADDR_ARRAY(peer));
20328 return -EINVAL;
20329 }
20330 else {
20331 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20332 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020333 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20334 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020335 /* if channel switch is configured, reset
20336 the channel for this peer */
20337 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20338 {
20339 pTdlsPeer->peerParams.channel = 0;
20340 pTdlsPeer->isOffChannelConfigured = FALSE;
20341 }
Atul Mittal115287b2014-07-08 13:26:33 +053020342 }
20343
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020344 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020345 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020347 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020348 }
Atul Mittal115287b2014-07-08 13:26:33 +053020349
20350 /*EXT TDLS*/
20351
20352 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020353 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20355 " %s TDLS set callback Failed",
20356 __func__);
20357 return -EINVAL;
20358 }
Atul Mittal115287b2014-07-08 13:26:33 +053020359
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020360 mutex_unlock(&pHddCtx->tdls_lock);
20361
20362 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020363}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020364static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020365#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20366 const u8 *peer,
20367#else
20368 u8 *peer,
20369#endif
20370 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020371{
20372 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20373 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020374 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020375 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020376
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020377 ENTER();
20378
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020379 if (!pAdapter) {
20380 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20381 return -EINVAL;
20382 }
20383
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020384 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20385 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20386 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020387 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020388 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020390 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020391 return -EINVAL;
20392 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020393
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020394 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020395 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020396 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020397 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020398 }
20399
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020400
20401 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020402 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020403 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020405 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20406 "Cannot process TDLS commands",
20407 pHddCtx->cfg_ini->fEnableTDLSSupport,
20408 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020409 return -ENOTSUPP;
20410 }
20411
20412 switch (oper) {
20413 case NL80211_TDLS_ENABLE_LINK:
20414 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020415 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020416 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020417 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20418 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020419 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020420 tANI_U16 numCurrTdlsPeers = 0;
20421 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020422 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020423 tSirMacAddr peerMac;
20424 int channel;
20425 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020426
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20428 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20429 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020430
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020431 mutex_lock(&pHddCtx->tdls_lock);
20432 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020433 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020434 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020435 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020436 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20437 " (oper %d) not exsting. ignored",
20438 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20439 return -EINVAL;
20440 }
20441
20442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20443 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20444 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20445 "NL80211_TDLS_ENABLE_LINK");
20446
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020447 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20448 {
20449 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20450 MAC_ADDRESS_STR " failed",
20451 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020452 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020453 return -EINVAL;
20454 }
20455
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020456 /* before starting tdls connection, set tdls
20457 * off channel established status to default value */
20458 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020459
20460 mutex_unlock(&pHddCtx->tdls_lock);
20461
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020462 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020463 /* TDLS Off Channel, Disable tdls channel switch,
20464 when there are more than one tdls link */
20465 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020466 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020467 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020468 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020469 /* get connected peer and send disable tdls off chan */
20470 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020471 if ((connPeer) &&
20472 (connPeer->isOffChannelSupported == TRUE) &&
20473 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020474 {
20475 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20476 "%s: More then one peer connected, Disable "
20477 "TDLS channel switch", __func__);
20478
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020479 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020480 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20481 channel = connPeer->peerParams.channel;
20482
20483 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020484
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020485 ret = sme_SendTdlsChanSwitchReq(
20486 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020487 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020488 peerMac,
20489 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020490 TDLS_OFF_CHANNEL_BW_OFFSET,
20491 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020492 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020493 hddLog(VOS_TRACE_LEVEL_ERROR,
20494 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020495 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020496 }
20497 else
20498 {
20499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20500 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020501 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020502 "isOffChannelConfigured %d",
20503 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020504 (connPeer ? (connPeer->isOffChannelSupported)
20505 : -1),
20506 (connPeer ? (connPeer->isOffChannelConfigured)
20507 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020508 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020509 }
20510 }
20511
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020512 mutex_lock(&pHddCtx->tdls_lock);
20513 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20514 if ( NULL == pTdlsPeer ) {
20515 mutex_unlock(&pHddCtx->tdls_lock);
20516 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20517 "%s: " MAC_ADDRESS_STR
20518 " (oper %d) peer got freed in other context. ignored",
20519 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20520 return -EINVAL;
20521 }
20522 peer_status = pTdlsPeer->link_status;
20523 mutex_unlock(&pHddCtx->tdls_lock);
20524
20525 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020526 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020527 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020528
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020529 if (0 != wlan_hdd_tdls_get_link_establish_params(
20530 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020531 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020532 return -EINVAL;
20533 }
20534 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020535
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020536 ret = sme_SendTdlsLinkEstablishParams(
20537 WLAN_HDD_GET_HAL_CTX(pAdapter),
20538 pAdapter->sessionId, peer,
20539 &tdlsLinkEstablishParams);
20540 if (ret != VOS_STATUS_SUCCESS) {
20541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20542 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020543 /* Send TDLS peer UAPSD capabilities to the firmware and
20544 * register with the TL on after the response for this operation
20545 * is received .
20546 */
20547 ret = wait_for_completion_interruptible_timeout(
20548 &pAdapter->tdls_link_establish_req_comp,
20549 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020550
20551 mutex_lock(&pHddCtx->tdls_lock);
20552 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20553 if ( NULL == pTdlsPeer ) {
20554 mutex_unlock(&pHddCtx->tdls_lock);
20555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20556 "%s %d: " MAC_ADDRESS_STR
20557 " (oper %d) peer got freed in other context. ignored",
20558 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20559 (int)oper);
20560 return -EINVAL;
20561 }
20562 peer_status = pTdlsPeer->link_status;
20563 mutex_unlock(&pHddCtx->tdls_lock);
20564
20565 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020566 {
20567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020568 FL("Link Establish Request Failed Status %ld"),
20569 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020570 return -EINVAL;
20571 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020572 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020573
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020574 mutex_lock(&pHddCtx->tdls_lock);
20575 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20576 if ( NULL == pTdlsPeer ) {
20577 mutex_unlock(&pHddCtx->tdls_lock);
20578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20579 "%s: " MAC_ADDRESS_STR
20580 " (oper %d) peer got freed in other context. ignored",
20581 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20582 return -EINVAL;
20583 }
20584
Atul Mittal115287b2014-07-08 13:26:33 +053020585 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20586 eTDLS_LINK_CONNECTED,
20587 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020588 staDesc.ucSTAId = pTdlsPeer->staId;
20589 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020590
20591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20592 "%s: tdlsLinkEstablishParams of peer "
20593 MAC_ADDRESS_STR "uapsdQueues: %d"
20594 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20595 "isResponder: %d peerstaId: %d",
20596 __func__,
20597 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20598 tdlsLinkEstablishParams.uapsdQueues,
20599 tdlsLinkEstablishParams.qos,
20600 tdlsLinkEstablishParams.maxSp,
20601 tdlsLinkEstablishParams.isBufSta,
20602 tdlsLinkEstablishParams.isOffChannelSupported,
20603 tdlsLinkEstablishParams.isResponder,
20604 pTdlsPeer->staId);
20605
20606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20607 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20608 __func__,
20609 staDesc.ucSTAId,
20610 staDesc.ucQosEnabled);
20611
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020612 ret = WLANTL_UpdateTdlsSTAClient(
20613 pHddCtx->pvosContext,
20614 &staDesc);
20615 if (ret != VOS_STATUS_SUCCESS) {
20616 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20617 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020618
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020619 /* Mark TDLS client Authenticated .*/
20620 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20621 pTdlsPeer->staId,
20622 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020623 if (VOS_STATUS_SUCCESS == status)
20624 {
Hoonki Lee14621352013-04-16 17:51:19 -070020625 if (pTdlsPeer->is_responder == 0)
20626 {
20627 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020628 tdlsConnInfo_t *tdlsInfo;
20629
20630 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20631
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020632 if (!vos_timer_is_initialized(
20633 &pTdlsPeer->initiatorWaitTimeoutTimer))
20634 {
20635 /* Initialize initiator wait callback */
20636 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020637 &pTdlsPeer->initiatorWaitTimeoutTimer,
20638 VOS_TIMER_TYPE_SW,
20639 wlan_hdd_tdls_initiator_wait_cb,
20640 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020641 }
Hoonki Lee14621352013-04-16 17:51:19 -070020642 wlan_hdd_tdls_timer_restart(pAdapter,
20643 &pTdlsPeer->initiatorWaitTimeoutTimer,
20644 WAIT_TIME_TDLS_INITIATOR);
20645 /* suspend initiator TX until it receives direct packet from the
20646 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020647 ret = WLANTL_SuspendDataTx(
20648 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20649 &staId, NULL);
20650 if (ret != VOS_STATUS_SUCCESS) {
20651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20652 }
Hoonki Lee14621352013-04-16 17:51:19 -070020653 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020654
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020655 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020656 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020657 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020658 suppChannelLen =
20659 tdlsLinkEstablishParams.supportedChannelsLen;
20660
20661 if ((suppChannelLen > 0) &&
20662 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20663 {
20664 tANI_U8 suppPeerChannel = 0;
20665 int i = 0;
20666 for (i = 0U; i < suppChannelLen; i++)
20667 {
20668 suppPeerChannel =
20669 tdlsLinkEstablishParams.supportedChannels[i];
20670
20671 pTdlsPeer->isOffChannelSupported = FALSE;
20672 if (suppPeerChannel ==
20673 pTdlsPeer->peerParams.channel)
20674 {
20675 pTdlsPeer->isOffChannelSupported = TRUE;
20676 break;
20677 }
20678 }
20679 }
20680 else
20681 {
20682 pTdlsPeer->isOffChannelSupported = FALSE;
20683 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020684 }
20685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20686 "%s: TDLS channel switch request for channel "
20687 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020688 "%d isOffChannelSupported %d", __func__,
20689 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020690 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020691 suppChannelLen,
20692 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020693
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020694 /* TDLS Off Channel, Enable tdls channel switch,
20695 when their is only one tdls link and it supports */
20696 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20697 if ((numCurrTdlsPeers == 1) &&
20698 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20699 (TRUE == pTdlsPeer->isOffChannelConfigured))
20700 {
20701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20702 "%s: Send TDLS channel switch request for channel %d",
20703 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020704
20705 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020706 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20707 channel = pTdlsPeer->peerParams.channel;
20708
20709 mutex_unlock(&pHddCtx->tdls_lock);
20710
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020711 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20712 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020713 peerMac,
20714 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020715 TDLS_OFF_CHANNEL_BW_OFFSET,
20716 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020717 if (ret != VOS_STATUS_SUCCESS) {
20718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20719 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020720 }
20721 else
20722 {
20723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20724 "%s: TDLS channel switch request not sent"
20725 " numCurrTdlsPeers %d "
20726 "isOffChannelSupported %d "
20727 "isOffChannelConfigured %d",
20728 __func__, numCurrTdlsPeers,
20729 pTdlsPeer->isOffChannelSupported,
20730 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020731 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020732 }
20733
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020734 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020735 else
20736 mutex_unlock(&pHddCtx->tdls_lock);
20737
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020738 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020739
20740 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020741 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20742 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020743 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020744 int ac;
20745 uint8 ucAc[4] = { WLANTL_AC_VO,
20746 WLANTL_AC_VI,
20747 WLANTL_AC_BK,
20748 WLANTL_AC_BE };
20749 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20750 for(ac=0; ac < 4; ac++)
20751 {
20752 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20753 pTdlsPeer->staId, ucAc[ac],
20754 tlTid[ac], tlTid[ac], 0, 0,
20755 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020756 if (status != VOS_STATUS_SUCCESS) {
20757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20758 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020759 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020760 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020761 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020762
Bhargav Shah66896792015-10-01 18:17:37 +053020763 /* stop TCP delack timer if TDLS is enable */
20764 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20765 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020766 hdd_wlan_tdls_enable_link_event(peer,
20767 pTdlsPeer->isOffChannelSupported,
20768 pTdlsPeer->isOffChannelConfigured,
20769 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020770 }
20771 break;
20772 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020773 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020774 tANI_U16 numCurrTdlsPeers = 0;
20775 hddTdlsPeer_t *connPeer = NULL;
20776
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20778 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20779 __func__, MAC_ADDR_ARRAY(peer));
20780
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020781 mutex_lock(&pHddCtx->tdls_lock);
20782 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020783
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020784
Sunil Dutt41de4e22013-11-14 18:09:02 +053020785 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020786 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20788 " (oper %d) not exsting. ignored",
20789 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20790 return -EINVAL;
20791 }
20792
20793 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20794 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20795 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20796 "NL80211_TDLS_DISABLE_LINK");
20797
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020798 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020799 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020800 long status;
20801
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020802 /* set tdls off channel status to false for this peer */
20803 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020804 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20805 eTDLS_LINK_TEARING,
20806 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20807 eTDLS_LINK_UNSPECIFIED:
20808 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020809 mutex_unlock(&pHddCtx->tdls_lock);
20810
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020811 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20812
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020813 status = sme_DeleteTdlsPeerSta(
20814 WLAN_HDD_GET_HAL_CTX(pAdapter),
20815 pAdapter->sessionId, peer );
20816 if (status != VOS_STATUS_SUCCESS) {
20817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20818 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020819
20820 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20821 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020822
20823 mutex_lock(&pHddCtx->tdls_lock);
20824 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20825 if ( NULL == pTdlsPeer ) {
20826 mutex_unlock(&pHddCtx->tdls_lock);
20827 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20828 " peer was freed in other context",
20829 __func__, MAC_ADDR_ARRAY(peer));
20830 return -EINVAL;
20831 }
20832
Atul Mittal271a7652014-09-12 13:18:22 +053020833 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020834 eTDLS_LINK_IDLE,
20835 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020836 mutex_unlock(&pHddCtx->tdls_lock);
20837
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020838 if (status <= 0)
20839 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020840 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20841 "%s: Del station failed status %ld",
20842 __func__, status);
20843 return -EPERM;
20844 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020845
20846 /* TDLS Off Channel, Enable tdls channel switch,
20847 when their is only one tdls link and it supports */
20848 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20849 if (numCurrTdlsPeers == 1)
20850 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020851 tSirMacAddr peerMac;
20852 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020853
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020854 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020855 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020856
20857 if (connPeer == NULL) {
20858 mutex_unlock(&pHddCtx->tdls_lock);
20859 hddLog(VOS_TRACE_LEVEL_ERROR,
20860 "%s connPeer is NULL", __func__);
20861 return -EINVAL;
20862 }
20863
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020864 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20865 channel = connPeer->peerParams.channel;
20866
20867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20868 "%s: TDLS channel switch "
20869 "isOffChannelSupported %d "
20870 "isOffChannelConfigured %d "
20871 "isOffChannelEstablished %d",
20872 __func__,
20873 (connPeer ? connPeer->isOffChannelSupported : -1),
20874 (connPeer ? connPeer->isOffChannelConfigured : -1),
20875 (connPeer ? connPeer->isOffChannelEstablished : -1));
20876
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020877 if ((connPeer) &&
20878 (connPeer->isOffChannelSupported == TRUE) &&
20879 (connPeer->isOffChannelConfigured == TRUE))
20880 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020881 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020882 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020883 status = sme_SendTdlsChanSwitchReq(
20884 WLAN_HDD_GET_HAL_CTX(pAdapter),
20885 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020886 peerMac,
20887 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020888 TDLS_OFF_CHANNEL_BW_OFFSET,
20889 TDLS_CHANNEL_SWITCH_ENABLE);
20890 if (status != VOS_STATUS_SUCCESS) {
20891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20892 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020893 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020894 else
20895 mutex_unlock(&pHddCtx->tdls_lock);
20896 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020897 else
20898 {
20899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20900 "%s: TDLS channel switch request not sent "
20901 "numCurrTdlsPeers %d ",
20902 __func__, numCurrTdlsPeers);
20903 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020904 }
20905 else
20906 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020907 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20909 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020910 }
Bhargav Shah66896792015-10-01 18:17:37 +053020911 if (numCurrTdlsPeers == 0) {
20912 /* start TCP delack timer if TDLS is disable */
20913 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20914 hdd_manage_delack_timer(pHddCtx);
20915 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020916 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020917 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020918 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020919 {
Atul Mittal115287b2014-07-08 13:26:33 +053020920 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020921
Atul Mittal115287b2014-07-08 13:26:33 +053020922 if (0 != status)
20923 {
20924 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020925 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020926 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020927 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020928 break;
20929 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020930 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020931 {
Atul Mittal115287b2014-07-08 13:26:33 +053020932 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20933 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020934 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020935 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020936
Atul Mittal115287b2014-07-08 13:26:33 +053020937 if (0 != status)
20938 {
20939 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020940 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020941 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020942 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020943 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020944 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020945 case NL80211_TDLS_DISCOVERY_REQ:
20946 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020948 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020949 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020950 return -ENOTSUPP;
20951 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20953 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020954 return -ENOTSUPP;
20955 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020956
20957 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020958 return 0;
20959}
Chilam NG571c65a2013-01-19 12:27:36 +053020960
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020961static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020962#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20963 const u8 *peer,
20964#else
20965 u8 *peer,
20966#endif
20967 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020968{
20969 int ret;
20970
20971 vos_ssr_protect(__func__);
20972 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20973 vos_ssr_unprotect(__func__);
20974
20975 return ret;
20976}
20977
Chilam NG571c65a2013-01-19 12:27:36 +053020978int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20979 struct net_device *dev, u8 *peer)
20980{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020981 hddLog(VOS_TRACE_LEVEL_INFO,
20982 "tdls send discover req: "MAC_ADDRESS_STR,
20983 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020984#if TDLS_MGMT_VERSION2
20985 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20986 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20987#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020988#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20989 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20990 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20991#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20992 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20993 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20994#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20995 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20996 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20997#else
Chilam NG571c65a2013-01-19 12:27:36 +053020998 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20999 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053021000#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053021001#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053021002}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080021003#endif
21004
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021005#ifdef WLAN_FEATURE_GTK_OFFLOAD
21006/*
21007 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21008 * Callback rountine called upon receiving response for
21009 * get offload info
21010 */
21011void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21012 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21013{
21014
21015 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021016 tANI_U8 tempReplayCounter[8];
21017 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021018
21019 ENTER();
21020
21021 if (NULL == pAdapter)
21022 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021024 "%s: HDD adapter is Null", __func__);
21025 return ;
21026 }
21027
21028 if (NULL == pGtkOffloadGetInfoRsp)
21029 {
21030 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21031 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21032 return ;
21033 }
21034
21035 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21036 {
21037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21038 "%s: wlan Failed to get replay counter value",
21039 __func__);
21040 return ;
21041 }
21042
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021043 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21044 /* Update replay counter */
21045 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21046 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21047
21048 {
21049 /* changing from little to big endian since supplicant
21050 * works on big endian format
21051 */
21052 int i;
21053 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21054
21055 for (i = 0; i < 8; i++)
21056 {
21057 tempReplayCounter[7-i] = (tANI_U8)p[i];
21058 }
21059 }
21060
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021061 /* Update replay counter to NL */
21062 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021063 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021064}
21065
21066/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021067 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021068 * This function is used to offload GTK rekeying job to the firmware.
21069 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021070int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021071 struct cfg80211_gtk_rekey_data *data)
21072{
21073 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21075 hdd_station_ctx_t *pHddStaCtx;
21076 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021077 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021078 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021079 eHalStatus status = eHAL_STATUS_FAILURE;
21080
21081 ENTER();
21082
21083 if (NULL == pAdapter)
21084 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021086 "%s: HDD adapter is Null", __func__);
21087 return -ENODEV;
21088 }
21089
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021090 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21091 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21092 pAdapter->sessionId, pAdapter->device_mode));
21093
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021094 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021095 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021096 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021097 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021098 }
21099
21100 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21101 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21102 if (NULL == hHal)
21103 {
21104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21105 "%s: HAL context is Null!!!", __func__);
21106 return -EAGAIN;
21107 }
21108
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021109 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21110 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21111 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21112 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021113 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021114 {
21115 /* changing from big to little endian since driver
21116 * works on little endian format
21117 */
21118 tANI_U8 *p =
21119 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21120 int i;
21121
21122 for (i = 0; i < 8; i++)
21123 {
21124 p[7-i] = data->replay_ctr[i];
21125 }
21126 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021127
21128 if (TRUE == pHddCtx->hdd_wlan_suspended)
21129 {
21130 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021131 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21132 sizeof (tSirGtkOffloadParams));
21133 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021134 pAdapter->sessionId);
21135
21136 if (eHAL_STATUS_SUCCESS != status)
21137 {
21138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21139 "%s: sme_SetGTKOffload failed, returned %d",
21140 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021141
21142 /* Need to clear any trace of key value in the memory.
21143 * Thus zero out the memory even though it is local
21144 * variable.
21145 */
21146 vos_mem_zero(&hddGtkOffloadReqParams,
21147 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021148 return status;
21149 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21151 "%s: sme_SetGTKOffload successfull", __func__);
21152 }
21153 else
21154 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21156 "%s: wlan not suspended GTKOffload request is stored",
21157 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021158 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021159
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021160 /* Need to clear any trace of key value in the memory.
21161 * Thus zero out the memory even though it is local
21162 * variable.
21163 */
21164 vos_mem_zero(&hddGtkOffloadReqParams,
21165 sizeof(hddGtkOffloadReqParams));
21166
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021167 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021168 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021169}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021170
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021171int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21172 struct cfg80211_gtk_rekey_data *data)
21173{
21174 int ret;
21175
21176 vos_ssr_protect(__func__);
21177 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21178 vos_ssr_unprotect(__func__);
21179
21180 return ret;
21181}
21182#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021183/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021184 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021185 * This function is used to set access control policy
21186 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021187static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21188 struct net_device *dev,
21189 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021190{
21191 int i;
21192 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21193 hdd_hostapd_state_t *pHostapdState;
21194 tsap_Config_t *pConfig;
21195 v_CONTEXT_t pVosContext = NULL;
21196 hdd_context_t *pHddCtx;
21197 int status;
21198
21199 ENTER();
21200
21201 if (NULL == pAdapter)
21202 {
21203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21204 "%s: HDD adapter is Null", __func__);
21205 return -ENODEV;
21206 }
21207
21208 if (NULL == params)
21209 {
21210 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21211 "%s: params is Null", __func__);
21212 return -EINVAL;
21213 }
21214
21215 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21216 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021217 if (0 != status)
21218 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021219 return status;
21220 }
21221
21222 pVosContext = pHddCtx->pvosContext;
21223 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21224
21225 if (NULL == pHostapdState)
21226 {
21227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21228 "%s: pHostapdState is Null", __func__);
21229 return -EINVAL;
21230 }
21231
21232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21233 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021234 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21235 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21236 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021237
21238 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21239 {
21240 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21241
21242 /* default value */
21243 pConfig->num_accept_mac = 0;
21244 pConfig->num_deny_mac = 0;
21245
21246 /**
21247 * access control policy
21248 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21249 * listed in hostapd.deny file.
21250 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21251 * listed in hostapd.accept file.
21252 */
21253 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21254 {
21255 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21256 }
21257 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21258 {
21259 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21260 }
21261 else
21262 {
21263 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21264 "%s:Acl Policy : %d is not supported",
21265 __func__, params->acl_policy);
21266 return -ENOTSUPP;
21267 }
21268
21269 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21270 {
21271 pConfig->num_accept_mac = params->n_acl_entries;
21272 for (i = 0; i < params->n_acl_entries; i++)
21273 {
21274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21275 "** Add ACL MAC entry %i in WhiletList :"
21276 MAC_ADDRESS_STR, i,
21277 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21278
21279 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21280 sizeof(qcmacaddr));
21281 }
21282 }
21283 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21284 {
21285 pConfig->num_deny_mac = params->n_acl_entries;
21286 for (i = 0; i < params->n_acl_entries; i++)
21287 {
21288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21289 "** Add ACL MAC entry %i in BlackList :"
21290 MAC_ADDRESS_STR, i,
21291 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21292
21293 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21294 sizeof(qcmacaddr));
21295 }
21296 }
21297
21298 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21299 {
21300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21301 "%s: SAP Set Mac Acl fail", __func__);
21302 return -EINVAL;
21303 }
21304 }
21305 else
21306 {
21307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021308 "%s: Invalid device_mode = %s (%d)",
21309 __func__, hdd_device_modetoString(pAdapter->device_mode),
21310 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021311 return -EINVAL;
21312 }
21313
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021314 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021315 return 0;
21316}
21317
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021318static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21319 struct net_device *dev,
21320 const struct cfg80211_acl_data *params)
21321{
21322 int ret;
21323 vos_ssr_protect(__func__);
21324 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21325 vos_ssr_unprotect(__func__);
21326
21327 return ret;
21328}
21329
Leo Chang9056f462013-08-01 19:21:11 -070021330#ifdef WLAN_NL80211_TESTMODE
21331#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021332void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021333(
21334 void *pAdapter,
21335 void *indCont
21336)
21337{
Leo Changd9df8aa2013-09-26 13:32:26 -070021338 tSirLPHBInd *lphbInd;
21339 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021340 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021341
21342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021343 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021344
c_hpothu73f35e62014-04-18 13:40:08 +053021345 if (pAdapter == NULL)
21346 {
21347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21348 "%s: pAdapter is NULL\n",__func__);
21349 return;
21350 }
21351
Leo Chang9056f462013-08-01 19:21:11 -070021352 if (NULL == indCont)
21353 {
21354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021355 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021356 return;
21357 }
21358
c_hpothu73f35e62014-04-18 13:40:08 +053021359 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021360 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021361 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021362 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021363 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021364 GFP_ATOMIC);
21365 if (!skb)
21366 {
21367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21368 "LPHB timeout, NL buffer alloc fail");
21369 return;
21370 }
21371
Leo Changac3ba772013-10-07 09:47:04 -070021372 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021373 {
21374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21375 "WLAN_HDD_TM_ATTR_CMD put fail");
21376 goto nla_put_failure;
21377 }
Leo Changac3ba772013-10-07 09:47:04 -070021378 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021379 {
21380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21381 "WLAN_HDD_TM_ATTR_TYPE put fail");
21382 goto nla_put_failure;
21383 }
Leo Changac3ba772013-10-07 09:47:04 -070021384 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021385 sizeof(tSirLPHBInd), lphbInd))
21386 {
21387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21388 "WLAN_HDD_TM_ATTR_DATA put fail");
21389 goto nla_put_failure;
21390 }
Leo Chang9056f462013-08-01 19:21:11 -070021391 cfg80211_testmode_event(skb, GFP_ATOMIC);
21392 return;
21393
21394nla_put_failure:
21395 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21396 "NLA Put fail");
21397 kfree_skb(skb);
21398
21399 return;
21400}
21401#endif /* FEATURE_WLAN_LPHB */
21402
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021403static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021404{
21405 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21406 int err = 0;
21407#ifdef FEATURE_WLAN_LPHB
21408 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021409 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021410
21411 ENTER();
21412
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021413 err = wlan_hdd_validate_context(pHddCtx);
21414 if (0 != err)
21415 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021416 return err;
21417 }
Leo Chang9056f462013-08-01 19:21:11 -070021418#endif /* FEATURE_WLAN_LPHB */
21419
21420 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21421 if (err)
21422 {
21423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21424 "%s Testmode INV ATTR", __func__);
21425 return err;
21426 }
21427
21428 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21429 {
21430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21431 "%s Testmode INV CMD", __func__);
21432 return -EINVAL;
21433 }
21434
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021435 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21436 TRACE_CODE_HDD_CFG80211_TESTMODE,
21437 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021438 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21439 {
21440#ifdef FEATURE_WLAN_LPHB
21441 /* Low Power Heartbeat configuration request */
21442 case WLAN_HDD_TM_CMD_WLAN_HB:
21443 {
21444 int buf_len;
21445 void *buf;
21446 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021447 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021448
21449 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21450 {
21451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21452 "%s Testmode INV DATA", __func__);
21453 return -EINVAL;
21454 }
21455
21456 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21457 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021458
Manjeet Singh3c577442017-02-10 19:03:38 +053021459 if (buf_len > sizeof(*hb_params)) {
21460 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21461 buf_len);
21462 return -ERANGE;
21463 }
21464
Amar Singhal05852702014-02-04 14:40:00 -080021465 hb_params_temp =(tSirLPHBReq *)buf;
21466 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21467 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21468 return -EINVAL;
21469
Leo Chang9056f462013-08-01 19:21:11 -070021470 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21471 if (NULL == hb_params)
21472 {
21473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21474 "%s Request Buffer Alloc Fail", __func__);
21475 return -EINVAL;
21476 }
21477
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021478 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021479 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021480 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21481 hb_params,
21482 wlan_hdd_cfg80211_lphb_ind_handler);
21483 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021484 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21486 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021487 vos_mem_free(hb_params);
21488 }
Leo Chang9056f462013-08-01 19:21:11 -070021489 return 0;
21490 }
21491#endif /* FEATURE_WLAN_LPHB */
21492 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021493 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21494 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021495 return -EOPNOTSUPP;
21496 }
21497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021498 EXIT();
21499 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021500}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021501
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021502static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21504 struct wireless_dev *wdev,
21505#endif
21506 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021507{
21508 int ret;
21509
21510 vos_ssr_protect(__func__);
21511 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21512 vos_ssr_unprotect(__func__);
21513
21514 return ret;
21515}
Leo Chang9056f462013-08-01 19:21:11 -070021516#endif /* CONFIG_NL80211_TESTMODE */
21517
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021518extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021519static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021520 struct net_device *dev,
21521 int idx, struct survey_info *survey)
21522{
21523 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21524 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021525 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021526 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021527 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021528 v_S7_t snr,rssi;
21529 int status, i, j, filled = 0;
21530
21531 ENTER();
21532
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021533 if (NULL == pAdapter)
21534 {
21535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21536 "%s: HDD adapter is Null", __func__);
21537 return -ENODEV;
21538 }
21539
21540 if (NULL == wiphy)
21541 {
21542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21543 "%s: wiphy is Null", __func__);
21544 return -ENODEV;
21545 }
21546
21547 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21548 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021549 if (0 != status)
21550 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021551 return status;
21552 }
21553
Mihir Sheted9072e02013-08-21 17:02:29 +053021554 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21555
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021556 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021557 0 != pAdapter->survey_idx ||
21558 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021559 {
21560 /* The survey dump ops when implemented completely is expected to
21561 * return a survey of all channels and the ops is called by the
21562 * kernel with incremental values of the argument 'idx' till it
21563 * returns -ENONET. But we can only support the survey for the
21564 * operating channel for now. survey_idx is used to track
21565 * that the ops is called only once and then return -ENONET for
21566 * the next iteration
21567 */
21568 pAdapter->survey_idx = 0;
21569 return -ENONET;
21570 }
21571
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021572 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21573 {
21574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21575 "%s: Roaming in progress, hence return ", __func__);
21576 return -ENONET;
21577 }
21578
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021579 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21580
21581 wlan_hdd_get_snr(pAdapter, &snr);
21582 wlan_hdd_get_rssi(pAdapter, &rssi);
21583
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021584 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21585 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21586 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021587 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21588 hdd_wlan_get_freq(channel, &freq);
21589
21590
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021591 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021592 {
21593 if (NULL == wiphy->bands[i])
21594 {
21595 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21596 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21597 continue;
21598 }
21599
21600 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21601 {
21602 struct ieee80211_supported_band *band = wiphy->bands[i];
21603
21604 if (band->channels[j].center_freq == (v_U16_t)freq)
21605 {
21606 survey->channel = &band->channels[j];
21607 /* The Rx BDs contain SNR values in dB for the received frames
21608 * while the supplicant expects noise. So we calculate and
21609 * return the value of noise (dBm)
21610 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21611 */
21612 survey->noise = rssi - snr;
21613 survey->filled = SURVEY_INFO_NOISE_DBM;
21614 filled = 1;
21615 }
21616 }
21617 }
21618
21619 if (filled)
21620 pAdapter->survey_idx = 1;
21621 else
21622 {
21623 pAdapter->survey_idx = 0;
21624 return -ENONET;
21625 }
21626
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021627 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021628 return 0;
21629}
21630
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021631static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21632 struct net_device *dev,
21633 int idx, struct survey_info *survey)
21634{
21635 int ret;
21636
21637 vos_ssr_protect(__func__);
21638 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21639 vos_ssr_unprotect(__func__);
21640
21641 return ret;
21642}
21643
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021644/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021645 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021646 * this is called when cfg80211 driver resume
21647 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21648 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021649int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021650{
21651 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21652 hdd_adapter_t *pAdapter;
21653 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21654 VOS_STATUS status = VOS_STATUS_SUCCESS;
21655
21656 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021657
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021658 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021659 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021660 return 0;
21661 }
21662
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021663 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21664 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021665
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021666 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021667 {
21668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21669 "%s: Resume SoftAP", __func__);
21670 hdd_set_wlan_suspend_mode(false);
21671 }
21672
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021673 spin_lock(&pHddCtx->schedScan_lock);
21674 pHddCtx->isWiphySuspended = FALSE;
21675 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21676 {
21677 spin_unlock(&pHddCtx->schedScan_lock);
21678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21679 "%s: Return resume is not due to PNO indication", __func__);
21680 return 0;
21681 }
21682 // Reset flag to avoid updatating cfg80211 data old results again
21683 pHddCtx->isSchedScanUpdatePending = FALSE;
21684 spin_unlock(&pHddCtx->schedScan_lock);
21685
21686 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21687
21688 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21689 {
21690 pAdapter = pAdapterNode->pAdapter;
21691 if ( (NULL != pAdapter) &&
21692 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21693 {
21694 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021695 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21697 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021698 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021699 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021700 {
21701 /* Acquire wakelock to handle the case where APP's tries to
21702 * suspend immediately after updating the scan results. Whis
21703 * results in app's is in suspended state and not able to
21704 * process the connect request to AP
21705 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021706 hdd_prevent_suspend_timeout(2000,
21707 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021708 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021709 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021710
21711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21712 "%s : cfg80211 scan result database updated", __func__);
21713
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021714 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021715 return 0;
21716
21717 }
21718 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21719 pAdapterNode = pNext;
21720 }
21721
21722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21723 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021724 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021725 return 0;
21726}
21727
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021728int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21729{
21730 int ret;
21731
21732 vos_ssr_protect(__func__);
21733 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21734 vos_ssr_unprotect(__func__);
21735
21736 return ret;
21737}
21738
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021739/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021740 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021741 * this is called when cfg80211 driver suspends
21742 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021743int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021744 struct cfg80211_wowlan *wow)
21745{
21746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021747 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021748
21749 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021750
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021751 ret = wlan_hdd_validate_context(pHddCtx);
21752 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021753 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021754 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021755 }
21756
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021757 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21759 "%s: Suspend SoftAP", __func__);
21760 hdd_set_wlan_suspend_mode(true);
21761 }
21762
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021763
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021764 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21765 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21766 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021767 pHddCtx->isWiphySuspended = TRUE;
21768
21769 EXIT();
21770
21771 return 0;
21772}
21773
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021774int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21775 struct cfg80211_wowlan *wow)
21776{
21777 int ret;
21778
21779 vos_ssr_protect(__func__);
21780 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21781 vos_ssr_unprotect(__func__);
21782
21783 return ret;
21784}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021785
21786#ifdef FEATURE_OEM_DATA_SUPPORT
21787static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021788 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021789{
21790 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21791
21792 ENTER();
21793
21794 if (wlan_hdd_validate_context(pHddCtx)) {
21795 return;
21796 }
21797 if (!pMsg)
21798 {
21799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21800 return;
21801 }
21802
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021803 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021804
21805 EXIT();
21806 return;
21807
21808}
21809
21810void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021811 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021812{
21813 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21814
21815 ENTER();
21816
21817 if (wlan_hdd_validate_context(pHddCtx)) {
21818 return;
21819 }
21820
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021821 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021822
21823 switch(evType) {
21824 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021825 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021826 break;
21827 default:
21828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21829 break;
21830 }
21831 EXIT();
21832}
21833#endif
21834
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021835#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21836 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021837/**
21838 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21839 * @wiphy: Pointer to wiphy
21840 * @wdev: Pointer to wireless device structure
21841 *
21842 * This function is used to abort an ongoing scan
21843 *
21844 * Return: None
21845 */
21846static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21847 struct wireless_dev *wdev)
21848{
21849 struct net_device *dev = wdev->netdev;
21850 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21851 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21852 int ret;
21853
21854 ENTER();
21855
21856 if (NULL == adapter) {
21857 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21858 return;
21859 }
21860
21861 ret = wlan_hdd_validate_context(hdd_ctx);
21862 if (0 != ret)
21863 return;
21864
21865 wlan_hdd_scan_abort(adapter);
21866
21867 return;
21868}
21869
21870/**
21871 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21872 * @wiphy: Pointer to wiphy
21873 * @wdev: Pointer to wireless device structure
21874 *
21875 * Return: None
21876 */
21877void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21878 struct wireless_dev *wdev)
21879{
21880 vos_ssr_protect(__func__);
21881 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21882 vos_ssr_unprotect(__func__);
21883
21884 return;
21885}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021886#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021887
Abhishek Singh936c6932017-11-07 17:28:23 +053021888#ifdef CHANNEL_SWITCH_SUPPORTED
21889/**
21890 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21891 * channel in SAP/GO
21892 * @wiphy: wiphy pointer
21893 * @dev: dev pointer.
21894 * @csa_params: Change channel params
21895 *
21896 * This function is called to switch channel in SAP/GO
21897 *
21898 * Return: 0 if success else return non zero
21899 */
21900static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21901 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21902{
21903 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21904 hdd_context_t *hdd_ctx;
21905 uint8_t channel;
21906 int ret;
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021907 ptSapContext sap_ctx;
Abhishek Singh936c6932017-11-07 17:28:23 +053021908 v_CONTEXT_t vos_ctx;
21909
21910 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21911
21912 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21913 ret = wlan_hdd_validate_context(hdd_ctx);
21914 if (ret)
21915 return ret;
21916
21917 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21918 if (!vos_ctx) {
21919 hddLog(LOGE, FL("Vos ctx is null"));
21920 return -EINVAL;
21921 }
21922
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021923 if (WLAN_HDD_SOFTAP != adapter->device_mode)
Abhishek Singh936c6932017-11-07 17:28:23 +053021924 return -ENOTSUPP;
21925
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021926 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
21927 if (!sap_ctx) {
21928 hddLog(LOGE, FL("sap_ctx is NULL"));
21929 return -EINVAL;
21930 }
21931
21932 ret = wlansap_chk_n_set_chan_change_in_progress(sap_ctx);
21933 if (ret)
21934 return ret;
21935
21936 INIT_COMPLETION(sap_ctx->ecsa_info.chan_switch_comp);
21937
Abhishek Singh936c6932017-11-07 17:28:23 +053021938 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021939 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021940
Abhishek Singh10e17cf2018-03-12 14:34:22 +053021941 if (ret) {
21942 wlansap_reset_chan_change_in_progress(sap_ctx);
21943 complete(&sap_ctx->ecsa_info.chan_switch_comp);
21944 }
21945
Abhishek Singh936c6932017-11-07 17:28:23 +053021946 return ret;
21947}
21948
21949/**
21950 * wlan_hdd_cfg80211_channel_switch()- function to switch
21951 * channel in SAP/GO
21952 * @wiphy: wiphy pointer
21953 * @dev: dev pointer.
21954 * @csa_params: Change channel params
21955 *
21956 * This function is called to switch channel in SAP/GO
21957 *
21958 * Return: 0 if success else return non zero
21959 */
21960static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21961 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21962{
21963 int ret;
21964
21965 vos_ssr_protect(__func__);
21966 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21967 vos_ssr_unprotect(__func__);
21968
21969 return ret;
21970}
21971#endif
21972
Jeff Johnson295189b2012-06-20 16:38:30 -070021973/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021974static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021975{
21976 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21977 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21978 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21979 .change_station = wlan_hdd_change_station,
21980#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21981 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21982 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21983 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021984#else
21985 .start_ap = wlan_hdd_cfg80211_start_ap,
21986 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21987 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021988#endif
21989 .change_bss = wlan_hdd_cfg80211_change_bss,
21990 .add_key = wlan_hdd_cfg80211_add_key,
21991 .get_key = wlan_hdd_cfg80211_get_key,
21992 .del_key = wlan_hdd_cfg80211_del_key,
21993 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021994#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021995 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021996#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021997 .scan = wlan_hdd_cfg80211_scan,
21998 .connect = wlan_hdd_cfg80211_connect,
21999 .disconnect = wlan_hdd_cfg80211_disconnect,
22000 .join_ibss = wlan_hdd_cfg80211_join_ibss,
22001 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
22002 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
22003 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
22004 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070022005 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
22006 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053022007 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070022008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
22009 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
22010 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
22011 .set_txq_params = wlan_hdd_set_txq_params,
22012#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070022013 .get_station = wlan_hdd_cfg80211_get_station,
22014 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
22015 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070022016 .add_station = wlan_hdd_cfg80211_add_station,
22017#ifdef FEATURE_WLAN_LFR
22018 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
22019 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
22020 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
22021#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070022022#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
22023 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22024#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022025#ifdef FEATURE_WLAN_TDLS
22026 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22027 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22028#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022029#ifdef WLAN_FEATURE_GTK_OFFLOAD
22030 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22031#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022032#ifdef FEATURE_WLAN_SCAN_PNO
22033 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22034 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22035#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022036 .resume = wlan_hdd_cfg80211_resume_wlan,
22037 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022038 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022039#ifdef WLAN_NL80211_TESTMODE
22040 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22041#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022042 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022043#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22044 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022045 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022046#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022047#ifdef CHANNEL_SWITCH_SUPPORTED
22048 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22049#endif
22050
Jeff Johnson295189b2012-06-20 16:38:30 -070022051};
22052