blob: bb8347c6cef2a259ac8463ec49cad88e38970c3f [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05302 * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053066#include <linux/etherdevice.h>
Jeff Johnson295189b2012-06-20 16:38:30 -070067#include <wlan_hdd_includes.h>
68#include <net/arp.h>
69#include <net/cfg80211.h>
70#include <linux/wireless.h>
71#include <wlan_hdd_wowl.h>
72#include <aniGlobal.h>
73#include "ccmApi.h"
74#include "sirParams.h"
75#include "dot11f.h"
76#include "wlan_hdd_assoc.h"
77#include "wlan_hdd_wext.h"
78#include "sme_Api.h"
79#include "wlan_hdd_p2p.h"
80#include "wlan_hdd_cfg80211.h"
81#include "wlan_hdd_hostapd.h"
82#include "sapInternal.h"
83#include "wlan_hdd_softap_tx_rx.h"
84#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053085#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053086#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053087#include "wlan_hdd_trace.h"
88#include "vos_types.h"
89#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070090#ifdef WLAN_BTAMP_FEATURE
91#include "bap_hdd_misc.h"
92#endif
93#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080094#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053095#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053096#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053097#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070098#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053099#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +0530100#include "wlan_logging_sock_svc.h"
Agrawal Ashishcfe83282016-09-29 13:03:45 +0530101#include "wlan_hdd_misc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530102
Jeff Johnson295189b2012-06-20 16:38:30 -0700103
104#define g_mode_rates_size (12)
105#define a_mode_rates_size (8)
106#define FREQ_BASE_80211G (2407)
107#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700108#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530109#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700110#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800111 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700112
113#define HDD2GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530114 .band = HDD_NL80211_BAND_2GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700115 .center_freq = (freq), \
116 .hw_value = (chan),\
117 .flags = (flag), \
118 .max_antenna_gain = 0 ,\
119 .max_power = 30, \
120}
121
122#define HDD5GHZCHAN(freq, chan, flag) { \
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530123 .band = HDD_NL80211_BAND_5GHZ, \
Jeff Johnson295189b2012-06-20 16:38:30 -0700124 .center_freq = (freq), \
125 .hw_value = (chan),\
126 .flags = (flag), \
127 .max_antenna_gain = 0 ,\
128 .max_power = 30, \
129}
130
131#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
132{\
133 .bitrate = rate, \
134 .hw_value = rate_id, \
135 .flags = flag, \
136}
137
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530138#ifdef WLAN_FEATURE_VOWIFI_11R
139#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
140#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
141#endif
142
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530144#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530145
Sunil Duttc69bccb2014-05-26 21:30:20 +0530146#ifdef WLAN_FEATURE_LINK_LAYER_STATS
147/*
148 * Used to allocate the size of 4096 for the link layer stats.
149 * The size of 4096 is considered assuming that all data per
150 * respective event fit with in the limit.Please take a call
151 * on the limit based on the data requirements on link layer
152 * statistics.
153 */
154#define LL_STATS_EVENT_BUF_SIZE 4096
155#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530156#ifdef WLAN_FEATURE_EXTSCAN
157/*
158 * Used to allocate the size of 4096 for the EXTScan NL data.
159 * The size of 4096 is considered assuming that all data per
160 * respective event fit with in the limit.Please take a call
161 * on the limit based on the data requirements.
162 */
163
164#define EXTSCAN_EVENT_BUF_SIZE 4096
165#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
166#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530167
Atul Mittal115287b2014-07-08 13:26:33 +0530168/*EXT TDLS*/
169/*
170 * Used to allocate the size of 4096 for the TDLS.
171 * The size of 4096 is considered assuming that all data per
172 * respective event fit with in the limit.Please take a call
173 * on the limit based on the data requirements on link layer
174 * statistics.
175 */
176#define EXTTDLS_EVENT_BUF_SIZE 4096
177
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530178/*
179 * Values for Mac spoofing feature
180 *
181 */
182#define MAC_ADDR_SPOOFING_FW_HOST_DISABLE 0
183#define MAC_ADDR_SPOOFING_FW_HOST_ENABLE 1
184#define MAC_ADDR_SPOOFING_FW_ENABLE_HOST_DISABLE 2
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +0530185#define MAC_ADDR_SPOOFING_DEFER_INTERVAL 10 //in ms
186
Anurag Chouhan343af7e2016-12-16 13:11:19 +0530187/*
188 * max_sched_scan_plans defined to 10
189 */
190#define MAX_SCHED_SCAN_PLANS 10
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +0530191
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530192static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700193{
194 WLAN_CIPHER_SUITE_WEP40,
195 WLAN_CIPHER_SUITE_WEP104,
196 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800197#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700198#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
199 WLAN_CIPHER_SUITE_KRK,
200 WLAN_CIPHER_SUITE_CCMP,
201#else
202 WLAN_CIPHER_SUITE_CCMP,
203#endif
204#ifdef FEATURE_WLAN_WAPI
205 WLAN_CIPHER_SUITE_SMS4,
206#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700207#ifdef WLAN_FEATURE_11W
208 WLAN_CIPHER_SUITE_AES_CMAC,
209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700210};
211
Agrawal Ashish97dec502015-11-26 20:20:58 +0530212const static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530213{
Jeff Johnson295189b2012-06-20 16:38:30 -0700214 HDD2GHZCHAN(2412, 1, 0) ,
215 HDD2GHZCHAN(2417, 2, 0) ,
216 HDD2GHZCHAN(2422, 3, 0) ,
217 HDD2GHZCHAN(2427, 4, 0) ,
218 HDD2GHZCHAN(2432, 5, 0) ,
219 HDD2GHZCHAN(2437, 6, 0) ,
220 HDD2GHZCHAN(2442, 7, 0) ,
221 HDD2GHZCHAN(2447, 8, 0) ,
222 HDD2GHZCHAN(2452, 9, 0) ,
223 HDD2GHZCHAN(2457, 10, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225 HDD2GHZCHAN(2467, 12, 0) ,
226 HDD2GHZCHAN(2472, 13, 0) ,
227 HDD2GHZCHAN(2484, 14, 0) ,
228};
229
Agrawal Ashish97dec502015-11-26 20:20:58 +0530230const static struct ieee80211_channel hdd_channels_5_GHZ[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700231{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700232 HDD5GHZCHAN(4920, 240, 0) ,
233 HDD5GHZCHAN(4940, 244, 0) ,
234 HDD5GHZCHAN(4960, 248, 0) ,
235 HDD5GHZCHAN(4980, 252, 0) ,
236 HDD5GHZCHAN(5040, 208, 0) ,
237 HDD5GHZCHAN(5060, 212, 0) ,
238 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700239 HDD5GHZCHAN(5180, 36, 0) ,
240 HDD5GHZCHAN(5200, 40, 0) ,
241 HDD5GHZCHAN(5220, 44, 0) ,
242 HDD5GHZCHAN(5240, 48, 0) ,
243 HDD5GHZCHAN(5260, 52, 0) ,
244 HDD5GHZCHAN(5280, 56, 0) ,
245 HDD5GHZCHAN(5300, 60, 0) ,
246 HDD5GHZCHAN(5320, 64, 0) ,
247 HDD5GHZCHAN(5500,100, 0) ,
248 HDD5GHZCHAN(5520,104, 0) ,
249 HDD5GHZCHAN(5540,108, 0) ,
250 HDD5GHZCHAN(5560,112, 0) ,
251 HDD5GHZCHAN(5580,116, 0) ,
252 HDD5GHZCHAN(5600,120, 0) ,
253 HDD5GHZCHAN(5620,124, 0) ,
254 HDD5GHZCHAN(5640,128, 0) ,
255 HDD5GHZCHAN(5660,132, 0) ,
256 HDD5GHZCHAN(5680,136, 0) ,
257 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800258#ifdef FEATURE_WLAN_CH144
259 HDD5GHZCHAN(5720,144, 0) ,
260#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700261 HDD5GHZCHAN(5745,149, 0) ,
262 HDD5GHZCHAN(5765,153, 0) ,
263 HDD5GHZCHAN(5785,157, 0) ,
264 HDD5GHZCHAN(5805,161, 0) ,
265 HDD5GHZCHAN(5825,165, 0) ,
266};
267
268static struct ieee80211_rate g_mode_rates[] =
269{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530270 HDD_G_MODE_RATETAB(10, 0x1, 0),
271 HDD_G_MODE_RATETAB(20, 0x2, 0),
272 HDD_G_MODE_RATETAB(55, 0x4, 0),
273 HDD_G_MODE_RATETAB(110, 0x8, 0),
274 HDD_G_MODE_RATETAB(60, 0x10, 0),
275 HDD_G_MODE_RATETAB(90, 0x20, 0),
276 HDD_G_MODE_RATETAB(120, 0x40, 0),
277 HDD_G_MODE_RATETAB(180, 0x80, 0),
278 HDD_G_MODE_RATETAB(240, 0x100, 0),
279 HDD_G_MODE_RATETAB(360, 0x200, 0),
280 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700281 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530282};
Jeff Johnson295189b2012-06-20 16:38:30 -0700283
284static struct ieee80211_rate a_mode_rates[] =
285{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530286 HDD_G_MODE_RATETAB(60, 0x10, 0),
287 HDD_G_MODE_RATETAB(90, 0x20, 0),
288 HDD_G_MODE_RATETAB(120, 0x40, 0),
289 HDD_G_MODE_RATETAB(180, 0x80, 0),
290 HDD_G_MODE_RATETAB(240, 0x100, 0),
291 HDD_G_MODE_RATETAB(360, 0x200, 0),
292 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700293 HDD_G_MODE_RATETAB(540, 0x800, 0),
294};
295
296static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
297{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530298 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700299 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530300 .band = HDD_NL80211_BAND_2GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700301 .bitrates = g_mode_rates,
302 .n_bitrates = g_mode_rates_size,
303 .ht_cap.ht_supported = 1,
304 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
305 | IEEE80211_HT_CAP_GRN_FLD
306 | IEEE80211_HT_CAP_DSSSCCK40
307 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
308 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
309 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
310 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
311 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
312 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
313};
314
Jeff Johnson295189b2012-06-20 16:38:30 -0700315static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
316{
Agrawal Ashish97dec502015-11-26 20:20:58 +0530317 .channels = NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -0700318 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +0530319 .band = HDD_NL80211_BAND_5GHZ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700320 .bitrates = a_mode_rates,
321 .n_bitrates = a_mode_rates_size,
322 .ht_cap.ht_supported = 1,
323 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
324 | IEEE80211_HT_CAP_GRN_FLD
325 | IEEE80211_HT_CAP_DSSSCCK40
326 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
327 | IEEE80211_HT_CAP_SGI_40
328 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
329 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
330 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
331 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
332 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
333 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
334};
335
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530336/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700337 TX/RX direction for each kind of interface */
338static const struct ieee80211_txrx_stypes
339wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
340 [NL80211_IFTYPE_STATION] = {
341 .tx = 0xffff,
342 .rx = BIT(SIR_MAC_MGMT_ACTION) |
343 BIT(SIR_MAC_MGMT_PROBE_REQ),
344 },
345 [NL80211_IFTYPE_AP] = {
346 .tx = 0xffff,
347 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
348 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
349 BIT(SIR_MAC_MGMT_PROBE_REQ) |
350 BIT(SIR_MAC_MGMT_DISASSOC) |
351 BIT(SIR_MAC_MGMT_AUTH) |
352 BIT(SIR_MAC_MGMT_DEAUTH) |
353 BIT(SIR_MAC_MGMT_ACTION),
354 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700355 [NL80211_IFTYPE_ADHOC] = {
356 .tx = 0xffff,
357 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
358 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ) |
360 BIT(SIR_MAC_MGMT_DISASSOC) |
361 BIT(SIR_MAC_MGMT_AUTH) |
362 BIT(SIR_MAC_MGMT_DEAUTH) |
363 BIT(SIR_MAC_MGMT_ACTION),
364 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700365 [NL80211_IFTYPE_P2P_CLIENT] = {
366 .tx = 0xffff,
367 .rx = BIT(SIR_MAC_MGMT_ACTION) |
368 BIT(SIR_MAC_MGMT_PROBE_REQ),
369 },
370 [NL80211_IFTYPE_P2P_GO] = {
371 /* This is also same as for SoftAP */
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381};
382
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800384static const struct ieee80211_iface_limit
385wlan_hdd_iface_limit[] = {
386 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800387 /* max = 3 ; Our driver create two interfaces during driver init
388 * wlan0 and p2p0 interfaces. p2p0 is considered as station
389 * interface until a group is formed. In JB architecture, once the
390 * group is formed, interface type of p2p0 is changed to P2P GO or
391 * Client.
392 * When supplicant remove the group, it first issue a set interface
393 * cmd to change the mode back to Station. In JB this works fine as
394 * we advertize two station type interface during driver init.
395 * Some vendors create separate interface for P2P GO/Client,
396 * after group formation(Third one). But while group remove
397 * supplicant first tries to change the mode(3rd interface) to STATION
398 * But as we advertized only two sta type interfaces nl80211 was
399 * returning error for the third one which was leading to failure in
400 * delete interface. Ideally while removing the group, supplicant
401 * should not try to change the 3rd interface mode to Station type.
402 * Till we get a fix in wpa_supplicant, we advertize max STA
403 * interface type to 3
404 */
405 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800406 .types = BIT(NL80211_IFTYPE_STATION),
407 },
408 {
409 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700410 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800411 },
412 {
413 .max = 1,
414 .types = BIT(NL80211_IFTYPE_P2P_GO) |
415 BIT(NL80211_IFTYPE_P2P_CLIENT),
416 },
417};
418
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530419/* interface limits for sta + monitor SCC */
420static const struct ieee80211_iface_limit
421wlan_hdd_iface_sta_mon_limit[] = {
422 {
423 .max = 1,
424 .types = BIT(NL80211_IFTYPE_STATION),
425 },
426 {
427 .max = 1, /* Monitor interface */
428 .types = BIT(NL80211_IFTYPE_MONITOR),
429 },
430};
431
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +0530434wlan_hdd_iface_combination[] = {
435 {
436 .limits = wlan_hdd_iface_limit,
437 .num_different_channels = 1,
438 /*
439 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
440 * and p2p0 interfaces during driver init
441 * Some vendors create separate interface for P2P operations.
442 * wlan0: STA interface
443 * p2p0: P2P Device interface, action frames goes
444 * through this interface.
445 * p2p-xx: P2P interface, After GO negotiation this interface is
446 * created for p2p operations(GO/CLIENT interface).
447 */
448 .max_interfaces = WLAN_MAX_INTERFACES,
449 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
450 .beacon_int_infra_match = false,
451 },
452 {
453 .limits = wlan_hdd_iface_sta_mon_limit,
454 .num_different_channels = 1,
455 .max_interfaces = WLAN_STA_AND_MON_INTERFACES,
456 .n_limits = ARRAY_SIZE(wlan_hdd_iface_sta_mon_limit),
457 .beacon_int_infra_match = false,
458 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800459};
460#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800461
Jeff Johnson295189b2012-06-20 16:38:30 -0700462static struct cfg80211_ops wlan_hdd_cfg80211_ops;
463
464/* Data rate 100KBPS based on IE Index */
465struct index_data_rate_type
466{
467 v_U8_t beacon_rate_index;
468 v_U16_t supported_rate[4];
469};
470
471/* 11B, 11G Rate table include Basic rate and Extended rate
472 The IDX field is the rate index
473 The HI field is the rate when RSSI is strong or being ignored
474 (in this case we report actual rate)
475 The MID field is the rate when RSSI is moderate
476 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
477 The LO field is the rate when RSSI is low
478 (in this case we don't report rates, actual current rate used)
479 */
480static const struct
481{
482 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700483 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700484} supported_data_rate[] =
485{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700486/* IDX HI HM LM LO (RSSI-based index */
487 {2, { 10, 10, 10, 0}},
488 {4, { 20, 20, 10, 0}},
489 {11, { 55, 20, 10, 0}},
490 {12, { 60, 55, 20, 0}},
491 {18, { 90, 55, 20, 0}},
492 {22, {110, 55, 20, 0}},
493 {24, {120, 90, 60, 0}},
494 {36, {180, 120, 60, 0}},
495 {44, {220, 180, 60, 0}},
496 {48, {240, 180, 90, 0}},
497 {66, {330, 180, 90, 0}},
498 {72, {360, 240, 90, 0}},
499 {96, {480, 240, 120, 0}},
500 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700501};
502
503/* MCS Based rate table */
504static struct index_data_rate_type supported_mcs_rate[] =
505{
506/* MCS L20 L40 S20 S40 */
507 {0, {65, 135, 72, 150}},
508 {1, {130, 270, 144, 300}},
509 {2, {195, 405, 217, 450}},
510 {3, {260, 540, 289, 600}},
511 {4, {390, 810, 433, 900}},
512 {5, {520, 1080, 578, 1200}},
513 {6, {585, 1215, 650, 1350}},
514 {7, {650, 1350, 722, 1500}}
515};
516
Leo Chang6f8870f2013-03-26 18:11:36 -0700517#ifdef WLAN_FEATURE_11AC
518
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530519#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700520
521struct index_vht_data_rate_type
522{
523 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530524 v_U16_t supported_VHT80_rate[2];
525 v_U16_t supported_VHT40_rate[2];
526 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700527};
528
529typedef enum
530{
531 DATA_RATE_11AC_MAX_MCS_7,
532 DATA_RATE_11AC_MAX_MCS_8,
533 DATA_RATE_11AC_MAX_MCS_9,
534 DATA_RATE_11AC_MAX_MCS_NA
535} eDataRate11ACMaxMcs;
536
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530537/* SSID broadcast type */
538typedef enum eSSIDBcastType
539{
540 eBCAST_UNKNOWN = 0,
541 eBCAST_NORMAL = 1,
542 eBCAST_HIDDEN = 2,
543} tSSIDBcastType;
544
Leo Chang6f8870f2013-03-26 18:11:36 -0700545/* MCS Based VHT rate table */
546static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
547{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530548/* MCS L80 S80 L40 S40 L20 S40*/
549 {0, {293, 325}, {135, 150}, {65, 72}},
550 {1, {585, 650}, {270, 300}, {130, 144}},
551 {2, {878, 975}, {405, 450}, {195, 217}},
552 {3, {1170, 1300}, {540, 600}, {260, 289}},
553 {4, {1755, 1950}, {810, 900}, {390, 433}},
554 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
555 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
556 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
557 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
558 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700559};
560#endif /* WLAN_FEATURE_11AC */
561
c_hpothu79aab322014-07-14 21:11:01 +0530562/*array index points to MCS and array value points respective rssi*/
563static int rssiMcsTbl[][10] =
564{
565/*MCS 0 1 2 3 4 5 6 7 8 9*/
566 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
567 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
568 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
569};
570
Jeff Johnson295189b2012-06-20 16:38:30 -0700571extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530572#ifdef FEATURE_WLAN_SCAN_PNO
573static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
574#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700575
Leo Chang9056f462013-08-01 19:21:11 -0700576#ifdef WLAN_NL80211_TESTMODE
577enum wlan_hdd_tm_attr
578{
579 WLAN_HDD_TM_ATTR_INVALID = 0,
580 WLAN_HDD_TM_ATTR_CMD = 1,
581 WLAN_HDD_TM_ATTR_DATA = 2,
582 WLAN_HDD_TM_ATTR_TYPE = 3,
583 /* keep last */
584 WLAN_HDD_TM_ATTR_AFTER_LAST,
585 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
586};
587
588enum wlan_hdd_tm_cmd
589{
590 WLAN_HDD_TM_CMD_WLAN_HB = 1,
591};
592
593#define WLAN_HDD_TM_DATA_MAX_LEN 5000
594
595static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
596{
597 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
598 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
599 .len = WLAN_HDD_TM_DATA_MAX_LEN },
600};
601#endif /* WLAN_NL80211_TESTMODE */
602
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800603#ifdef FEATURE_WLAN_CH_AVOID
604/*
605 * FUNCTION: wlan_hdd_send_avoid_freq_event
606 * This is called when wlan driver needs to send vendor specific
607 * avoid frequency range event to userspace
608 */
609int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
610 tHddAvoidFreqList *pAvoidFreqList)
611{
612 struct sk_buff *vendor_event;
613
614 ENTER();
615
616 if (!pHddCtx)
617 {
618 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
619 "%s: HDD context is null", __func__);
620 return -1;
621 }
622
623 if (!pAvoidFreqList)
624 {
625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
626 "%s: pAvoidFreqList is null", __func__);
627 return -1;
628 }
629
630 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530631#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
632 NULL,
633#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800634 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530635 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800636 GFP_KERNEL);
637 if (!vendor_event)
638 {
639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
640 "%s: cfg80211_vendor_event_alloc failed", __func__);
641 return -1;
642 }
643
644 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
645 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
646
647 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
648
649 EXIT();
650 return 0;
651}
652#endif /* FEATURE_WLAN_CH_AVOID */
653
Srinivas Dasari030bad32015-02-18 23:23:54 +0530654/*
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +0530655 * define short names for the global vendor params
656 * used by QCA_NL80211_VENDOR_SUBCMD_HANG
657 */
658#define HANG_REASON_INDEX QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX
659
660/**
661 * hdd_convert_hang_reason() - Convert cds recovery reason to vendor specific
662 * hang reason
663 * @reason: cds recovery reason
664 *
665 * Return: Vendor specific reason code
666 */
667static enum qca_wlan_vendor_hang_reason
668hdd_convert_hang_reason(enum vos_hang_reason reason)
669{
670 unsigned int ret_val;
671
672 switch (reason) {
673 case VOS_GET_MSG_BUFF_FAILURE:
674 ret_val = QCA_WLAN_HANG_GET_MSG_BUFF_FAILURE;
675 break;
676 case VOS_ACTIVE_LIST_TIMEOUT:
677 ret_val = QCA_WLAN_HANG_ACTIVE_LIST_TIMEOUT;
678 break;
679 case VOS_SCAN_REQ_EXPIRED:
680 ret_val = QCA_WLAN_HANG_SCAN_REQ_EXPIRED;
681 break;
682 case VOS_TRANSMISSIONS_TIMEOUT:
683 ret_val = QCA_WLAN_HANG_TRANSMISSIONS_TIMEOUT;
684 break;
685 case VOS_DXE_FAILURE:
686 ret_val = QCA_WLAN_HANG_DXE_FAILURE;
687 break;
688 case VOS_WDI_FAILURE:
689 ret_val = QCA_WLAN_HANG_WDI_FAILURE;
690 break;
691 case VOS_REASON_UNSPECIFIED:
692 default:
693 ret_val = QCA_WLAN_HANG_REASON_UNSPECIFIED;
694 }
695 return ret_val;
696}
697
698/**
699 * wlan_hdd_send_hang_reason_event() - Send hang reason to the userspace
700 * @hdd_ctx: Pointer to hdd context
701 * @reason: cds recovery reason
702 *
703 * Return: 0 on success or failure reason
704 */
705int wlan_hdd_send_hang_reason_event(hdd_context_t *hdd_ctx,
706 enum vos_hang_reason reason)
707{
708 struct sk_buff *vendor_event;
709 enum qca_wlan_vendor_hang_reason hang_reason;
710
711 ENTER();
712
713 if (!hdd_ctx) {
714 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
715 "HDD context is null");
716 return -EINVAL;
717 }
718
719 vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
721 NULL,
722#endif
723 sizeof(unsigned int),
724 HANG_REASON_INDEX,
725 GFP_KERNEL);
726 if (!vendor_event) {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "cfg80211_vendor_event_alloc failed");
729 return -ENOMEM;
730 }
731
732 hang_reason = hdd_convert_hang_reason(reason);
733
734 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_HANG_REASON,
735 (unsigned int) hang_reason)) {
736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
737 "QCA_WLAN_VENDOR_ATTR_HANG_REASON put fail");
738 kfree_skb(vendor_event);
739 return -EINVAL;
740 }
741
742 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
743
744 EXIT();
745 return 0;
746}
747#undef HANG_REASON_INDEX
748
749/*
Srinivas Dasari030bad32015-02-18 23:23:54 +0530750 * FUNCTION: __wlan_hdd_cfg80211_nan_request
751 * This is called when wlan driver needs to send vendor specific
752 * nan request event.
753 */
754static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
755 struct wireless_dev *wdev,
756 const void *data, int data_len)
757{
758 tNanRequestReq nan_req;
759 VOS_STATUS status;
760 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530761 struct net_device *dev = wdev->netdev;
762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
763 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530764 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
765
766 if (0 == data_len)
767 {
768 hddLog(VOS_TRACE_LEVEL_ERROR,
769 FL("NAN - Invalid Request, length = 0"));
770 return ret_val;
771 }
772
773 if (NULL == data)
774 {
775 hddLog(VOS_TRACE_LEVEL_ERROR,
776 FL("NAN - Invalid Request, data is NULL"));
777 return ret_val;
778 }
779
780 status = wlan_hdd_validate_context(pHddCtx);
781 if (0 != status)
782 {
783 hddLog(VOS_TRACE_LEVEL_ERROR,
784 FL("HDD context is not valid"));
785 return -EINVAL;
786 }
787
788 hddLog(LOG1, FL("Received NAN command"));
789 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
790 (tANI_U8 *)data, data_len);
791
792 /* check the NAN Capability */
793 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
794 {
795 hddLog(VOS_TRACE_LEVEL_ERROR,
796 FL("NAN is not supported by Firmware"));
797 return -EINVAL;
798 }
799
800 nan_req.request_data_len = data_len;
801 nan_req.request_data = data;
802
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530803 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530804 if (VOS_STATUS_SUCCESS == status)
805 {
806 ret_val = 0;
807 }
808 return ret_val;
809}
810
811/*
812 * FUNCTION: wlan_hdd_cfg80211_nan_request
813 * Wrapper to protect the nan vendor command from ssr
814 */
815static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
816 struct wireless_dev *wdev,
817 const void *data, int data_len)
818{
819 int ret;
820
821 vos_ssr_protect(__func__);
822 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
823 vos_ssr_unprotect(__func__);
824
825 return ret;
826}
827
828/*
829 * FUNCTION: wlan_hdd_cfg80211_nan_callback
830 * This is a callback function and it gets called
831 * when we need to report nan response event to
832 * upper layers.
833 */
834static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
835{
836 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
837 struct sk_buff *vendor_event;
838 int status;
839 tSirNanEvent *data;
840
841 ENTER();
842 if (NULL == msg)
843 {
844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
845 FL(" msg received here is null"));
846 return;
847 }
848 data = msg;
849
850 status = wlan_hdd_validate_context(pHddCtx);
851
852 if (0 != status)
853 {
854 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
855 FL("HDD context is not valid"));
856 return;
857 }
858
859 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
861 NULL,
862#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530863 data->event_data_len +
864 NLMSG_HDRLEN,
865 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
866 GFP_KERNEL);
867
868 if (!vendor_event)
869 {
870 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
871 FL("cfg80211_vendor_event_alloc failed"));
872 return;
873 }
874 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
875 data->event_data_len, data->event_data))
876 {
877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
878 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
879 kfree_skb(vendor_event);
880 return;
881 }
882 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
883 EXIT();
884}
885
886/*
887 * FUNCTION: wlan_hdd_cfg80211_nan_init
888 * This function is called to register the callback to sme layer
889 */
890inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
891{
892 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
893}
894
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530895/*
896 * define short names for the global vendor params
897 * used by __wlan_hdd_cfg80211_get_station_cmd()
898 */
899#define STATION_INVALID \
900 QCA_WLAN_VENDOR_ATTR_GET_STATION_INVALID
901#define STATION_INFO \
902 QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO
903#define STATION_ASSOC_FAIL_REASON \
904 QCA_WLAN_VENDOR_ATTR_GET_STATION_ASSOC_FAIL_REASON
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +0530905#define STATION_REMOTE \
906 QCA_WLAN_VENDOR_ATTR_GET_STATION_REMOTE
Anurag Chouhanfcd20172017-07-19 17:25:19 +0530907#define STATION_MAX \
908 QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX
909
910static const struct nla_policy
911hdd_get_station_policy[STATION_MAX + 1] = {
912 [STATION_INFO] = {.type = NLA_FLAG},
913 [STATION_ASSOC_FAIL_REASON] = {.type = NLA_FLAG},
914};
915
916/**
917 * hdd_get_station_assoc_fail() - Handle get station assoc fail
918 * @hdd_ctx: HDD context within host driver
919 * @wdev: wireless device
920 *
921 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION_ASSOC_FAIL.
922 * Validate cmd attributes and send the station info to upper layers.
923 *
924 * Return: Success(0) or reason code for failure
925 */
926static int hdd_get_station_assoc_fail(hdd_context_t *hdd_ctx,
927 hdd_adapter_t *adapter)
928{
929 struct sk_buff *skb = NULL;
930 uint32_t nl_buf_len;
931 hdd_station_ctx_t *hdd_sta_ctx;
932
933 nl_buf_len = NLMSG_HDRLEN;
934 nl_buf_len += sizeof(uint32_t);
935 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
936
937 if (!skb) {
938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"cfg80211_vendor_cmd_alloc_reply_skb failed");
939 return -ENOMEM;
940 }
941
942 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
943
944 if (nla_put_u32(skb, INFO_ASSOC_FAIL_REASON,
945 hdd_sta_ctx->conn_info.assoc_status_code)) {
946 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
947 goto fail;
948 }
949 return cfg80211_vendor_cmd_reply(skb);
950fail:
951 if (skb)
952 kfree_skb(skb);
953 return -EINVAL;
954}
955
956/**
957 * hdd_map_auth_type() - transform auth type specific to
958 * vendor command
959 * @auth_type: csr auth type
960 *
961 * Return: Success(0) or reason code for failure
962 */
963static int hdd_convert_auth_type(uint32_t auth_type)
964{
965 uint32_t ret_val;
966
967 switch (auth_type) {
968 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
969 ret_val = QCA_WLAN_AUTH_TYPE_OPEN;
970 break;
971 case eCSR_AUTH_TYPE_SHARED_KEY:
972 ret_val = QCA_WLAN_AUTH_TYPE_SHARED;
973 break;
974 case eCSR_AUTH_TYPE_WPA:
975 ret_val = QCA_WLAN_AUTH_TYPE_WPA;
976 break;
977 case eCSR_AUTH_TYPE_WPA_PSK:
978 ret_val = QCA_WLAN_AUTH_TYPE_WPA_PSK;
979 break;
980 case eCSR_AUTH_TYPE_AUTOSWITCH:
981 ret_val = QCA_WLAN_AUTH_TYPE_AUTOSWITCH;
982 break;
983 case eCSR_AUTH_TYPE_WPA_NONE:
984 ret_val = QCA_WLAN_AUTH_TYPE_WPA_NONE;
985 break;
986 case eCSR_AUTH_TYPE_RSN:
987 ret_val = QCA_WLAN_AUTH_TYPE_RSN;
988 break;
989 case eCSR_AUTH_TYPE_RSN_PSK:
990 ret_val = QCA_WLAN_AUTH_TYPE_RSN_PSK;
991 break;
992 case eCSR_AUTH_TYPE_FT_RSN:
993 ret_val = QCA_WLAN_AUTH_TYPE_FT;
994 break;
995 case eCSR_AUTH_TYPE_FT_RSN_PSK:
996 ret_val = QCA_WLAN_AUTH_TYPE_FT_PSK;
997 break;
998 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
999 ret_val = QCA_WLAN_AUTH_TYPE_WAI;
1000 break;
1001 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
1002 ret_val = QCA_WLAN_AUTH_TYPE_WAI_PSK;
1003 break;
1004#ifdef FEATURE_WLAN_ESE
1005 case eCSR_AUTH_TYPE_CCKM_WPA:
1006 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_WPA;
1007 break;
1008 case eCSR_AUTH_TYPE_CCKM_RSN:
1009 ret_val = QCA_WLAN_AUTH_TYPE_CCKM_RSN;
1010 break;
1011#endif
1012 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1013 ret_val = QCA_WLAN_AUTH_TYPE_SHA256_PSK;
1014 break;
1015 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1016 ret_val = QCA_WLAN_AUTH_TYPE_SHA256;
1017 break;
1018 case eCSR_NUM_OF_SUPPORT_AUTH_TYPE:
1019 case eCSR_AUTH_TYPE_FAILED:
1020 case eCSR_AUTH_TYPE_NONE:
1021 default:
1022 ret_val = QCA_WLAN_AUTH_TYPE_INVALID;
1023 break;
1024 }
1025 return ret_val;
1026}
1027
1028/**
1029 * hdd_map_dot_11_mode() - transform dot11mode type specific to
1030 * vendor command
1031 * @dot11mode: dot11mode
1032 *
1033 * Return: Success(0) or reason code for failure
1034 */
1035static int hdd_convert_dot11mode(uint32_t dot11mode)
1036{
1037 uint32_t ret_val;
1038
1039 switch (dot11mode) {
1040 case eCSR_CFG_DOT11_MODE_11A:
1041 ret_val = QCA_WLAN_802_11_MODE_11A;
1042 break;
1043 case eCSR_CFG_DOT11_MODE_11B:
1044 ret_val = QCA_WLAN_802_11_MODE_11B;
1045 break;
1046 case eCSR_CFG_DOT11_MODE_11G:
1047 ret_val = QCA_WLAN_802_11_MODE_11G;
1048 break;
1049 case eCSR_CFG_DOT11_MODE_11N:
1050 ret_val = QCA_WLAN_802_11_MODE_11N;
1051 break;
1052 case eCSR_CFG_DOT11_MODE_11AC:
1053 ret_val = QCA_WLAN_802_11_MODE_11AC;
1054 break;
1055 case eCSR_CFG_DOT11_MODE_AUTO:
1056 case eCSR_CFG_DOT11_MODE_ABG:
1057 default:
1058 ret_val = QCA_WLAN_802_11_MODE_INVALID;
1059 }
1060 return ret_val;
1061}
1062
1063/**
1064 * hdd_add_tx_bitrate() - add tx bitrate attribute
1065 * @skb: pointer to sk buff
1066 * @hdd_sta_ctx: pointer to hdd station context
1067 * @idx: attribute index
1068 *
1069 * Return: Success(0) or reason code for failure
1070 */
1071static int32_t hdd_add_tx_bitrate(struct sk_buff *skb,
1072 hdd_station_ctx_t *hdd_sta_ctx,
1073 int idx)
1074{
1075 struct nlattr *nla_attr;
1076 uint32_t bitrate, bitrate_compat;
1077
1078 nla_attr = nla_nest_start(skb, idx);
1079 if (!nla_attr)
1080 goto fail;
1081 /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301082 bitrate = cfg80211_calculate_bitrate(
1083 &hdd_sta_ctx->cache_conn_info.txrate);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301084
1085 /* report 16-bit bitrate only if we can */
1086 bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0;
1087 if (bitrate > 0 &&
1088 nla_put_u32(skb, NL80211_RATE_INFO_BITRATE32, bitrate)) {
1089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1090 goto fail;
1091 }
1092 if (bitrate_compat > 0 &&
1093 nla_put_u16(skb, NL80211_RATE_INFO_BITRATE, bitrate_compat)) {
1094 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1095 goto fail;
1096 }
1097 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301098 hdd_sta_ctx->cache_conn_info.txrate.nss)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1100 goto fail;
1101 }
1102 nla_nest_end(skb, nla_attr);
1103 return 0;
1104fail:
1105 return -EINVAL;
1106}
1107
1108/**
1109 * hdd_add_sta_info() - add station info attribute
1110 * @skb: pointer to sk buff
1111 * @hdd_sta_ctx: pointer to hdd station context
1112 * @idx: attribute index
1113 *
1114 * Return: Success(0) or reason code for failure
1115 */
1116static int32_t hdd_add_sta_info(struct sk_buff *skb,
1117 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1118{
1119 struct nlattr *nla_attr;
1120
1121 nla_attr = nla_nest_start(skb, idx);
1122 if (!nla_attr)
1123 goto fail;
1124 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301125 (hdd_sta_ctx->cache_conn_info.signal + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1127 goto fail;
1128 }
1129 if (hdd_add_tx_bitrate(skb, hdd_sta_ctx, NL80211_STA_INFO_TX_BITRATE))
1130 goto fail;
1131 nla_nest_end(skb, nla_attr);
1132 return 0;
1133fail:
1134 return -EINVAL;
1135}
1136
1137/**
1138 * hdd_add_survey_info() - add survey info attribute
1139 * @skb: pointer to sk buff
1140 * @hdd_sta_ctx: pointer to hdd station context
1141 * @idx: attribute index
1142 *
1143 * Return: Success(0) or reason code for failure
1144 */
1145static int32_t hdd_add_survey_info(struct sk_buff *skb,
1146 hdd_station_ctx_t *hdd_sta_ctx,
1147 int idx)
1148{
1149 struct nlattr *nla_attr;
1150
1151 nla_attr = nla_nest_start(skb, idx);
1152 if (!nla_attr)
1153 goto fail;
1154 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301155 hdd_sta_ctx->cache_conn_info.freq) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301156 nla_put_u8(skb, NL80211_SURVEY_INFO_NOISE,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301157 (hdd_sta_ctx->cache_conn_info.noise + 100))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1159 goto fail;
1160 }
1161 nla_nest_end(skb, nla_attr);
1162 return 0;
1163fail:
1164 return -EINVAL;
1165}
1166
1167/**
1168 * hdd_add_link_standard_info() - add link info attribute
1169 * @skb: pointer to sk buff
1170 * @hdd_sta_ctx: pointer to hdd station context
1171 * @idx: attribute index
1172 *
1173 * Return: Success(0) or reason code for failure
1174 */
1175static int32_t
1176hdd_add_link_standard_info(struct sk_buff *skb,
1177 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1178{
1179 struct nlattr *nla_attr;
1180
1181 nla_attr = nla_nest_start(skb, idx);
1182 if (!nla_attr)
1183 goto fail;
1184 if (nla_put(skb,
1185 NL80211_ATTR_SSID,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301186 hdd_sta_ctx->cache_conn_info.SSID.SSID.length,
1187 hdd_sta_ctx->cache_conn_info.SSID.SSID.ssId)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1189 goto fail;
1190 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301191 if (nla_put(skb, NL80211_ATTR_MAC, VOS_MAC_ADDR_SIZE,
1192 hdd_sta_ctx->cache_conn_info.bssId))
1193 goto fail;
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301194 if (hdd_add_survey_info(skb, hdd_sta_ctx, NL80211_ATTR_SURVEY_INFO))
1195 goto fail;
1196 if (hdd_add_sta_info(skb, hdd_sta_ctx, NL80211_ATTR_STA_INFO))
1197 goto fail;
1198 nla_nest_end(skb, nla_attr);
1199 return 0;
1200fail:
1201 return -EINVAL;
1202}
1203
1204/**
1205 * hdd_add_ap_standard_info() - add ap info attribute
1206 * @skb: pointer to sk buff
1207 * @hdd_sta_ctx: pointer to hdd station context
1208 * @idx: attribute index
1209 *
1210 * Return: Success(0) or reason code for failure
1211 */
1212static int32_t
1213hdd_add_ap_standard_info(struct sk_buff *skb,
1214 hdd_station_ctx_t *hdd_sta_ctx, int idx)
1215{
1216 struct nlattr *nla_attr;
1217
1218 nla_attr = nla_nest_start(skb, idx);
1219 if (!nla_attr)
1220 goto fail;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301221 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301222 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301223 sizeof(hdd_sta_ctx->cache_conn_info.vht_caps),
1224 &hdd_sta_ctx->cache_conn_info.vht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1226 goto fail;
1227 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301228 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301229 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301230 sizeof(hdd_sta_ctx->cache_conn_info.ht_caps),
1231 &hdd_sta_ctx->cache_conn_info.ht_caps)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1233 goto fail;
1234 }
1235 nla_nest_end(skb, nla_attr);
1236 return 0;
1237fail:
1238 return -EINVAL;
1239}
1240
1241/**
1242 * hdd_get_station_info() - send BSS information to supplicant
1243 * @hdd_ctx: pointer to hdd context
1244 * @adapter: pointer to adapter
1245 *
1246 * Return: 0 if success else error status
1247 */
1248static int hdd_get_station_info(hdd_context_t *hdd_ctx,
1249 hdd_adapter_t *adapter)
1250{
1251 struct sk_buff *skb = NULL;
1252 uint8_t *tmp_hs20 = NULL;
1253 uint32_t nl_buf_len;
1254 hdd_station_ctx_t *hdd_sta_ctx;
1255
1256 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1257
1258 nl_buf_len = NLMSG_HDRLEN;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301259
1260 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.SSID.SSID.length) +
1261 VOS_MAC_ADDR_SIZE +
1262 sizeof(hdd_sta_ctx->cache_conn_info.freq) +
1263 sizeof(hdd_sta_ctx->cache_conn_info.noise) +
1264 sizeof(hdd_sta_ctx->cache_conn_info.signal) +
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301265 (sizeof(uint32_t) * 2) +
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301266 sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
1267 sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
1268 sizeof(hdd_sta_ctx->cache_conn_info.authType) +
1269 sizeof(hdd_sta_ctx->cache_conn_info.dot11Mode);
1270 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
1271 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
1272 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
1273 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
1274 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
1275 tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
1276 cache_conn_info.hs20vendor_ie);
1277 nl_buf_len +=
1278 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie) -
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301279 1);
1280 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301281 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
1282 nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_operation);
1283 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
1284 nl_buf_len +=
1285 sizeof(hdd_sta_ctx->cache_conn_info.vht_operation);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301286
1287
1288 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1289 if (!skb) {
1290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"%s: %d cfg80211_vendor_cmd_alloc_reply_skb failed",
1291 __func__, __LINE__);
1292 return -ENOMEM;
1293 }
1294
1295 if (hdd_add_link_standard_info(skb, hdd_sta_ctx,
1296 LINK_INFO_STANDARD_NL80211_ATTR)) {
1297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1298 goto fail;
1299 }
1300 if (hdd_add_ap_standard_info(skb, hdd_sta_ctx,
1301 AP_INFO_STANDARD_NL80211_ATTR)) {
1302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1303 goto fail;
1304 }
1305 if (nla_put_u32(skb, INFO_ROAM_COUNT,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301306 hdd_sta_ctx->cache_conn_info.roam_count) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301307 nla_put_u32(skb, INFO_AKM,
1308 hdd_convert_auth_type(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301309 hdd_sta_ctx->cache_conn_info.authType)) ||
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301310 nla_put_u32(skb, WLAN802_11_MODE,
1311 hdd_convert_dot11mode(
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301312 hdd_sta_ctx->cache_conn_info.dot11Mode))) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1314 goto fail;
1315 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301316 if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301317 if (nla_put(skb, HT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301318 (sizeof(hdd_sta_ctx->cache_conn_info.ht_operation)),
1319 &hdd_sta_ctx->cache_conn_info.ht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1321 goto fail;
1322 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301323 if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301324 if (nla_put(skb, VHT_OPERATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301325 (sizeof(hdd_sta_ctx->
1326 cache_conn_info.vht_operation)),
1327 &hdd_sta_ctx->cache_conn_info.vht_operation)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1329 goto fail;
1330 }
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301331 if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present)
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301332 if (nla_put(skb, AP_INFO_HS20_INDICATION,
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +05301333 (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
1334 - 1), tmp_hs20 + 1)) {
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"put fail");
1336 goto fail;
1337 }
1338
1339 return cfg80211_vendor_cmd_reply(skb);
1340fail:
1341 if (skb)
1342 kfree_skb(skb);
1343 return -EINVAL;
1344}
1345
1346/**
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301347 * hdd_add_survey_info_sap_get_len - get data length used in
1348 * hdd_add_survey_info_sap()
1349 *
1350 * This function calculates the data length used in hdd_add_survey_info_sap()
1351 *
1352 * Return: total data length used in hdd_add_survey_info_sap()
1353 */
1354static uint32_t hdd_add_survey_info_sap_get_len(void)
1355{
1356 return ((NLA_HDRLEN) + (sizeof(uint32_t) + NLA_HDRLEN));
1357}
1358
1359/**
1360 * hdd_add_survey_info - add survey info attribute
1361 * @skb: pointer to response skb buffer
1362 * @stainfo: station information
1363 * @idx: attribute type index for nla_next_start()
1364 *
1365 * This function adds survey info attribute to response skb buffer
1366 *
1367 * Return : 0 on success and errno on failure
1368 */
1369static int32_t hdd_add_survey_info_sap(struct sk_buff *skb,
1370 struct hdd_cache_sta_info *stainfo,
1371 int idx)
1372{
1373 struct nlattr *nla_attr;
1374
1375 nla_attr = nla_nest_start(skb, idx);
1376 if (!nla_attr)
1377 goto fail;
1378 if (nla_put_u32(skb, NL80211_SURVEY_INFO_FREQUENCY,
1379 stainfo->freq)) {
1380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1381 FL("put fail"));
1382 goto fail;
1383 }
1384 nla_nest_end(skb, nla_attr);
1385 return 0;
1386fail:
1387 return -EINVAL;
1388}
1389
1390/**
1391 * hdd_add_tx_bitrate_sap_get_len - get data length used in
1392 * hdd_add_tx_bitrate_sap()
1393 *
1394 * This function calculates the data length used in hdd_add_tx_bitrate_sap()
1395 *
1396 * Return: total data length used in hdd_add_tx_bitrate_sap()
1397 */
1398static uint32_t hdd_add_tx_bitrate_sap_get_len(void)
1399{
1400 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN));
1401}
1402
1403/**
1404 * hdd_add_tx_bitrate_sap - add vht nss info attribute
1405 * @skb: pointer to response skb buffer
1406 * @stainfo: station information
1407 * @idx: attribute type index for nla_next_start()
1408 *
1409 * This function adds vht nss attribute to response skb buffer
1410 *
1411 * Return : 0 on success and errno on failure
1412 */
1413static int hdd_add_tx_bitrate_sap(struct sk_buff *skb,
1414 struct hdd_cache_sta_info *stainfo,
1415 int idx)
1416{
1417 struct nlattr *nla_attr;
1418
1419 nla_attr = nla_nest_start(skb, idx);
1420 if (!nla_attr)
1421 goto fail;
1422
1423 if (nla_put_u8(skb, NL80211_RATE_INFO_VHT_NSS,
1424 stainfo->nss)) {
1425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1426 FL("put fail"));
1427 goto fail;
1428 }
1429 nla_nest_end(skb, nla_attr);
1430 return 0;
1431fail:
1432 return -EINVAL;
1433}
1434
1435/**
1436 * hdd_add_sta_info_sap_get_len - get data length used in
1437 * hdd_add_sta_info_sap()
1438 *
1439 * This function calculates the data length used in hdd_add_sta_info_sap()
1440 *
1441 * Return: total data length used in hdd_add_sta_info_sap()
1442 */
1443static uint32_t hdd_add_sta_info_sap_get_len(void)
1444{
1445 return ((NLA_HDRLEN) + (sizeof(uint8_t) + NLA_HDRLEN) +
1446 hdd_add_tx_bitrate_sap_get_len());
1447}
1448
1449/**
1450 * hdd_add_sta_info_sap - add sta signal info attribute
1451 * @skb: pointer to response skb buffer
1452 * @rssi: peer rssi value
1453 * @stainfo: station information
1454 * @idx: attribute type index for nla_next_start()
1455 *
1456 * This function adds sta signal attribute to response skb buffer
1457 *
1458 * Return : 0 on success and errno on failure
1459 */
1460static int32_t hdd_add_sta_info_sap(struct sk_buff *skb, int8_t rssi,
1461 struct hdd_cache_sta_info *stainfo, int idx)
1462{
1463 struct nlattr *nla_attr;
1464
1465 nla_attr = nla_nest_start(skb, idx);
1466 if (!nla_attr)
1467 goto fail;
1468
Hanumanth Reddy Pothula14bc86d2018-01-02 20:02:02 +05301469 /* upperlayer expects positive rssi value */
1470 if (nla_put_u8(skb, NL80211_STA_INFO_SIGNAL, (rssi + 96))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1472 FL("put fail"));
1473 goto fail;
1474 }
1475 if (hdd_add_tx_bitrate_sap(skb, stainfo, NL80211_STA_INFO_TX_BITRATE)) {
1476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1477 FL("put fail"));
1478 goto fail;
1479 }
1480
1481 nla_nest_end(skb, nla_attr);
1482 return 0;
1483fail:
1484 return -EINVAL;
1485}
1486
1487/**
1488 * hdd_add_link_standard_info_sap_get_len - get data length used in
1489 * hdd_add_link_standard_info_sap()
1490 *
1491 * This function calculates the data length used in
1492 * hdd_add_link_standard_info_sap()
1493 *
1494 * Return: total data length used in hdd_add_link_standard_info_sap()
1495 */
1496static uint32_t hdd_add_link_standard_info_sap_get_len(void)
1497{
1498 return ((NLA_HDRLEN) +
1499 hdd_add_survey_info_sap_get_len() +
1500 hdd_add_sta_info_sap_get_len() +
1501 (sizeof(uint32_t) + NLA_HDRLEN));
1502}
1503
1504/**
1505 * hdd_add_link_standard_info_sap - add add link info attribut
1506 * @skb: pointer to response skb buffer
1507 * @stainfo: station information
1508 * @idx: attribute type index for nla_next_start()
1509 *
1510 * This function adds link info attribut to response skb buffer
1511 *
1512 * Return : 0 on success and errno on failure
1513 */
1514static int hdd_add_link_standard_info_sap(struct sk_buff *skb, int8_t rssi,
1515 struct hdd_cache_sta_info *stainfo,
1516 int idx)
1517{
1518 struct nlattr *nla_attr;
1519
1520 nla_attr = nla_nest_start(skb, idx);
1521 if (!nla_attr)
1522 goto fail;
1523 if (hdd_add_survey_info_sap(skb, stainfo, NL80211_ATTR_SURVEY_INFO))
1524 goto fail;
1525 if (hdd_add_sta_info_sap(skb, rssi, stainfo, NL80211_ATTR_STA_INFO))
1526 goto fail;
1527
1528 if (nla_put_u32(skb, NL80211_ATTR_REASON_CODE, stainfo->reason_code)) {
1529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1530 FL("put fail"));
1531 goto fail;
1532 }
1533
1534 nla_nest_end(skb, nla_attr);
1535 return 0;
1536fail:
1537 return -EINVAL;
1538}
1539
1540/**
1541 * hdd_add_ap_standard_info_sap_get_len - get data length used in
1542 * hdd_add_ap_standard_info_sap()
1543 * @stainfo: station information
1544 *
1545 * This function calculates the data length used in
1546 * hdd_add_ap_standard_info_sap()
1547 *
1548 * Return: total data length used in hdd_add_ap_standard_info_sap()
1549 */
1550static uint32_t hdd_add_ap_standard_info_sap_get_len(
1551 struct hdd_cache_sta_info *stainfo)
1552{
1553 uint32_t len;
1554
1555 len = NLA_HDRLEN;
1556 if (stainfo->vht_present)
1557 len += (sizeof(stainfo->vht_caps) + NLA_HDRLEN);
1558 if (stainfo->ht_present)
1559 len += (sizeof(stainfo->ht_caps) + NLA_HDRLEN);
1560
1561 return len;
1562}
1563
1564/**
1565 * hdd_add_ap_standard_info_sap - add HT and VHT info attributes
1566 * @skb: pointer to response skb buffer
1567 * @stainfo: station information
1568 * @idx: attribute type index for nla_next_start()
1569 *
1570 * This function adds HT and VHT info attributes to response skb buffer
1571 *
1572 * Return : 0 on success and errno on failure
1573 */
1574static int hdd_add_ap_standard_info_sap(struct sk_buff *skb,
1575 struct hdd_cache_sta_info *stainfo,
1576 int idx)
1577{
1578 struct nlattr *nla_attr;
1579
1580 nla_attr = nla_nest_start(skb, idx);
1581 if (!nla_attr)
1582 goto fail;
1583
1584 if (stainfo->vht_present) {
1585 if (nla_put(skb, NL80211_ATTR_VHT_CAPABILITY,
1586 sizeof(stainfo->vht_caps),
1587 &stainfo->vht_caps)) {
1588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1589 FL("put fail"));
1590 goto fail;
1591 }
1592 }
1593 if (stainfo->ht_present) {
1594 if (nla_put(skb, NL80211_ATTR_HT_CAPABILITY,
1595 sizeof(stainfo->ht_caps),
1596 &stainfo->ht_caps)) {
1597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1598 FL("put fail"));
1599 goto fail;
1600 }
1601 }
1602 nla_nest_end(skb, nla_attr);
1603 return 0;
1604fail:
1605 return -EINVAL;
1606}
1607
1608/**
1609 * hdd_decode_ch_width - decode channel band width based
1610 * @ch_width: encoded enum value holding channel band width
1611 *
1612 * This function decodes channel band width from the given encoded enum value.
1613 *
1614 * Returns: decoded channel band width.
1615 */
1616static uint8_t hdd_decode_ch_width(tSirMacHTChannelWidth ch_width)
1617{
1618 switch (ch_width) {
1619 case 0:
1620 return 20;
1621 case 1:
1622 return 40;
1623 case 2:
1624 return 80;
1625 default:
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1627 "invalid enum: %d", ch_width);
1628 return 20;
1629 }
1630}
1631
1632/**
1633 * hdd_get_cached_station_remote() - get cached(deleted) peer's info
1634 * @hdd_ctx: hdd context
1635 * @adapter: hostapd interface
1636 * @mac_addr: mac address of requested peer
1637 *
1638 * This function collect and indicate the cached(deleted) peer's info
1639 *
1640 * Return: 0 on success, otherwise error value
1641 */
1642static int hdd_get_cached_station_remote(hdd_context_t *hdd_ctx,
1643 hdd_adapter_t *adapter,
1644 v_MACADDR_t mac_addr)
1645{
1646 struct hdd_cache_sta_info *stainfo;
1647 struct sk_buff *skb = NULL;
1648 uint32_t nl_buf_len;
1649 uint8_t cw;
1650 ptSapContext sap_ctx;
1651 v_CONTEXT_t vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
1652
1653 sap_ctx = VOS_GET_SAP_CB(vos_ctx);
1654 if(sap_ctx == NULL){
1655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1656 FL("psapCtx is NULL"));
1657 return -ENOENT;
1658 }
1659
1660 stainfo = hdd_get_cache_stainfo(sap_ctx->cache_sta_info,
1661 mac_addr.bytes);
1662 if (!stainfo) {
1663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1664 "peer " MAC_ADDRESS_STR " not found",
1665 MAC_ADDR_ARRAY(mac_addr.bytes));
1666 return -EINVAL;
1667 }
1668 if (sap_ctx->aStaInfo[stainfo->ucSTAId].isUsed == TRUE) {
1669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1670 "peer " MAC_ADDRESS_STR " is in connected state",
1671 MAC_ADDR_ARRAY(mac_addr.bytes));
1672 return -EINVAL;
1673 }
1674
1675
1676 nl_buf_len = NLMSG_HDRLEN + hdd_add_link_standard_info_sap_get_len() +
1677 hdd_add_ap_standard_info_sap_get_len(stainfo) +
1678 (sizeof(stainfo->dot11_mode) + NLA_HDRLEN) +
1679 (sizeof(cw) + NLA_HDRLEN) +
1680 (sizeof(stainfo->rx_rate) + NLA_HDRLEN);
1681
1682 skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
1683 if (!skb) {
1684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "cfg80211_vendor_cmd_alloc_reply_skb failed");
1685 return -ENOMEM;
1686 }
1687
1688 if (hdd_add_link_standard_info_sap(skb, stainfo->rssi, stainfo,
1689 LINK_INFO_STANDARD_NL80211_ATTR)) {
1690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "link standard put fail");
1691 goto fail;
1692 }
1693
1694 if (hdd_add_ap_standard_info_sap(skb, stainfo,
1695 AP_INFO_STANDARD_NL80211_ATTR)) {
1696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "ap standard put fail");
1697 goto fail;
1698 }
1699
1700 /* upper layer expects decoded channel BW */
1701 cw = hdd_decode_ch_width(stainfo->ch_width);
1702 if (nla_put_u32(skb, REMOTE_SUPPORTED_MODE, stainfo->dot11_mode) ||
1703 nla_put_u8(skb, REMOTE_CH_WIDTH, cw)) {
1704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "remote ch put fail");
1705 goto fail;
1706 }
Hanumanth Reddy Pothula504fe152018-01-02 20:41:03 +05301707 if (nla_put_u32(skb, REMOTE_LAST_RX_RATE, (stainfo->rx_rate * 100))) {
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, "rx rate put fail");
1709 goto fail;
1710 }
1711
1712 vos_mem_zero(stainfo, sizeof(*stainfo));
1713
1714 return cfg80211_vendor_cmd_reply(skb);
1715fail:
1716 if (skb)
1717 kfree_skb(skb);
1718
1719 return -EINVAL;
1720}
1721
1722/**
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301723 * __hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1724 * @wiphy: corestack handler
1725 * @wdev: wireless device
1726 * @data: data
1727 * @data_len: data length
1728 *
1729 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1730 * Validate cmd attributes and send the station info to upper layers.
1731 *
1732 * Return: Success(0) or reason code for failure
1733 */
1734static int32_t
1735__hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1736 struct wireless_dev *wdev,
1737 const void *data,
1738 int data_len)
1739{
1740 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
1741 struct net_device *dev = wdev->netdev;
1742 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
1743 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX + 1];
1744 int32_t status;
1745
1746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"Enter");
1747 if (VOS_FTM_MODE == hdd_get_conparam()) {
1748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Command not allowed in FTM mode");
1749 status = -EPERM;
1750 goto out;
1751 }
1752
1753 status = wlan_hdd_validate_context(hdd_ctx);
1754 if (0 != status)
1755 goto out;
1756
1757
1758 status = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_STATION_MAX,
1759 data, data_len, NULL);
1760 if (status) {
1761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"Invalid ATTR");
1762 goto out;
1763 }
1764
1765 /* Parse and fetch Command Type*/
1766 if (tb[STATION_INFO]) {
1767 status = hdd_get_station_info(hdd_ctx, adapter);
1768 } else if (tb[STATION_ASSOC_FAIL_REASON]) {
1769 status = hdd_get_station_assoc_fail(hdd_ctx, adapter);
Hanumanth Reddy Pothulaa35c4872017-12-14 20:47:59 +05301770 } else if (tb[STATION_REMOTE]) {
1771 v_MACADDR_t mac_addr;
1772
1773 if (adapter->device_mode != WLAN_HDD_SOFTAP &&
1774 adapter->device_mode != WLAN_HDD_P2P_GO) {
1775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"invalid device_mode:%d",
1776 adapter->device_mode);
1777 status = -EINVAL;
1778 goto out;
1779 }
1780
1781 nla_memcpy(mac_addr.bytes, tb[STATION_REMOTE],
1782 VOS_MAC_ADDRESS_LEN);
1783
1784 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "STATION_REMOTE "MAC_ADDRESS_STR"",
1785 MAC_ADDR_ARRAY(mac_addr.bytes));
1786
1787 status = hdd_get_cached_station_remote(hdd_ctx, adapter,
1788 mac_addr);
Anurag Chouhanfcd20172017-07-19 17:25:19 +05301789 } else {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,"get station info cmd type failed");
1791 status = -EINVAL;
1792 goto out;
1793 }
1794 EXIT();
1795out:
1796 return status;
1797}
1798
1799/**
1800 * wlan_hdd_cfg80211_get_station_cmd() - Handle get station vendor cmd
1801 * @wiphy: corestack handler
1802 * @wdev: wireless device
1803 * @data: data
1804 * @data_len: data length
1805 *
1806 * Handles QCA_NL80211_VENDOR_SUBCMD_GET_STATION.
1807 * Validate cmd attributes and send the station info to upper layers.
1808 *
1809 * Return: Success(0) or reason code for failure
1810 */
1811static int32_t
1812hdd_cfg80211_get_station_cmd(struct wiphy *wiphy,
1813 struct wireless_dev *wdev,
1814 const void *data,
1815 int data_len)
1816{
1817 int ret;
1818
1819 vos_ssr_protect(__func__);
1820 ret = __hdd_cfg80211_get_station_cmd(wiphy, wdev, data, data_len);
1821 vos_ssr_unprotect(__func__);
1822
1823 return ret;
1824}
1825
1826/*
1827 * undef short names defined for get station command
1828 * used by __wlan_hdd_cfg80211_get_station_cmd()
1829 */
1830#undef STATION_INVALID
1831#undef STATION_INFO
1832#undef STATION_ASSOC_FAIL_REASON
1833#undef STATION_MAX
Srinivas Dasari030bad32015-02-18 23:23:54 +05301834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835#ifdef WLAN_FEATURE_LINK_LAYER_STATS
1836
1837static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
1838 struct sk_buff *vendor_event)
1839{
1840 if (nla_put_u8(vendor_event,
1841 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
1842 stats->rate.preamble) ||
1843 nla_put_u8(vendor_event,
1844 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
1845 stats->rate.nss) ||
1846 nla_put_u8(vendor_event,
1847 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
1848 stats->rate.bw) ||
1849 nla_put_u8(vendor_event,
1850 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
1851 stats->rate.rateMcsIdx) ||
1852 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
1853 stats->rate.bitrate ) ||
1854 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
1855 stats->txMpdu ) ||
1856 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
1857 stats->rxMpdu ) ||
1858 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
1859 stats->mpduLost ) ||
1860 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
1861 stats->retries) ||
1862 nla_put_u32(vendor_event,
1863 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
1864 stats->retriesShort ) ||
1865 nla_put_u32(vendor_event,
1866 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
1867 stats->retriesLong))
1868 {
1869 hddLog(VOS_TRACE_LEVEL_ERROR,
1870 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1871 return FALSE;
1872 }
1873 return TRUE;
1874}
1875
1876static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
1877 struct sk_buff *vendor_event)
1878{
1879 u32 i = 0;
1880 struct nlattr *rateInfo;
1881 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
1882 stats->type) ||
1883 nla_put(vendor_event,
1884 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
1885 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
1886 nla_put_u32(vendor_event,
1887 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
1888 stats->capabilities) ||
1889 nla_put_u32(vendor_event,
1890 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
1891 stats->numRate))
1892 {
1893 hddLog(VOS_TRACE_LEVEL_ERROR,
1894 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1895 goto error;
1896 }
1897
1898 rateInfo = nla_nest_start(vendor_event,
1899 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301900 if(!rateInfo)
1901 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301902 for (i = 0; i < stats->numRate; i++)
1903 {
1904 struct nlattr *rates;
1905 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
1906 stats->rateStats +
1907 (i * sizeof(tSirWifiRateStat)));
1908 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301909 if(!rates)
1910 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301911
1912 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
1913 {
1914 hddLog(VOS_TRACE_LEVEL_ERROR,
1915 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1916 return FALSE;
1917 }
1918 nla_nest_end(vendor_event, rates);
1919 }
1920 nla_nest_end(vendor_event, rateInfo);
1921
1922 return TRUE;
1923error:
1924 return FALSE;
1925}
1926
1927static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
1928 struct sk_buff *vendor_event)
1929{
1930 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
1931 stats->ac ) ||
1932 nla_put_u32(vendor_event,
1933 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
1934 stats->txMpdu ) ||
1935 nla_put_u32(vendor_event,
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
1937 stats->rxMpdu ) ||
1938 nla_put_u32(vendor_event,
1939 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
1940 stats->txMcast ) ||
1941 nla_put_u32(vendor_event,
1942 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
1943 stats->rxMcast ) ||
1944 nla_put_u32(vendor_event,
1945 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
1946 stats->rxAmpdu ) ||
1947 nla_put_u32(vendor_event,
1948 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
1949 stats->txAmpdu ) ||
1950 nla_put_u32(vendor_event,
1951 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
1952 stats->mpduLost )||
1953 nla_put_u32(vendor_event,
1954 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
1955 stats->retries ) ||
1956 nla_put_u32(vendor_event,
1957 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
1958 stats->retriesShort ) ||
1959 nla_put_u32(vendor_event,
1960 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
1961 stats->retriesLong ) ||
1962 nla_put_u32(vendor_event,
1963 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
1964 stats->contentionTimeMin ) ||
1965 nla_put_u32(vendor_event,
1966 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
1967 stats->contentionTimeMax ) ||
1968 nla_put_u32(vendor_event,
1969 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
1970 stats->contentionTimeAvg ) ||
1971 nla_put_u32(vendor_event,
1972 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
1973 stats->contentionNumSamples ))
1974 {
1975 hddLog(VOS_TRACE_LEVEL_ERROR,
1976 FL("QCA_WLAN_VENDOR_ATTR put fail") );
1977 return FALSE;
1978 }
1979 return TRUE;
1980}
1981
1982static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
1983 struct sk_buff *vendor_event)
1984{
Dino Myclec8f3f332014-07-21 16:48:27 +05301985 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301986 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
1987 nla_put(vendor_event,
1988 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
1989 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
1990 nla_put_u32(vendor_event,
1991 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
1992 stats->state ) ||
1993 nla_put_u32(vendor_event,
1994 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
1995 stats->roaming ) ||
1996 nla_put_u32(vendor_event,
1997 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
1998 stats->capabilities ) ||
1999 nla_put(vendor_event,
2000 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
2001 strlen(stats->ssid), stats->ssid) ||
2002 nla_put(vendor_event,
2003 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
2004 WNI_CFG_BSSID_LEN, stats->bssid) ||
2005 nla_put(vendor_event,
2006 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
2007 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
2008 nla_put(vendor_event,
2009 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
2010 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
2011 )
2012 {
2013 hddLog(VOS_TRACE_LEVEL_ERROR,
2014 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2015 return FALSE;
2016 }
2017 return TRUE;
2018}
2019
Dino Mycle3b9536d2014-07-09 22:05:24 +05302020static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
2021 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022 struct sk_buff *vendor_event)
2023{
2024 int i = 0;
2025 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302026 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2027 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302028 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302029
Sunil Duttc69bccb2014-05-26 21:30:20 +05302030 if (FALSE == put_wifi_interface_info(
2031 &pWifiIfaceStat->info,
2032 vendor_event))
2033 {
2034 hddLog(VOS_TRACE_LEVEL_ERROR,
2035 FL("QCA_WLAN_VENDOR_ATTR put fail") );
2036 return FALSE;
2037
2038 }
Dino Mycle3b9536d2014-07-09 22:05:24 +05302039 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
2040 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
2041 if (NULL == pWifiIfaceStatTL)
2042 {
2043 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
2044 return FALSE;
2045 }
2046
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05302047 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
2048 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
2049 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
2050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
2051
2052 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
2053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
2054 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
2055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302056
2057 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
2058 {
2059 if (VOS_STATUS_SUCCESS ==
2060 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2061 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
2062 {
2063 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
2064 * obtained from TL structure
2065 */
2066
2067 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
2068 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302069 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
2070
Srinivas Dasari98947432014-11-07 19:41:24 +05302071 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
2072 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
2073 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
2074 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
2075 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
2076 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
2077 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
2078 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302079
Srinivas Dasari98947432014-11-07 19:41:24 +05302080 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
2081 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
2082 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
2083 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
2084 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
2085 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
2086 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
2087 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302088
Srinivas Dasari98947432014-11-07 19:41:24 +05302089 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
2090 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
2091 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
2092 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
2093 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
2094 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
2095 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
2096 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05302097 }
2098 else
2099 {
2100 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
2101 }
2102
Dino Mycle3b9536d2014-07-09 22:05:24 +05302103 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
2104 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
2105 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
2106 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
2107 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
2108 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
2109 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
2110 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
2111 }
2112 else
2113 {
2114 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
2115 }
2116
2117
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118
2119 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302120 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2121 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
2122 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302123 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
2124 pWifiIfaceStat->beaconRx) ||
2125 nla_put_u32(vendor_event,
2126 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
2127 pWifiIfaceStat->mgmtRx) ||
2128 nla_put_u32(vendor_event,
2129 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
2130 pWifiIfaceStat->mgmtActionRx) ||
2131 nla_put_u32(vendor_event,
2132 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
2133 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302134 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302135 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
2136 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302137 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302138 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
2139 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05302140 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302141 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
2142 pWifiIfaceStat->rssiAck))
2143 {
2144 hddLog(VOS_TRACE_LEVEL_ERROR,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302145 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2146 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302147 return FALSE;
2148 }
2149
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302150#ifdef FEATURE_EXT_LL_STAT
2151 /*
2152 * Ensure when EXT_LL_STAT is supported by both host and fwr,
2153 * then host should send Leaky AP stats to upper layer,
2154 * otherwise no need to send these stats.
2155 */
2156 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
2157 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
2158 )
2159 {
2160 hddLog(VOS_TRACE_LEVEL_INFO,
2161 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
2162 pWifiIfaceStat->leakyApStat.is_leaky_ap,
2163 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
2164 pWifiIfaceStat->leakyApStat.rx_leak_window,
2165 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
2166 if (nla_put_u32(vendor_event,
2167 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
2168 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
2169 nla_put_u32(vendor_event,
2170 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
2171 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
2172 nla_put_u32(vendor_event,
2173 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
2174 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05302175 hdd_wlan_nla_put_u64(vendor_event,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05302176 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
2177 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
2178 {
2179 hddLog(VOS_TRACE_LEVEL_ERROR,
2180 FL("EXT_LL_STAT put fail"));
2181 vos_mem_free(pWifiIfaceStatTL);
2182 return FALSE;
2183 }
2184 }
2185#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05302186 wmmInfo = nla_nest_start(vendor_event,
2187 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302188 if(!wmmInfo)
2189 {
2190 vos_mem_free(pWifiIfaceStatTL);
2191 return FALSE;
2192 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302193 for (i = 0; i < WIFI_AC_MAX; i++)
2194 {
2195 struct nlattr *wmmStats;
2196 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302197 if(!wmmStats)
2198 {
2199 vos_mem_free(pWifiIfaceStatTL);
2200 return FALSE;
2201 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302202 if (FALSE == put_wifi_wmm_ac_stat(
2203 &pWifiIfaceStat->AccessclassStats[i],
2204 vendor_event))
2205 {
2206 hddLog(VOS_TRACE_LEVEL_ERROR,
2207 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05302208 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 return FALSE;
2210 }
2211
2212 nla_nest_end(vendor_event, wmmStats);
2213 }
2214 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05302215 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302216 return TRUE;
2217}
2218
2219static tSirWifiInterfaceMode
2220 hdd_map_device_to_ll_iface_mode ( int deviceMode )
2221{
2222 switch (deviceMode)
2223 {
2224 case WLAN_HDD_INFRA_STATION:
2225 return WIFI_INTERFACE_STA;
2226 case WLAN_HDD_SOFTAP:
2227 return WIFI_INTERFACE_SOFTAP;
2228 case WLAN_HDD_P2P_CLIENT:
2229 return WIFI_INTERFACE_P2P_CLIENT;
2230 case WLAN_HDD_P2P_GO:
2231 return WIFI_INTERFACE_P2P_GO;
2232 case WLAN_HDD_IBSS:
2233 return WIFI_INTERFACE_IBSS;
2234 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05302235 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 }
2237}
2238
2239static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
2240 tpSirWifiInterfaceInfo pInfo)
2241{
2242 v_U8_t *staMac = NULL;
2243 hdd_station_ctx_t *pHddStaCtx;
2244 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2245 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
2246
2247 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
2248
2249 vos_mem_copy(pInfo->macAddr,
2250 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
2251
2252 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
2253 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
2254 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
2255 {
2256 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2257 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
2258 {
2259 pInfo->state = WIFI_DISCONNECTED;
2260 }
2261 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
2262 {
2263 hddLog(VOS_TRACE_LEVEL_ERROR,
2264 "%s: Session ID %d, Connection is in progress", __func__,
2265 pAdapter->sessionId);
2266 pInfo->state = WIFI_ASSOCIATING;
2267 }
2268 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
2269 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
2270 {
2271 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
2272 hddLog(VOS_TRACE_LEVEL_ERROR,
2273 "%s: client " MAC_ADDRESS_STR
2274 " is in the middle of WPS/EAPOL exchange.", __func__,
2275 MAC_ADDR_ARRAY(staMac));
2276 pInfo->state = WIFI_AUTHENTICATING;
2277 }
2278 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
2279 {
2280 pInfo->state = WIFI_ASSOCIATED;
2281 vos_mem_copy(pInfo->bssid,
2282 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
2283 vos_mem_copy(pInfo->ssid,
2284 pHddStaCtx->conn_info.SSID.SSID.ssId,
2285 pHddStaCtx->conn_info.SSID.SSID.length);
2286 //NULL Terminate the string.
2287 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
2288 }
2289 }
2290 vos_mem_copy(pInfo->countryStr,
2291 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2292
2293 vos_mem_copy(pInfo->apCountryStr,
2294 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
2295
2296 return TRUE;
2297}
2298
2299/*
2300 * hdd_link_layer_process_peer_stats () - This function is called after
2301 * receiving Link Layer Peer statistics from FW.This function converts
2302 * the firmware data to the NL data and sends the same to the kernel/upper
2303 * layers.
2304 */
2305static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
2306 v_VOID_t *pData)
2307{
2308 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302309 tpSirWifiPeerStat pWifiPeerStat;
2310 tpSirWifiPeerInfo pWifiPeerInfo;
2311 struct nlattr *peerInfo;
2312 struct sk_buff *vendor_event;
2313 int status, i;
2314
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302315 ENTER();
2316
Sunil Duttc69bccb2014-05-26 21:30:20 +05302317 status = wlan_hdd_validate_context(pHddCtx);
2318 if (0 != status)
2319 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302320 return;
2321 }
2322
2323 pWifiPeerStat = (tpSirWifiPeerStat) pData;
2324
2325 hddLog(VOS_TRACE_LEVEL_INFO,
2326 "LL_STATS_PEER_ALL : numPeers %u",
2327 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302328 /*
2329 * Allocate a size of 4096 for the peer stats comprising
2330 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
2331 * sizeof (tSirWifiRateStat).Each field is put with an
2332 * NL attribute.The size of 4096 is considered assuming
2333 * that number of rates shall not exceed beyond 50 with
2334 * the sizeof (tSirWifiRateStat) being 32.
2335 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302336 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2337 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302338 if (!vendor_event)
2339 {
2340 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302341 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05302342 __func__);
2343 return;
2344 }
2345 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302346 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2347 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
2348 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302349 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
2350 pWifiPeerStat->numPeers))
2351 {
2352 hddLog(VOS_TRACE_LEVEL_ERROR,
2353 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
2354 kfree_skb(vendor_event);
2355 return;
2356 }
2357
2358 peerInfo = nla_nest_start(vendor_event,
2359 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302360 if(!peerInfo)
2361 {
2362 hddLog(VOS_TRACE_LEVEL_ERROR,
2363 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
2364 __func__);
2365 kfree_skb(vendor_event);
2366 return;
2367 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302368
2369 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2370 pWifiPeerStat->peerInfo);
2371
2372 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
2373 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302374 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302375 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302376
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302377 if(!peers)
2378 {
2379 hddLog(VOS_TRACE_LEVEL_ERROR,
2380 "%s: peer stats put fail",
2381 __func__);
2382 kfree_skb(vendor_event);
2383 return;
2384 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302385 if (FALSE == put_wifi_peer_info(
2386 pWifiPeerInfo, vendor_event))
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR,
2389 "%s: put_wifi_peer_info put fail", __func__);
2390 kfree_skb(vendor_event);
2391 return;
2392 }
2393
2394 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
2395 pWifiPeerStat->peerInfo +
2396 (i * sizeof(tSirWifiPeerInfo)) +
2397 (numRate * sizeof (tSirWifiRateStat)));
2398 nla_nest_end(vendor_event, peers);
2399 }
2400 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302401 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302402 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302403}
2404
2405/*
2406 * hdd_link_layer_process_iface_stats () - This function is called after
2407 * receiving Link Layer Interface statistics from FW.This function converts
2408 * the firmware data to the NL data and sends the same to the kernel/upper
2409 * layers.
2410 */
2411static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
2412 v_VOID_t *pData)
2413{
2414 tpSirWifiIfaceStat pWifiIfaceStat;
2415 struct sk_buff *vendor_event;
2416 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2417 int status;
2418
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302419 ENTER();
2420
Sunil Duttc69bccb2014-05-26 21:30:20 +05302421 status = wlan_hdd_validate_context(pHddCtx);
2422 if (0 != status)
2423 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302424 return;
2425 }
2426 /*
2427 * Allocate a size of 4096 for the interface stats comprising
2428 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
2429 * assuming that all these fit with in the limit.Please take
2430 * a call on the limit based on the data requirements on
2431 * interface statistics.
2432 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302433 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2434 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302435 if (!vendor_event)
2436 {
2437 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302438 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302439 return;
2440 }
2441
2442 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
2443
Dino Mycle3b9536d2014-07-09 22:05:24 +05302444
2445 if (FALSE == hdd_get_interface_info( pAdapter,
2446 &pWifiIfaceStat->info))
2447 {
2448 hddLog(VOS_TRACE_LEVEL_ERROR,
2449 FL("hdd_get_interface_info get fail") );
2450 kfree_skb(vendor_event);
2451 return;
2452 }
2453
2454 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
2455 vendor_event))
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR,
2458 FL("put_wifi_iface_stats fail") );
2459 kfree_skb(vendor_event);
2460 return;
2461 }
2462
Sunil Duttc69bccb2014-05-26 21:30:20 +05302463 hddLog(VOS_TRACE_LEVEL_INFO,
2464 "WMI_LINK_STATS_IFACE Data");
2465
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302466 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302467
2468 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302469}
2470
2471/*
2472 * hdd_link_layer_process_radio_stats () - This function is called after
2473 * receiving Link Layer Radio statistics from FW.This function converts
2474 * the firmware data to the NL data and sends the same to the kernel/upper
2475 * layers.
2476 */
2477static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
2478 v_VOID_t *pData)
2479{
2480 int status, i;
2481 tpSirWifiRadioStat pWifiRadioStat;
2482 tpSirWifiChannelStats pWifiChannelStats;
2483 struct sk_buff *vendor_event;
2484 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2485 struct nlattr *chList;
2486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302487 ENTER();
2488
Sunil Duttc69bccb2014-05-26 21:30:20 +05302489 status = wlan_hdd_validate_context(pHddCtx);
2490 if (0 != status)
2491 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302492 return;
2493 }
2494 pWifiRadioStat = (tpSirWifiRadioStat) pData;
2495
2496 hddLog(VOS_TRACE_LEVEL_INFO,
2497 "LL_STATS_RADIO"
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302498 " number of radios = %u"
Sunil Duttc69bccb2014-05-26 21:30:20 +05302499 " radio is %d onTime is %u "
2500 " txTime is %u rxTime is %u "
2501 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05302503 " onTimePnoScan is %u onTimeHs20 is %u "
2504 " numChannels is %u",
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302505 NUM_RADIOS,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302506 pWifiRadioStat->radio, pWifiRadioStat->onTime,
2507 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
2508 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302509 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302510 pWifiRadioStat->onTimeRoamScan,
2511 pWifiRadioStat->onTimePnoScan,
2512 pWifiRadioStat->onTimeHs20,
2513 pWifiRadioStat->numChannels);
2514 /*
2515 * Allocate a size of 4096 for the Radio stats comprising
2516 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
2517 * (tSirWifiChannelStats).Each channel data is put with an
2518 * NL attribute.The size of 4096 is considered assuming that
2519 * number of channels shall not exceed beyond 60 with the
2520 * sizeof (tSirWifiChannelStats) being 24 bytes.
2521 */
2522
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302523 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2524 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302525 if (!vendor_event)
2526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302528 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05302529 return;
2530 }
2531
2532 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302533 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
2534 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
2535 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302536 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
2537 pWifiRadioStat->radio) ||
2538 nla_put_u32(vendor_event,
Ravi Kumar Bokka93065922016-10-27 13:52:34 +05302539 QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS,
2540 NUM_RADIOS) ||
2541 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302542 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
2543 pWifiRadioStat->onTime) ||
2544 nla_put_u32(vendor_event,
2545 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
2546 pWifiRadioStat->txTime) ||
2547 nla_put_u32(vendor_event,
2548 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
2549 pWifiRadioStat->rxTime) ||
2550 nla_put_u32(vendor_event,
2551 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
2552 pWifiRadioStat->onTimeScan) ||
2553 nla_put_u32(vendor_event,
2554 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
2555 pWifiRadioStat->onTimeNbd) ||
2556 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302557 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
2558 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05302559 nla_put_u32(vendor_event,
2560 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
2561 pWifiRadioStat->onTimeRoamScan) ||
2562 nla_put_u32(vendor_event,
2563 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
2564 pWifiRadioStat->onTimePnoScan) ||
2565 nla_put_u32(vendor_event,
2566 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
2567 pWifiRadioStat->onTimeHs20) ||
2568 nla_put_u32(vendor_event,
2569 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
2570 pWifiRadioStat->numChannels))
2571 {
2572 hddLog(VOS_TRACE_LEVEL_ERROR,
2573 FL("QCA_WLAN_VENDOR_ATTR put fail"));
2574 kfree_skb(vendor_event);
2575 return ;
2576 }
2577
2578 chList = nla_nest_start(vendor_event,
2579 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302580 if(!chList)
2581 {
2582 hddLog(VOS_TRACE_LEVEL_ERROR,
2583 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
2584 __func__);
2585 kfree_skb(vendor_event);
2586 return;
2587 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302588 for (i = 0; i < pWifiRadioStat->numChannels; i++)
2589 {
2590 struct nlattr *chInfo;
2591
2592 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
2593 pWifiRadioStat->channels +
2594 (i * sizeof(tSirWifiChannelStats)));
2595
Sunil Duttc69bccb2014-05-26 21:30:20 +05302596 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05302597 if(!chInfo)
2598 {
2599 hddLog(VOS_TRACE_LEVEL_ERROR,
2600 "%s: failed to put chInfo",
2601 __func__);
2602 kfree_skb(vendor_event);
2603 return;
2604 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302605
2606 if (nla_put_u32(vendor_event,
2607 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
2608 pWifiChannelStats->channel.width) ||
2609 nla_put_u32(vendor_event,
2610 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
2611 pWifiChannelStats->channel.centerFreq) ||
2612 nla_put_u32(vendor_event,
2613 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
2614 pWifiChannelStats->channel.centerFreq0) ||
2615 nla_put_u32(vendor_event,
2616 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
2617 pWifiChannelStats->channel.centerFreq1) ||
2618 nla_put_u32(vendor_event,
2619 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
2620 pWifiChannelStats->onTime) ||
2621 nla_put_u32(vendor_event,
2622 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
2623 pWifiChannelStats->ccaBusyTime))
2624 {
2625 hddLog(VOS_TRACE_LEVEL_ERROR,
2626 FL("cfg80211_vendor_event_alloc failed") );
2627 kfree_skb(vendor_event);
2628 return ;
2629 }
2630 nla_nest_end(vendor_event, chInfo);
2631 }
2632 nla_nest_end(vendor_event, chList);
2633
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302634 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635
2636 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302637 return;
2638}
2639
2640/*
2641 * hdd_link_layer_stats_ind_callback () - This function is called after
2642 * receiving Link Layer indications from FW.This callback converts the firmware
2643 * data to the NL data and send the same to the kernel/upper layers.
2644 */
2645static void hdd_link_layer_stats_ind_callback ( void *pCtx,
2646 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05302647 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302648{
Dino Mycled3d50022014-07-07 12:58:25 +05302649 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
2650 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302651 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05302652 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302653 int status;
2654
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302655 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302656
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302657 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302658 if (0 != status)
2659 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302660 return;
2661 }
2662
Dino Mycled3d50022014-07-07 12:58:25 +05302663 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
2664 if (NULL == pAdapter)
2665 {
2666 hddLog(VOS_TRACE_LEVEL_ERROR,
2667 FL(" MAC address %pM does not exist with host"),
2668 macAddr);
2669 return;
2670 }
2671
Sunil Duttc69bccb2014-05-26 21:30:20 +05302672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302673 "%s: Interface: %s LLStats indType: %d", __func__,
2674 pAdapter->dev->name, indType);
2675
Sunil Duttc69bccb2014-05-26 21:30:20 +05302676 switch (indType)
2677 {
2678 case SIR_HAL_LL_STATS_RESULTS_RSP:
2679 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302680 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302681 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
2682 "respId = %u, moreResultToFollow = %u",
2683 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
2684 macAddr, linkLayerStatsResults->respId,
2685 linkLayerStatsResults->moreResultToFollow);
2686
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302687 spin_lock(&hdd_context_lock);
2688 context = &pHddCtx->ll_stats_context;
2689 /* validate response received from target */
2690 if ((context->request_id != linkLayerStatsResults->respId) ||
2691 !(context->request_bitmap & linkLayerStatsResults->paramId))
2692 {
2693 spin_unlock(&hdd_context_lock);
2694 hddLog(LOGE,
2695 FL("Error : Request id %d response id %d request bitmap 0x%x"
2696 "response bitmap 0x%x"),
2697 context->request_id, linkLayerStatsResults->respId,
2698 context->request_bitmap, linkLayerStatsResults->paramId);
2699 return;
2700 }
2701 spin_unlock(&hdd_context_lock);
2702
Sunil Duttc69bccb2014-05-26 21:30:20 +05302703 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
2704 {
2705 hdd_link_layer_process_radio_stats(pAdapter,
2706 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302707 spin_lock(&hdd_context_lock);
2708 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
2709 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302710 }
2711 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
2712 {
2713 hdd_link_layer_process_iface_stats(pAdapter,
2714 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302715 spin_lock(&hdd_context_lock);
2716 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
2717 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302718 }
2719 else if ( linkLayerStatsResults->paramId &
2720 WMI_LINK_STATS_ALL_PEER )
2721 {
2722 hdd_link_layer_process_peer_stats(pAdapter,
2723 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302724 spin_lock(&hdd_context_lock);
2725 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
2726 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302727 } /* WMI_LINK_STATS_ALL_PEER */
2728 else
2729 {
2730 hddLog(VOS_TRACE_LEVEL_ERROR,
2731 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
2732 }
2733
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302734 spin_lock(&hdd_context_lock);
2735 /* complete response event if all requests are completed */
2736 if (0 == context->request_bitmap)
2737 complete(&context->response_event);
2738 spin_unlock(&hdd_context_lock);
2739
Sunil Duttc69bccb2014-05-26 21:30:20 +05302740 break;
2741 }
2742 default:
2743 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
2744 break;
2745 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302746
2747 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302748 return;
2749}
2750
2751const struct
2752nla_policy
2753qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
2754{
2755 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
2756 { .type = NLA_U32 },
2757 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
2758 { .type = NLA_U32 },
2759};
2760
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302761static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2762 struct wireless_dev *wdev,
2763 const void *data,
2764 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302765{
2766 int status;
2767 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302768 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302769 struct net_device *dev = wdev->netdev;
2770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2771 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302773 ENTER();
2774
Sunil Duttc69bccb2014-05-26 21:30:20 +05302775 status = wlan_hdd_validate_context(pHddCtx);
2776 if (0 != status)
2777 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302778 return -EINVAL;
2779 }
2780
2781 if (NULL == pAdapter)
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR,
2784 FL("HDD adapter is Null"));
2785 return -ENODEV;
2786 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302787 /* check the LLStats Capability */
2788 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2789 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2790 {
Anurag Chouhan65ea6dc2016-10-25 19:59:14 +05302791 hddLog(VOS_TRACE_LEVEL_WARN,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302792 FL("Link Layer Statistics not supported by Firmware"));
2793 return -EINVAL;
2794 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302795
2796 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
2797 (struct nlattr *)data,
2798 data_len, qca_wlan_vendor_ll_set_policy))
2799 {
2800 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2801 return -EINVAL;
2802 }
2803 if (!tb_vendor
2804 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
2805 {
2806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
2807 return -EINVAL;
2808 }
2809 if (!tb_vendor[
2810 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
2813 return -EINVAL;
2814 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302815 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302816 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302817
Dino Mycledf0a5d92014-07-04 09:41:55 +05302818 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302819 nla_get_u32(
2820 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
2821
Dino Mycledf0a5d92014-07-04 09:41:55 +05302822 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302823 nla_get_u32(
2824 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
2825
Dino Mycled3d50022014-07-07 12:58:25 +05302826 vos_mem_copy(linkLayerStatsSetReq.macAddr,
2827 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302828
2829
2830 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302831 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
2832 "Statistics Gathering = %d ",
2833 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
2834 linkLayerStatsSetReq.mpduSizeThreshold,
2835 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302836
2837 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
2838 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05302839 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302840 {
2841 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2842 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302843 return -EINVAL;
2844
2845 }
Srinivas Dasari98947432014-11-07 19:41:24 +05302846
Sunil Duttc69bccb2014-05-26 21:30:20 +05302847 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302848 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302849 {
2850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2851 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302852 return -EINVAL;
2853 }
2854
2855 pAdapter->isLinkLayerStatsSet = 1;
2856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302857 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302858 return 0;
2859}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302860static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
2861 struct wireless_dev *wdev,
2862 const void *data,
2863 int data_len)
2864{
2865 int ret = 0;
2866
2867 vos_ssr_protect(__func__);
2868 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
2869 vos_ssr_unprotect(__func__);
2870
2871 return ret;
2872}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302873
2874const struct
2875nla_policy
2876qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
2877{
2878 /* Unsigned 32bit value provided by the caller issuing the GET stats
2879 * command. When reporting
2880 * the stats results, the driver uses the same value to indicate
2881 * which GET request the results
2882 * correspond to.
2883 */
2884 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
2885
2886 /* Unsigned 32bit value . bit mask to identify what statistics are
2887 requested for retrieval */
2888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
2889};
2890
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302891static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2892 struct wireless_dev *wdev,
2893 const void *data,
2894 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302895{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302896 unsigned long rc;
2897 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302898 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2899 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302900 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302901 struct net_device *dev = wdev->netdev;
2902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302903 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302904 int status;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
Sunil Duttc69bccb2014-05-26 21:30:20 +05302908 status = wlan_hdd_validate_context(pHddCtx);
2909 if (0 != status)
2910 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302911 return -EINVAL ;
2912 }
2913
2914 if (NULL == pAdapter)
2915 {
2916 hddLog(VOS_TRACE_LEVEL_FATAL,
2917 "%s: HDD adapter is Null", __func__);
2918 return -ENODEV;
2919 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302920
2921 if (pHddStaCtx == NULL)
2922 {
2923 hddLog(VOS_TRACE_LEVEL_FATAL,
2924 "%s: HddStaCtx is Null", __func__);
2925 return -ENODEV;
2926 }
2927
Dino Mycledf0a5d92014-07-04 09:41:55 +05302928 /* check the LLStats Capability */
2929 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2930 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2931 {
2932 hddLog(VOS_TRACE_LEVEL_ERROR,
2933 FL("Link Layer Statistics not supported by Firmware"));
2934 return -EINVAL;
2935 }
2936
Sunil Duttc69bccb2014-05-26 21:30:20 +05302937
2938 if (!pAdapter->isLinkLayerStatsSet)
2939 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05302940 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05302941 "%s: isLinkLayerStatsSet : %d",
2942 __func__, pAdapter->isLinkLayerStatsSet);
2943 return -EINVAL;
2944 }
2945
Mukul Sharma10313ba2015-07-29 19:14:39 +05302946 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2947 {
2948 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2949 "%s: Roaming in progress, so unable to proceed this request", __func__);
2950 return -EBUSY;
2951 }
2952
Sunil Duttc69bccb2014-05-26 21:30:20 +05302953 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2954 (struct nlattr *)data,
2955 data_len, qca_wlan_vendor_ll_get_policy))
2956 {
2957 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2958 return -EINVAL;
2959 }
2960
2961 if (!tb_vendor
2962 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2963 {
2964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2965 return -EINVAL;
2966 }
2967
2968 if (!tb_vendor
2969 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2970 {
2971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2972 return -EINVAL;
2973 }
2974
Sunil Duttc69bccb2014-05-26 21:30:20 +05302975
Dino Mycledf0a5d92014-07-04 09:41:55 +05302976 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302977 nla_get_u32( tb_vendor[
2978 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302979 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302980 nla_get_u32( tb_vendor[
2981 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2982
Dino Mycled3d50022014-07-07 12:58:25 +05302983 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2984 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302985
2986 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302987 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
2988 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302989 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302990
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302991 spin_lock(&hdd_context_lock);
2992 context = &pHddCtx->ll_stats_context;
2993 context->request_id = linkLayerStatsGetReq.reqId;
2994 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2995 INIT_COMPLETION(context->response_event);
2996 spin_unlock(&hdd_context_lock);
2997
Sunil Duttc69bccb2014-05-26 21:30:20 +05302998 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302999 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303000 {
3001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3002 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303003 return -EINVAL;
3004 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303005
mukul sharma4bd8d2e2015-08-13 20:33:25 +05303006 rc = wait_for_completion_timeout(&context->response_event,
3007 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
3008 if (!rc)
3009 {
3010 hddLog(LOGE,
3011 FL("Target response timed out request id %d request bitmap 0x%x"),
3012 context->request_id, context->request_bitmap);
3013 return -ETIMEDOUT;
3014 }
3015
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303016 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303017 return 0;
3018}
3019
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303020static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
3021 struct wireless_dev *wdev,
3022 const void *data,
3023 int data_len)
3024{
3025 int ret = 0;
3026
3027 vos_ssr_protect(__func__);
3028 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
3029 vos_ssr_unprotect(__func__);
3030
3031 return ret;
3032}
3033
Sunil Duttc69bccb2014-05-26 21:30:20 +05303034const struct
3035nla_policy
3036qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
3037{
3038 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
3039 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
3040 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
3041 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
3042};
3043
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303044static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3045 struct wireless_dev *wdev,
3046 const void *data,
3047 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303048{
3049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3050 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05303051 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303052 struct net_device *dev = wdev->netdev;
3053 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3054 u32 statsClearReqMask;
3055 u8 stopReq;
3056 int status;
3057
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303058 ENTER();
3059
Sunil Duttc69bccb2014-05-26 21:30:20 +05303060 status = wlan_hdd_validate_context(pHddCtx);
3061 if (0 != status)
3062 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05303063 return -EINVAL;
3064 }
3065
3066 if (NULL == pAdapter)
3067 {
3068 hddLog(VOS_TRACE_LEVEL_FATAL,
3069 "%s: HDD adapter is Null", __func__);
3070 return -ENODEV;
3071 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05303072 /* check the LLStats Capability */
3073 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
3074 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
3075 {
3076 hddLog(VOS_TRACE_LEVEL_ERROR,
3077 FL("Enable LLStats Capability"));
3078 return -EINVAL;
3079 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05303080
3081 if (!pAdapter->isLinkLayerStatsSet)
3082 {
3083 hddLog(VOS_TRACE_LEVEL_FATAL,
3084 "%s: isLinkLayerStatsSet : %d",
3085 __func__, pAdapter->isLinkLayerStatsSet);
3086 return -EINVAL;
3087 }
3088
3089 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
3090 (struct nlattr *)data,
3091 data_len, qca_wlan_vendor_ll_clr_policy))
3092 {
3093 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
3094 return -EINVAL;
3095 }
3096
3097 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
3098
3099 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
3100 {
3101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
3102 return -EINVAL;
3103
3104 }
3105
Sunil Duttc69bccb2014-05-26 21:30:20 +05303106
Dino Mycledf0a5d92014-07-04 09:41:55 +05303107 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303108 nla_get_u32(
3109 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
3110
Dino Mycledf0a5d92014-07-04 09:41:55 +05303111 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05303112 nla_get_u8(
3113 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
3114
3115 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05303116 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05303117
Dino Mycled3d50022014-07-07 12:58:25 +05303118 vos_mem_copy(linkLayerStatsClearReq.macAddr,
3119 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05303120
3121 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05303122 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
3123 "statsClearReqMask = 0x%X, stopReq = %d",
3124 linkLayerStatsClearReq.reqId,
3125 linkLayerStatsClearReq.macAddr,
3126 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303127 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05303128
3129 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303130 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05303131 {
3132 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05303133 hdd_station_ctx_t *pHddStaCtx;
3134
3135 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3136 if (VOS_STATUS_SUCCESS !=
3137 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
3138 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
3139 {
3140 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
3141 "WLANTL_ClearInterfaceStats Failed", __func__);
3142 return -EINVAL;
3143 }
3144 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
3145 (statsClearReqMask & WIFI_STATS_IFACE)) {
3146 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
3147 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
3148 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
3149 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
3150 }
3151
Sunil Duttc69bccb2014-05-26 21:30:20 +05303152 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
3153 2 * sizeof(u32) +
3154 NLMSG_HDRLEN);
3155
3156 if (temp_skbuff != NULL)
3157 {
3158
3159 if (nla_put_u32(temp_skbuff,
3160 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
3161 statsClearReqMask) ||
3162 nla_put_u32(temp_skbuff,
3163 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
3164 stopReq))
3165 {
3166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
3167 kfree_skb(temp_skbuff);
3168 return -EINVAL;
3169 }
3170 /* If the ask is to stop the stats collection as part of clear
3171 * (stopReq = 1) , ensure that no further requests of get
3172 * go to the firmware by having isLinkLayerStatsSet set to 0.
3173 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05303174 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05303175 * case the firmware is just asked to clear the statistics.
3176 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05303177 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05303178 pAdapter->isLinkLayerStatsSet = 0;
3179 return cfg80211_vendor_cmd_reply(temp_skbuff);
3180 }
3181 return -ENOMEM;
3182 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303183
3184 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05303185 return -EINVAL;
3186}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303187static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
3188 struct wireless_dev *wdev,
3189 const void *data,
3190 int data_len)
3191{
3192 int ret = 0;
3193
3194 vos_ssr_protect(__func__);
3195 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
3196 vos_ssr_unprotect(__func__);
3197
3198 return ret;
3199
3200
3201}
Sunil Duttc69bccb2014-05-26 21:30:20 +05303202#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
3203
Dino Mycle6fb96c12014-06-10 11:52:40 +05303204#ifdef WLAN_FEATURE_EXTSCAN
3205static const struct nla_policy
3206wlan_hdd_extscan_config_policy
3207 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
3208{
3209 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
3210 { .type = NLA_U32 },
3211 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
3212 { .type = NLA_U32 },
SaidiReddy Yenugaf2145922017-05-26 18:19:31 +05303213 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS] =
3214 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303215 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
3216 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
3217 { .type = NLA_U32 },
3218 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
3219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
3220
3221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
3222 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
3223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
3224 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
3225 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303226 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
3227 { .type = NLA_U32 },
3228 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
3229 { .type = NLA_U32 },
3230 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
3231 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303232 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
3233 { .type = NLA_U32 },
3234 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
3235 { .type = NLA_U32 },
3236 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
3237 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303238 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
3239 { .type = NLA_U8 },
3240 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303241 { .type = NLA_U8 },
3242 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
3243 { .type = NLA_U8 },
3244 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
3245 { .type = NLA_U8 },
3246
3247 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
3248 { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05303249 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] = {
3250 .type = NLA_UNSPEC,
3251 .len = HDD_MAC_ADDR_LEN},
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
3253 { .type = NLA_S32 },
3254 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
3255 { .type = NLA_S32 },
3256 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
3257 { .type = NLA_U32 },
3258 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
3259 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303260 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
3261 { .type = NLA_U32 },
3262 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
3263 { .type = NLA_BINARY,
3264 .len = IEEE80211_MAX_SSID_LEN + 1 },
3265 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05303266 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303267 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
3268 { .type = NLA_U32 },
3269 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
3270 { .type = NLA_U8 },
3271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
3272 { .type = NLA_S32 },
3273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
3274 { .type = NLA_S32 },
3275 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
3276 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277};
3278
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303279/**
3280 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
3281 * @ctx: hdd global context
3282 * @data: capabilities data
3283 *
3284 * Return: none
3285 */
3286static void
3287wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303289 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303290 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303291 tSirEXTScanCapabilitiesEvent *data =
3292 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303294 ENTER();
3295
3296 if (wlan_hdd_validate_context(pHddCtx))
3297 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303298 return;
3299 }
3300
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 if (!pMsg)
3302 {
3303 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3304 return;
3305 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303307 vos_spin_lock_acquire(&hdd_context_lock);
3308
3309 context = &pHddCtx->ext_scan_context;
3310 /* validate response received from target*/
3311 if (context->request_id != data->requestId)
3312 {
3313 vos_spin_lock_release(&hdd_context_lock);
3314 hddLog(LOGE,
3315 FL("Target response id did not match: request_id %d resposne_id %d"),
3316 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 return;
3318 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303319 else
3320 {
3321 context->capability_response = *data;
3322 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 }
3324
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303325 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 return;
3328}
3329
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303330/*
3331 * define short names for the global vendor params
3332 * used by wlan_hdd_send_ext_scan_capability()
3333 */
3334#define PARAM_REQUEST_ID \
3335 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3336#define PARAM_STATUS \
3337 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
3338#define MAX_SCAN_CACHE_SIZE \
3339 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
3340#define MAX_SCAN_BUCKETS \
3341 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
3342#define MAX_AP_CACHE_PER_SCAN \
3343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
3344#define MAX_RSSI_SAMPLE_SIZE \
3345 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
3346#define MAX_SCAN_RPT_THRHOLD \
3347 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
3348#define MAX_HOTLIST_BSSIDS \
3349 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
3350#define MAX_BSSID_HISTORY_ENTRIES \
3351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
3352#define MAX_HOTLIST_SSIDS \
3353 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303354#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
3355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303356
3357static int wlan_hdd_send_ext_scan_capability(void *ctx)
3358{
3359 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3360 struct sk_buff *skb = NULL;
3361 int ret;
3362 tSirEXTScanCapabilitiesEvent *data;
3363 tANI_U32 nl_buf_len;
3364
3365 ret = wlan_hdd_validate_context(pHddCtx);
3366 if (0 != ret)
3367 {
3368 return ret;
3369 }
3370
3371 data = &(pHddCtx->ext_scan_context.capability_response);
3372
3373 nl_buf_len = NLMSG_HDRLEN;
3374 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
3375 (sizeof(data->status) + NLA_HDRLEN) +
3376 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
3377 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
3378 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
3379 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
3380 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
3381 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
3382 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
3383 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
3384
3385 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
3386
3387 if (!skb)
3388 {
3389 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
3390 return -ENOMEM;
3391 }
3392
3393 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
3394 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
3395 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
3396 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
3397 data->maxRssiSampleSize, data->maxScanReportingThreshold);
3398 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
3399 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
3400 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
3401
3402 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
3403 nla_put_u32(skb, PARAM_STATUS, data->status) ||
3404 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
3405 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
3406 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
3407 data->maxApPerScan) ||
3408 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
3409 data->maxRssiSampleSize) ||
3410 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
3411 data->maxScanReportingThreshold) ||
3412 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
3413 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
3414 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303415 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
3416 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303417 {
3418 hddLog(LOGE, FL("nla put fail"));
3419 goto nla_put_failure;
3420 }
3421
3422 cfg80211_vendor_cmd_reply(skb);
3423 return 0;
3424
3425nla_put_failure:
3426 kfree_skb(skb);
3427 return -EINVAL;;
3428}
3429
3430/*
3431 * done with short names for the global vendor params
3432 * used by wlan_hdd_send_ext_scan_capability()
3433 */
3434#undef PARAM_REQUEST_ID
3435#undef PARAM_STATUS
3436#undef MAX_SCAN_CACHE_SIZE
3437#undef MAX_SCAN_BUCKETS
3438#undef MAX_AP_CACHE_PER_SCAN
3439#undef MAX_RSSI_SAMPLE_SIZE
3440#undef MAX_SCAN_RPT_THRHOLD
3441#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303442#undef MAX_BSSID_HISTORY_ENTRIES
3443#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444
3445static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
3446{
3447 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
3448 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303450 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303452 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303453
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303454 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303455 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303457 if (!pMsg)
3458 {
3459 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303460 return;
3461 }
3462
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3464 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
3465
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303466 context = &pHddCtx->ext_scan_context;
3467 spin_lock(&hdd_context_lock);
3468 if (context->request_id == pData->requestId) {
3469 context->response_status = pData->status ? -EINVAL : 0;
3470 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303471 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05303472 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473
3474 /*
3475 * Store the Request ID for comparing with the requestID obtained
3476 * in other requests.HDD shall return a failure is the extscan_stop
3477 * request is issued with a different requestId as that of the
3478 * extscan_start request. Also, This requestId shall be used while
3479 * indicating the full scan results to the upper layers.
3480 * The requestId is stored with the assumption that the firmware
3481 * shall return the ext scan start request's requestId in ext scan
3482 * start response.
3483 */
3484 if (pData->status == 0)
3485 pMac->sme.extScanStartReqId = pData->requestId;
3486
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489}
3490
3491
3492static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
3493{
3494 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
3495 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303496 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303498 ENTER();
3499
3500 if (wlan_hdd_validate_context(pHddCtx)){
3501 return;
3502 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303504 if (!pMsg)
3505 {
3506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303507 return;
3508 }
3509
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303510 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3511 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303513 context = &pHddCtx->ext_scan_context;
3514 spin_lock(&hdd_context_lock);
3515 if (context->request_id == pData->requestId) {
3516 context->response_status = pData->status ? -EINVAL : 0;
3517 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05303519 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303521 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303522 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523}
3524
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
3526 void *pMsg)
3527{
3528 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 tpSirEXTScanSetBssidHotListRspParams pData =
3530 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303531 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303533 ENTER();
3534
3535 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 return;
3537 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303538
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303539 if (!pMsg)
3540 {
3541 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3542 return;
3543 }
3544
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303545 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3546 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303547
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303548 context = &pHddCtx->ext_scan_context;
3549 spin_lock(&hdd_context_lock);
3550 if (context->request_id == pData->requestId) {
3551 context->response_status = pData->status ? -EINVAL : 0;
3552 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303553 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303554 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303556 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558}
3559
3560static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
3561 void *pMsg)
3562{
3563 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564 tpSirEXTScanResetBssidHotlistRspParams pData =
3565 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303566 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303568 ENTER();
3569
3570 if (wlan_hdd_validate_context(pHddCtx)) {
3571 return;
3572 }
3573 if (!pMsg)
3574 {
3575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303576 return;
3577 }
3578
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303579 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
3580 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303582 context = &pHddCtx->ext_scan_context;
3583 spin_lock(&hdd_context_lock);
3584 if (context->request_id == pData->requestId) {
3585 context->response_status = pData->status ? -EINVAL : 0;
3586 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05303588 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303590 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303591 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592}
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
3595 void *pMsg)
3596{
3597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3598 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303599 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303600 tANI_S32 totalResults;
3601 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303602 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
3603 struct hdd_ext_scan_context *context;
3604 bool ignore_cached_results = false;
3605 tExtscanCachedScanResult *result;
3606 struct nlattr *nla_results;
3607 tANI_U16 ieLength= 0;
3608 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303610 ENTER();
3611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303612 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303614
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303615 if (!pMsg)
3616 {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3618 return;
3619 }
3620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303621 spin_lock(&hdd_context_lock);
3622 context = &pHddCtx->ext_scan_context;
3623 ignore_cached_results = context->ignore_cached_results;
3624 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303626 if (ignore_cached_results) {
3627 hddLog(LOGE,
3628 FL("Ignore the cached results received after timeout"));
3629 return;
3630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
3633 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303635 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303637 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
3638 scan_id_index++) {
3639 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 totalResults = result->num_results;
3642 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
3643 result->scan_id, result->flags, totalResults);
3644 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303646 do{
3647 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
3648 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
3649 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303651 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
3652 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
3653
3654 if (!skb) {
3655 hddLog(VOS_TRACE_LEVEL_ERROR,
3656 FL("cfg80211_vendor_event_alloc failed"));
3657 return;
3658 }
3659
3660 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
3661
3662 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3663 pData->requestId) ||
3664 nla_put_u32(skb,
3665 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3666 resultsPerEvent)) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3668 goto fail;
3669 }
3670 if (nla_put_u8(skb,
3671 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3672 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 {
3674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3675 goto fail;
3676 }
3677
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303678 if (nla_put_u32(skb,
3679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3680 result->scan_id)) {
3681 hddLog(LOGE, FL("put fail"));
3682 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303684
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303685 nla_results = nla_nest_start(skb,
3686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
3687 if (!nla_results)
3688 goto fail;
3689
3690 if (resultsPerEvent) {
3691 struct nlattr *aps;
3692 struct nlattr *nla_result;
3693
3694 nla_result = nla_nest_start(skb, scan_id_index);
3695 if(!nla_result)
3696 goto fail;
3697
3698 if (nla_put_u32(skb,
3699 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
3700 result->scan_id) ||
3701 nla_put_u32(skb,
3702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
3703 result->flags) ||
3704 nla_put_u32(skb,
3705 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3706 totalResults)) {
3707 hddLog(LOGE, FL("put fail"));
3708 goto fail;
3709 }
3710
3711 aps = nla_nest_start(skb,
3712 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3713 if (!aps)
3714 {
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3716 goto fail;
3717 }
3718
3719 head_ptr = (tpSirWifiScanResult) &(result->ap);
3720
3721 for (j = 0; j < resultsPerEvent; j++, i++) {
3722 struct nlattr *ap;
3723 pSirWifiScanResult = head_ptr + i;
3724
3725 /*
Srinivas Dasari91727c12016-03-23 17:59:06 +05303726 * Firmware returns timestamp from extscan_start till
3727 * BSSID was cached (in micro seconds). Add this with
3728 * time gap between system boot up to extscan_start
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303729 * to derive the time since boot when the
3730 * BSSID was cached.
3731 */
Srinivas Dasari91727c12016-03-23 17:59:06 +05303732 pSirWifiScanResult->ts +=
3733 pHddCtx->extscan_start_time_since_boot;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303734 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
3735 "Ssid (%s)"
3736 "Bssid: %pM "
3737 "Channel (%u)"
3738 "Rssi (%d)"
3739 "RTT (%u)"
3740 "RTT_SD (%u)"
3741 "Beacon Period %u"
3742 "Capability 0x%x "
3743 "Ie length %d",
3744 i,
3745 pSirWifiScanResult->ts,
3746 pSirWifiScanResult->ssid,
3747 pSirWifiScanResult->bssid,
3748 pSirWifiScanResult->channel,
3749 pSirWifiScanResult->rssi,
3750 pSirWifiScanResult->rtt,
3751 pSirWifiScanResult->rtt_sd,
3752 pSirWifiScanResult->beaconPeriod,
3753 pSirWifiScanResult->capability,
3754 ieLength);
3755
3756 ap = nla_nest_start(skb, j + 1);
3757 if (!ap)
3758 {
3759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3760 goto fail;
3761 }
3762
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303763 if (hdd_wlan_nla_put_u64(skb,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303764 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3765 pSirWifiScanResult->ts) )
3766 {
3767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3768 goto fail;
3769 }
3770 if (nla_put(skb,
3771 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3772 sizeof(pSirWifiScanResult->ssid),
3773 pSirWifiScanResult->ssid) )
3774 {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3776 goto fail;
3777 }
3778 if (nla_put(skb,
3779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3780 sizeof(pSirWifiScanResult->bssid),
3781 pSirWifiScanResult->bssid) )
3782 {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3784 goto fail;
3785 }
3786 if (nla_put_u32(skb,
3787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3788 pSirWifiScanResult->channel) )
3789 {
3790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3791 goto fail;
3792 }
3793 if (nla_put_s32(skb,
3794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3795 pSirWifiScanResult->rssi) )
3796 {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3798 goto fail;
3799 }
3800 if (nla_put_u32(skb,
3801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3802 pSirWifiScanResult->rtt) )
3803 {
3804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3805 goto fail;
3806 }
3807 if (nla_put_u32(skb,
3808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3809 pSirWifiScanResult->rtt_sd))
3810 {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3812 goto fail;
3813 }
3814 if (nla_put_u32(skb,
3815 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3816 pSirWifiScanResult->beaconPeriod))
3817 {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3819 goto fail;
3820 }
3821 if (nla_put_u32(skb,
3822 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3823 pSirWifiScanResult->capability))
3824 {
3825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3826 goto fail;
3827 }
3828 if (nla_put_u32(skb,
3829 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3830 ieLength))
3831 {
3832 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3833 goto fail;
3834 }
3835
3836 if (ieLength)
3837 if (nla_put(skb,
3838 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3839 ieLength, ie)) {
3840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3841 goto fail;
3842 }
3843
3844 nla_nest_end(skb, ap);
3845 }
3846 nla_nest_end(skb, aps);
3847 nla_nest_end(skb, nla_result);
3848 }
3849
3850 nla_nest_end(skb, nla_results);
3851
3852 cfg80211_vendor_cmd_reply(skb);
3853
3854 } while (totalResults > 0);
3855 }
3856
3857 if (!pData->moreData) {
3858 spin_lock(&hdd_context_lock);
3859 context->response_status = 0;
3860 complete(&context->response_event);
3861 spin_unlock(&hdd_context_lock);
3862 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303863
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303864 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303865 return;
3866fail:
3867 kfree_skb(skb);
3868 return;
3869}
3870
3871static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3872 void *pMsg)
3873{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303874 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303875 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3876 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303877 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 ENTER();
3880
3881 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303882 hddLog(LOGE,
3883 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303884 return;
3885 }
3886 if (!pMsg)
3887 {
3888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303889 return;
3890 }
3891
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303892 if (pData->bss_found)
3893 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3894 else
3895 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3896
Dino Mycle6fb96c12014-06-10 11:52:40 +05303897 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303898#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3899 NULL,
3900#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303901 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303902 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303903
3904 if (!skb) {
3905 hddLog(VOS_TRACE_LEVEL_ERROR,
3906 FL("cfg80211_vendor_event_alloc failed"));
3907 return;
3908 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303909
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303910 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3911 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3912 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3913 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3914
3915 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303916 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3917 "Ssid (%s) "
3918 "Bssid (" MAC_ADDRESS_STR ") "
3919 "Channel (%u) "
3920 "Rssi (%d) "
3921 "RTT (%u) "
3922 "RTT_SD (%u) ",
3923 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303924 pData->bssHotlist[i].ts,
3925 pData->bssHotlist[i].ssid,
3926 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3927 pData->bssHotlist[i].channel,
3928 pData->bssHotlist[i].rssi,
3929 pData->bssHotlist[i].rtt,
3930 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931 }
3932
3933 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3934 pData->requestId) ||
3935 nla_put_u32(skb,
3936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303937 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3939 goto fail;
3940 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303941 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303942 struct nlattr *aps;
3943
3944 aps = nla_nest_start(skb,
3945 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3946 if (!aps)
3947 goto fail;
3948
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303949 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303950 struct nlattr *ap;
3951
3952 ap = nla_nest_start(skb, i + 1);
3953 if (!ap)
3954 goto fail;
3955
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05303956 if (hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303957 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303958 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303959 nla_put(skb,
3960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303961 sizeof(pData->bssHotlist[i].ssid),
3962 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303963 nla_put(skb,
3964 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303965 sizeof(pData->bssHotlist[i].bssid),
3966 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303967 nla_put_u32(skb,
3968 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303969 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303970 nla_put_s32(skb,
3971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303972 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303973 nla_put_u32(skb,
3974 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303975 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303976 nla_put_u32(skb,
3977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303978 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303979 goto fail;
3980
3981 nla_nest_end(skb, ap);
3982 }
3983 nla_nest_end(skb, aps);
3984
3985 if (nla_put_u8(skb,
3986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3987 pData->moreData))
3988 goto fail;
3989 }
3990
3991 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303992 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303993 return;
3994
3995fail:
3996 kfree_skb(skb);
3997 return;
3998
3999}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304000
4001static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
4002 void *pMsg)
4003{
4004 struct sk_buff *skb;
4005 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4006 tpSirWifiFullScanResultEvent pData =
4007 (tpSirWifiFullScanResultEvent) (pMsg);
4008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304009 ENTER();
4010
4011 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304012 hddLog(LOGE,
4013 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304014 return;
4015 }
4016 if (!pMsg)
4017 {
4018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 return;
4020 }
4021
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304022 /*
4023 * If the full scan result including IE data exceeds NL 4K size
4024 * limitation, drop that beacon/probe rsp frame.
4025 */
4026 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
4027 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
4028 return;
4029 }
4030
Dino Mycle6fb96c12014-06-10 11:52:40 +05304031 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304032#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4033 NULL,
4034#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304035 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4036 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
4037 GFP_KERNEL);
4038
4039 if (!skb) {
4040 hddLog(VOS_TRACE_LEVEL_ERROR,
4041 FL("cfg80211_vendor_event_alloc failed"));
4042 return;
4043 }
4044
Dino Mycle6fb96c12014-06-10 11:52:40 +05304045 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
4046 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
4047 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
4048 "Ssid (%s)"
4049 "Bssid (" MAC_ADDRESS_STR ")"
4050 "Channel (%u)"
4051 "Rssi (%d)"
4052 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304053 "RTT_SD (%u)"
4054 "Bcn Period %d"
4055 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 pData->ap.ts,
4057 pData->ap.ssid,
4058 MAC_ADDR_ARRAY(pData->ap.bssid),
4059 pData->ap.channel,
4060 pData->ap.rssi,
4061 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304062 pData->ap.rtt_sd,
4063 pData->ap.beaconPeriod,
4064 pData->ap.capability);
4065
Dino Mycle6fb96c12014-06-10 11:52:40 +05304066 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
4067 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4068 pData->requestId) ||
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304069 hdd_wlan_nla_put_u64(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
4071 pData->ap.ts) ||
4072 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
4073 sizeof(pData->ap.ssid),
4074 pData->ap.ssid) ||
4075 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
4076 WNI_CFG_BSSID_LEN,
4077 pData->ap.bssid) ||
4078 nla_put_u32(skb,
4079 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
4080 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05304081 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304082 pData->ap.rssi) ||
4083 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
4084 pData->ap.rtt) ||
4085 nla_put_u32(skb,
4086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
4087 pData->ap.rtt_sd) ||
4088 nla_put_u16(skb,
4089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
4090 pData->ap.beaconPeriod) ||
4091 nla_put_u16(skb,
4092 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
4093 pData->ap.capability) ||
4094 nla_put_u32(skb,
4095 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304096 pData->ieLength) ||
4097 nla_put_u8(skb,
4098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
4099 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05304100 {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4102 goto nla_put_failure;
4103 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304104
4105 if (pData->ieLength) {
4106 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
4107 pData->ieLength,
4108 pData->ie))
4109 {
4110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4111 goto nla_put_failure;
4112 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304113 }
4114
4115 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304116 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304117 return;
4118
4119nla_put_failure:
4120 kfree_skb(skb);
4121 return;
4122}
4123
4124static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
4125 void *pMsg)
4126{
4127 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4128 struct sk_buff *skb = NULL;
4129 tpSirEXTScanResultsAvailableIndParams pData =
4130 (tpSirEXTScanResultsAvailableIndParams) pMsg;
4131
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304132 ENTER();
4133
4134 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304135 hddLog(LOGE,
4136 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304137 return;
4138 }
4139 if (!pMsg)
4140 {
4141 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142 return;
4143 }
4144
4145 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304146#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4147 NULL,
4148#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4150 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
4151 GFP_KERNEL);
4152
4153 if (!skb) {
4154 hddLog(VOS_TRACE_LEVEL_ERROR,
4155 FL("cfg80211_vendor_event_alloc failed"));
4156 return;
4157 }
4158
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
4160 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
4161 pData->numResultsAvailable);
4162 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4163 pData->requestId) ||
4164 nla_put_u32(skb,
4165 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
4166 pData->numResultsAvailable)) {
4167 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4168 goto nla_put_failure;
4169 }
4170
4171 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304172 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173 return;
4174
4175nla_put_failure:
4176 kfree_skb(skb);
4177 return;
4178}
4179
4180static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
4181{
4182 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4183 struct sk_buff *skb = NULL;
4184 tpSirEXTScanProgressIndParams pData =
4185 (tpSirEXTScanProgressIndParams) pMsg;
4186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304187 ENTER();
4188
4189 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304190 hddLog(LOGE,
4191 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304192 return;
4193 }
4194 if (!pMsg)
4195 {
4196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304197 return;
4198 }
4199
4200 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304201#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4202 NULL,
4203#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4205 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
4206 GFP_KERNEL);
4207
4208 if (!skb) {
4209 hddLog(VOS_TRACE_LEVEL_ERROR,
4210 FL("cfg80211_vendor_event_alloc failed"));
4211 return;
4212 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304213 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304214 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
4215 pData->extScanEventType);
4216 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
4217 pData->status);
4218
4219 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
4220 pData->extScanEventType) ||
4221 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05304222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
4223 pData->requestId) ||
4224 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
4226 pData->status)) {
4227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4228 goto nla_put_failure;
4229 }
4230
4231 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304232 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 return;
4234
4235nla_put_failure:
4236 kfree_skb(skb);
4237 return;
4238}
4239
4240void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
4241 void *pMsg)
4242{
4243 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
4244
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304245 ENTER();
4246
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304248 return;
4249 }
4250
4251 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
4252
4253
4254 switch(evType) {
4255 case SIR_HAL_EXTSCAN_START_RSP:
4256 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
4257 break;
4258
4259 case SIR_HAL_EXTSCAN_STOP_RSP:
4260 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
4261 break;
4262 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
4263 /* There is no need to send this response to upper layer
4264 Just log the message */
4265 hddLog(VOS_TRACE_LEVEL_INFO,
4266 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
4267 break;
4268 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
4269 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
4270 break;
4271
4272 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
4273 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
4274 break;
4275
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304277 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304278 break;
4279 case SIR_HAL_EXTSCAN_PROGRESS_IND:
4280 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
4281 break;
4282 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
4283 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
4284 break;
4285 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
4286 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
4287 break;
4288 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
4289 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
4290 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
4292 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
4293 break;
4294 default:
4295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
4296 break;
4297 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304298 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304299}
4300
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304301static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4302 struct wireless_dev *wdev,
4303 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304304{
Dino Myclee8843b32014-07-04 14:21:45 +05304305 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304306 struct net_device *dev = wdev->netdev;
4307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4308 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4309 struct nlattr
4310 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4311 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304312 struct hdd_ext_scan_context *context;
4313 unsigned long rc;
4314 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304316 ENTER();
4317
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 status = wlan_hdd_validate_context(pHddCtx);
4319 if (0 != status)
4320 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
Dino Myclee8843b32014-07-04 14:21:45 +05304323 /* check the EXTScan Capability */
4324 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304325 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4326 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304327 {
4328 hddLog(VOS_TRACE_LEVEL_ERROR,
4329 FL("EXTScan not enabled/supported by Firmware"));
4330 return -EINVAL;
4331 }
4332
Dino Mycle6fb96c12014-06-10 11:52:40 +05304333 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4334 data, dataLen,
4335 wlan_hdd_extscan_config_policy)) {
4336 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4337 return -EINVAL;
4338 }
4339
4340 /* Parse and fetch request Id */
4341 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4342 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4343 return -EINVAL;
4344 }
4345
Dino Myclee8843b32014-07-04 14:21:45 +05304346 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304347 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304349
Dino Myclee8843b32014-07-04 14:21:45 +05304350 reqMsg.sessionId = pAdapter->sessionId;
4351 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304353 vos_spin_lock_acquire(&hdd_context_lock);
4354 context = &pHddCtx->ext_scan_context;
4355 context->request_id = reqMsg.requestId;
4356 INIT_COMPLETION(context->response_event);
4357 vos_spin_lock_release(&hdd_context_lock);
4358
Dino Myclee8843b32014-07-04 14:21:45 +05304359 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304360 if (!HAL_STATUS_SUCCESS(status)) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR,
4362 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304363 return -EINVAL;
4364 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05304365
4366 rc = wait_for_completion_timeout(&context->response_event,
4367 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4368 if (!rc) {
4369 hddLog(LOGE, FL("Target response timed out"));
4370 return -ETIMEDOUT;
4371 }
4372
4373 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
4374 if (ret)
4375 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
4376
4377 return ret;
4378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304379 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304380 return 0;
4381}
4382
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304383static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
4384 struct wireless_dev *wdev,
4385 const void *data, int dataLen)
4386{
4387 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304388
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304389 vos_ssr_protect(__func__);
4390 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
4391 vos_ssr_unprotect(__func__);
4392
4393 return ret;
4394}
4395
4396static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
4398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr
4405 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4406 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304407 struct hdd_ext_scan_context *context;
4408 unsigned long rc;
4409 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304411 ENTER();
4412
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304413 if (VOS_FTM_MODE == hdd_get_conparam()) {
4414 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4415 return -EINVAL;
4416 }
4417
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 status = wlan_hdd_validate_context(pHddCtx);
4419 if (0 != status)
4420 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304421 return -EINVAL;
4422 }
Dino Myclee8843b32014-07-04 14:21:45 +05304423 /* check the EXTScan Capability */
4424 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304425 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4426 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304427 {
4428 hddLog(VOS_TRACE_LEVEL_ERROR,
4429 FL("EXTScan not enabled/supported by Firmware"));
4430 return -EINVAL;
4431 }
4432
Dino Mycle6fb96c12014-06-10 11:52:40 +05304433 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4434 data, dataLen,
4435 wlan_hdd_extscan_config_policy)) {
4436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4437 return -EINVAL;
4438 }
4439 /* Parse and fetch request Id */
4440 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4442 return -EINVAL;
4443 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304444
Dino Myclee8843b32014-07-04 14:21:45 +05304445 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304446 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4447
Dino Myclee8843b32014-07-04 14:21:45 +05304448 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304449
Dino Myclee8843b32014-07-04 14:21:45 +05304450 reqMsg.sessionId = pAdapter->sessionId;
4451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452
4453 /* Parse and fetch flush parameter */
4454 if (!tb
4455 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
4456 {
4457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
4458 goto failed;
4459 }
Dino Myclee8843b32014-07-04 14:21:45 +05304460 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
4462
Dino Myclee8843b32014-07-04 14:21:45 +05304463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304464
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304465 spin_lock(&hdd_context_lock);
4466 context = &pHddCtx->ext_scan_context;
4467 context->request_id = reqMsg.requestId;
4468 context->ignore_cached_results = false;
4469 INIT_COMPLETION(context->response_event);
4470 spin_unlock(&hdd_context_lock);
4471
Dino Myclee8843b32014-07-04 14:21:45 +05304472 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304473 if (!HAL_STATUS_SUCCESS(status)) {
4474 hddLog(VOS_TRACE_LEVEL_ERROR,
4475 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304476 return -EINVAL;
4477 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304478
4479 rc = wait_for_completion_timeout(&context->response_event,
4480 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4481 if (!rc) {
4482 hddLog(LOGE, FL("Target response timed out"));
4483 retval = -ETIMEDOUT;
4484 spin_lock(&hdd_context_lock);
4485 context->ignore_cached_results = true;
4486 spin_unlock(&hdd_context_lock);
4487 } else {
4488 spin_lock(&hdd_context_lock);
4489 retval = context->response_status;
4490 spin_unlock(&hdd_context_lock);
4491 }
4492
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304493 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05304494 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304495
4496failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05304497 return -EINVAL;
4498}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304499static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
4500 struct wireless_dev *wdev,
4501 const void *data, int dataLen)
4502{
4503 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304504
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304505 vos_ssr_protect(__func__);
4506 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
4507 vos_ssr_unprotect(__func__);
4508
4509 return ret;
4510}
4511
4512static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304513 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05304514 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304515{
4516 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
4517 struct net_device *dev = wdev->netdev;
4518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4520 struct nlattr
4521 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4522 struct nlattr
4523 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4524 struct nlattr *apTh;
4525 eHalStatus status;
4526 tANI_U8 i = 0;
4527 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304528 struct hdd_ext_scan_context *context;
4529 tANI_U32 request_id;
4530 unsigned long rc;
4531 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304535 if (VOS_FTM_MODE == hdd_get_conparam()) {
4536 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4537 return -EINVAL;
4538 }
4539
Dino Mycle6fb96c12014-06-10 11:52:40 +05304540 status = wlan_hdd_validate_context(pHddCtx);
4541 if (0 != status)
4542 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304543 return -EINVAL;
4544 }
Dino Myclee8843b32014-07-04 14:21:45 +05304545 /* check the EXTScan Capability */
4546 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304547 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4548 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304549 {
4550 hddLog(VOS_TRACE_LEVEL_ERROR,
4551 FL("EXTScan not enabled/supported by Firmware"));
4552 return -EINVAL;
4553 }
4554
Dino Mycle6fb96c12014-06-10 11:52:40 +05304555 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4556 data, dataLen,
4557 wlan_hdd_extscan_config_policy)) {
4558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4559 return -EINVAL;
4560 }
4561
4562 /* Parse and fetch request Id */
4563 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4564 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4565 return -EINVAL;
4566 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
4568 vos_mem_malloc(sizeof(*pReqMsg));
4569 if (!pReqMsg) {
4570 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4571 return -ENOMEM;
4572 }
4573
Dino Myclee8843b32014-07-04 14:21:45 +05304574
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 pReqMsg->requestId = nla_get_u32(
4576 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4577 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4578
4579 /* Parse and fetch number of APs */
4580 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
4581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
4582 goto fail;
4583 }
4584
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304585 /* Parse and fetch lost ap sample size */
4586 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
4587 hddLog(LOGE, FL("attr lost ap sample size failed"));
4588 goto fail;
4589 }
4590
4591 pReqMsg->lostBssidSampleSize = nla_get_u32(
4592 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
4593 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595 pReqMsg->sessionId = pAdapter->sessionId;
4596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4597
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304598 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304600 if (pReqMsg->numBssid > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
4601 hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
4602 pReqMsg->numBssid, WLAN_EXTSCAN_MAX_HOTLIST_APS);
4603 goto fail;
4604 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304605 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606
4607 nla_for_each_nested(apTh,
4608 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304609 if (i == pReqMsg->numBssid) {
4610 hddLog(LOGW, FL("Ignoring excess AP"));
4611 break;
4612 }
4613
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4615 nla_data(apTh), nla_len(apTh),
4616 NULL)) {
4617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4618 goto fail;
4619 }
4620
4621 /* Parse and fetch MAC address */
4622 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
4623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
4624 goto fail;
4625 }
4626 memcpy(pReqMsg->ap[i].bssid, nla_data(
4627 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
4628 sizeof(tSirMacAddr));
4629 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
4630
4631 /* Parse and fetch low RSSI */
4632 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
4633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
4634 goto fail;
4635 }
4636 pReqMsg->ap[i].low = nla_get_s32(
4637 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
4638 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
4639
4640 /* Parse and fetch high RSSI */
4641 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
4642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
4643 goto fail;
4644 }
4645 pReqMsg->ap[i].high = nla_get_s32(
4646 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4647 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
4648 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304649 i++;
4650 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304651
Hanumanth Reddy Pothula8e188402017-01-27 16:43:45 +05304652 if (i < pReqMsg->numBssid) {
4653 hddLog(LOGW, FL("Number of AP %u less than expected %u"),
4654 i, pReqMsg->numBssid);
4655 pReqMsg->numBssid = i;
4656 }
4657
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304658 context = &pHddCtx->ext_scan_context;
4659 spin_lock(&hdd_context_lock);
4660 INIT_COMPLETION(context->response_event);
4661 context->request_id = request_id = pReqMsg->requestId;
4662 spin_unlock(&hdd_context_lock);
4663
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
4665 if (!HAL_STATUS_SUCCESS(status)) {
4666 hddLog(VOS_TRACE_LEVEL_ERROR,
4667 FL("sme_SetBssHotlist failed(err=%d)"), status);
4668 vos_mem_free(pReqMsg);
4669 return -EINVAL;
4670 }
4671
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304672 /* request was sent -- wait for the response */
4673 rc = wait_for_completion_timeout(&context->response_event,
4674 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4675
4676 if (!rc) {
4677 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
4678 retval = -ETIMEDOUT;
4679 } else {
4680 spin_lock(&hdd_context_lock);
4681 if (context->request_id == request_id)
4682 retval = context->response_status;
4683 else
4684 retval = -EINVAL;
4685 spin_unlock(&hdd_context_lock);
4686 }
4687
Dino Myclee8843b32014-07-04 14:21:45 +05304688 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304689 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05304690 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304691
4692fail:
4693 vos_mem_free(pReqMsg);
4694 return -EINVAL;
4695}
4696
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304697static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4698 struct wireless_dev *wdev,
4699 const void *data, int dataLen)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4705 dataLen);
4706 vos_ssr_unprotect(__func__);
4707
4708 return ret;
4709}
4710
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304711static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304712 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304713 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714{
Agrawal Ashish16abf782016-08-18 22:42:59 +05304715 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4716 struct net_device *dev = wdev->netdev;
4717 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4718 uint32_t chan_list[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4719 uint8_t num_channels = 0;
4720 uint8_t num_chan_new = 0;
4721 uint8_t buf[256] = {0};
Dino Mycle6fb96c12014-06-10 11:52:40 +05304722 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304723 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 tWifiBand wifiBand;
4725 eHalStatus status;
4726 struct sk_buff *replySkb;
Agrawal Ashish16abf782016-08-18 22:42:59 +05304727 tANI_U8 i,j,k;
4728 int ret,len = 0;;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304729
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304730 ENTER();
4731
Dino Mycle6fb96c12014-06-10 11:52:40 +05304732 status = wlan_hdd_validate_context(pHddCtx);
4733 if (0 != status)
4734 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 return -EINVAL;
4736 }
Dino Myclee8843b32014-07-04 14:21:45 +05304737
Dino Mycle6fb96c12014-06-10 11:52:40 +05304738 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4739 data, dataLen,
4740 wlan_hdd_extscan_config_policy)) {
4741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4742 return -EINVAL;
4743 }
4744
4745 /* Parse and fetch request Id */
4746 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4748 return -EINVAL;
4749 }
4750 requestId = nla_get_u32(
4751 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4752 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4753
4754 /* Parse and fetch wifi band */
4755 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4756 {
4757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4758 return -EINVAL;
4759 }
4760 wifiBand = nla_get_u32(
4761 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4762 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4763
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304764 /* Parse and fetch max channels */
4765 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4766 {
4767 hddLog(LOGE, FL("attr max channels failed"));
4768 return -EINVAL;
4769 }
4770 maxChannels = nla_get_u32(
4771 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4773
Dino Mycle6fb96c12014-06-10 11:52:40 +05304774 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
Agrawal Ashish16abf782016-08-18 22:42:59 +05304775 wifiBand, chan_list,
4776 &num_channels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304777 if (eHAL_STATUS_SUCCESS != status) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR,
4779 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4780 return -EINVAL;
4781 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304782
Agrawal Ashish16abf782016-08-18 22:42:59 +05304783 num_channels = VOS_MIN(num_channels, maxChannels);
4784 num_chan_new = num_channels;
4785 /* remove the indoor only channels if iface is SAP */
4786 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
4787 {
4788 num_chan_new = 0;
4789 for (i = 0; i < num_channels; i++)
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05304790 for (j = 0; j < HDD_NUM_NL80211_BANDS; j++) {
Agrawal Ashish16abf782016-08-18 22:42:59 +05304791 if (wiphy->bands[j] == NULL)
4792 continue;
4793 for (k = 0; k < wiphy->bands[j]->n_channels; k++) {
4794 if ((chan_list[i] ==
4795 wiphy->bands[j]->channels[k].center_freq) &&
4796 (!(wiphy->bands[j]->channels[k].flags &
4797 IEEE80211_CHAN_INDOOR_ONLY))) {
4798 chan_list[num_chan_new] = chan_list[i];
4799 num_chan_new++;
4800 }
4801 }
4802 }
4803 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304804
Agrawal Ashish16abf782016-08-18 22:42:59 +05304805 hddLog(LOG1, FL("Number of channels: %d"), num_chan_new);
4806 for (i = 0; i < num_chan_new; i++)
4807 len += scnprintf(buf + len, sizeof(buf) - len, "%u ", chan_list[i]);
4808 hddLog(LOG1, "Channels: %s", buf);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809
4810 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
Agrawal Ashish16abf782016-08-18 22:42:59 +05304811 sizeof(u32) * num_chan_new +
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 NLMSG_HDRLEN);
4813
4814 if (!replySkb) {
4815 hddLog(VOS_TRACE_LEVEL_ERROR,
4816 FL("valid channels: buffer alloc fail"));
4817 return -EINVAL;
4818 }
4819 if (nla_put_u32(replySkb,
4820 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304821 num_chan_new) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05304822 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
Agrawal Ashish16abf782016-08-18 22:42:59 +05304823 sizeof(u32) * num_chan_new, chan_list)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824
4825 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4826 kfree_skb(replySkb);
4827 return -EINVAL;
4828 }
4829
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304830 ret = cfg80211_vendor_cmd_reply(replySkb);
4831
4832 EXIT();
4833 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834}
4835
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304836static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4837 struct wireless_dev *wdev,
4838 const void *data, int dataLen)
4839{
4840 int ret = 0;
4841
4842 vos_ssr_protect(__func__);
4843 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4844 dataLen);
4845 vos_ssr_unprotect(__func__);
4846
4847 return ret;
4848}
4849
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304850static int hdd_extscan_start_fill_bucket_channel_spec(
4851 hdd_context_t *pHddCtx,
4852 tpSirEXTScanStartReqParams pReqMsg,
4853 struct nlattr **tb)
4854{
4855 struct nlattr *bucket[
4856 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4857 struct nlattr *channel[
4858 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4859 struct nlattr *buckets;
4860 struct nlattr *channels;
4861 int rem1, rem2;
4862 eHalStatus status;
4863 tANI_U8 bktIndex, j, numChannels;
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304864 uint32_t expected_buckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304865 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4866 tANI_U32 passive_max_chn_time, active_max_chn_time;
4867
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304868 expected_buckets = pReqMsg->numBuckets;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304869 bktIndex = 0;
4870
4871 nla_for_each_nested(buckets,
4872 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
Ashish Kumar Dhanotiyacb407902017-08-14 19:57:32 +05304873 if (bktIndex >= expected_buckets) {
4874 hddLog(LOGW, FL("ignoring excess buckets"));
4875 break;
4876 }
4877
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304878 if (nla_parse(bucket,
Ashish Kumar Dhanotiya9c93f562017-06-20 12:13:33 +05304879 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4880 nla_data(buckets), nla_len(buckets),
4881 wlan_hdd_extscan_config_policy)) {
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304882 hddLog(LOGE, FL("nla_parse failed"));
4883 return -EINVAL;
4884 }
4885
4886 /* Parse and fetch bucket spec */
4887 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4888 hddLog(LOGE, FL("attr bucket index failed"));
4889 return -EINVAL;
4890 }
4891 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4892 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4893 hddLog(LOG1, FL("Bucket spec Index %d"),
4894 pReqMsg->buckets[bktIndex].bucket);
4895
4896 /* Parse and fetch wifi band */
4897 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4898 hddLog(LOGE, FL("attr wifi band failed"));
4899 return -EINVAL;
4900 }
4901 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4902 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4903 hddLog(LOG1, FL("Wifi band %d"),
4904 pReqMsg->buckets[bktIndex].band);
4905
4906 /* Parse and fetch period */
4907 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4908 hddLog(LOGE, FL("attr period failed"));
4909 return -EINVAL;
4910 }
4911 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4912 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4913 hddLog(LOG1, FL("period %d"),
4914 pReqMsg->buckets[bktIndex].period);
4915
4916 /* Parse and fetch report events */
4917 if (!bucket[
4918 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4919 hddLog(LOGE, FL("attr report events failed"));
4920 return -EINVAL;
4921 }
4922 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4923 bucket[
4924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4925 hddLog(LOG1, FL("report events %d"),
4926 pReqMsg->buckets[bktIndex].reportEvents);
4927
4928 /* Parse and fetch max period */
4929 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4930 hddLog(LOGE, FL("attr max period failed"));
4931 return -EINVAL;
4932 }
4933 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4934 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4935 hddLog(LOG1, FL("max period %u"),
4936 pReqMsg->buckets[bktIndex].max_period);
4937
4938 /* Parse and fetch exponent */
4939 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4940 hddLog(LOGE, FL("attr exponent failed"));
4941 return -EINVAL;
4942 }
4943 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4944 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4945 hddLog(LOG1, FL("exponent %u"),
4946 pReqMsg->buckets[bktIndex].exponent);
4947
4948 /* Parse and fetch step count */
4949 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4950 hddLog(LOGE, FL("attr step count failed"));
4951 return -EINVAL;
4952 }
4953 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4954 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4955 hddLog(LOG1, FL("Step count %u"),
4956 pReqMsg->buckets[bktIndex].step_count);
4957
4958 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4959 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4960
4961 /* Framework shall pass the channel list if the input WiFi band is
4962 * WIFI_BAND_UNSPECIFIED.
4963 * If the input WiFi band is specified (any value other than
4964 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4965 */
4966 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4967 numChannels = 0;
4968 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4969 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4970 pReqMsg->buckets[bktIndex].band,
4971 chanList, &numChannels);
4972 if (!HAL_STATUS_SUCCESS(status)) {
4973 hddLog(LOGE,
4974 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4975 status);
4976 return -EINVAL;
4977 }
4978
4979 pReqMsg->buckets[bktIndex].numChannels =
4980 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4981 hddLog(LOG1, FL("Num channels %d"),
4982 pReqMsg->buckets[bktIndex].numChannels);
4983
4984 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4985 j++) {
4986 pReqMsg->buckets[bktIndex].channels[j].channel =
4987 chanList[j];
4988 pReqMsg->buckets[bktIndex].channels[j].
4989 chnlClass = 0;
4990 if (CSR_IS_CHANNEL_DFS(
4991 vos_freq_to_chan(chanList[j]))) {
4992 pReqMsg->buckets[bktIndex].channels[j].
4993 passive = 1;
4994 pReqMsg->buckets[bktIndex].channels[j].
4995 dwellTimeMs = passive_max_chn_time;
4996 } else {
4997 pReqMsg->buckets[bktIndex].channels[j].
4998 passive = 0;
4999 pReqMsg->buckets[bktIndex].channels[j].
5000 dwellTimeMs = active_max_chn_time;
5001 }
5002
5003 hddLog(LOG1,
5004 "Channel %u Passive %u Dwell time %u ms",
5005 pReqMsg->buckets[bktIndex].channels[j].channel,
5006 pReqMsg->buckets[bktIndex].channels[j].passive,
5007 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5008 }
5009
5010 bktIndex++;
5011 continue;
5012 }
5013
5014 /* Parse and fetch number of channels */
5015 if (!bucket[
5016 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
5017 hddLog(LOGE, FL("attr num channels failed"));
5018 return -EINVAL;
5019 }
5020
5021 pReqMsg->buckets[bktIndex].numChannels =
5022 nla_get_u32(bucket[
5023 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
5024 hddLog(LOG1, FL("num channels %d"),
5025 pReqMsg->buckets[bktIndex].numChannels);
5026
5027 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
5028 hddLog(LOGE, FL("attr channel spec failed"));
5029 return -EINVAL;
5030 }
5031
5032 j = 0;
5033 nla_for_each_nested(channels,
5034 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
5035 if (nla_parse(channel,
5036 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5037 nla_data(channels), nla_len(channels),
5038 wlan_hdd_extscan_config_policy)) {
5039 hddLog(LOGE, FL("nla_parse failed"));
5040 return -EINVAL;
5041 }
5042
5043 /* Parse and fetch channel */
5044 if (!channel[
5045 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
5046 hddLog(LOGE, FL("attr channel failed"));
5047 return -EINVAL;
5048 }
5049 pReqMsg->buckets[bktIndex].channels[j].channel =
5050 nla_get_u32(channel[
5051 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
5052 hddLog(LOG1, FL("channel %u"),
5053 pReqMsg->buckets[bktIndex].channels[j].channel);
5054
5055 /* Parse and fetch dwell time */
5056 if (!channel[
5057 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
5058 hddLog(LOGE, FL("attr dwelltime failed"));
5059 return -EINVAL;
5060 }
5061 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
5062 nla_get_u32(channel[
5063 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
5064
5065 hddLog(LOG1, FL("Dwell time (%u ms)"),
5066 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
5067
5068
5069 /* Parse and fetch channel spec passive */
5070 if (!channel[
5071 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
5072 hddLog(LOGE,
5073 FL("attr channel spec passive failed"));
5074 return -EINVAL;
5075 }
5076 pReqMsg->buckets[bktIndex].channels[j].passive =
5077 nla_get_u8(channel[
5078 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
5079 hddLog(LOG1, FL("Chnl spec passive %u"),
5080 pReqMsg->buckets[bktIndex].channels[j].passive);
5081
5082 j++;
5083 }
5084
5085 bktIndex++;
5086 }
5087
5088 return 0;
5089}
5090
5091
5092/*
5093 * define short names for the global vendor params
5094 * used by wlan_hdd_cfg80211_extscan_start()
5095 */
5096#define PARAM_MAX \
5097QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
5098#define PARAM_REQUEST_ID \
5099QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
5100#define PARAM_BASE_PERIOD \
5101QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
5102#define PARAM_MAX_AP_PER_SCAN \
5103QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
5104#define PARAM_RPT_THRHLD_PERCENT \
5105QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
5106#define PARAM_RPT_THRHLD_NUM_SCANS \
5107QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
5108#define PARAM_NUM_BUCKETS \
5109QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
5110
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305111static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305112 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305113 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305114{
Dino Myclee8843b32014-07-04 14:21:45 +05305115 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305116 struct net_device *dev = wdev->netdev;
5117 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5118 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5119 struct nlattr *tb[PARAM_MAX + 1];
5120 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305121 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305122 tANI_U32 request_id;
5123 struct hdd_ext_scan_context *context;
5124 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305125
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305126 ENTER();
5127
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305128 if (VOS_FTM_MODE == hdd_get_conparam()) {
5129 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5130 return -EINVAL;
5131 }
5132
Dino Mycle6fb96c12014-06-10 11:52:40 +05305133 status = wlan_hdd_validate_context(pHddCtx);
5134 if (0 != status)
5135 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305136 return -EINVAL;
5137 }
Dino Myclee8843b32014-07-04 14:21:45 +05305138 /* check the EXTScan Capability */
5139 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305140 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5141 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305142 {
5143 hddLog(VOS_TRACE_LEVEL_ERROR,
5144 FL("EXTScan not enabled/supported by Firmware"));
5145 return -EINVAL;
5146 }
5147
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305148 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305149 data, dataLen,
5150 wlan_hdd_extscan_config_policy)) {
5151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5152 return -EINVAL;
5153 }
5154
5155 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305156 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5158 return -EINVAL;
5159 }
5160
Dino Myclee8843b32014-07-04 14:21:45 +05305161 pReqMsg = (tpSirEXTScanStartReqParams)
5162 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305163 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05305164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
5165 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305166 }
5167
5168 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305169 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305170 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
5171
5172 pReqMsg->sessionId = pAdapter->sessionId;
5173 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
5174
5175 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305176 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305177 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
5178 goto fail;
5179 }
5180 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305181 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305182 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
5183 pReqMsg->basePeriod);
5184
5185 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305186 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305187 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
5188 goto fail;
5189 }
5190 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305191 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305192 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
5193 pReqMsg->maxAPperScan);
5194
5195 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305196 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305197 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
5198 goto fail;
5199 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305200 pReqMsg->reportThresholdPercent = nla_get_u8(
5201 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305202 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305203 pReqMsg->reportThresholdPercent);
5204
5205 /* Parse and fetch report threshold num scans */
5206 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
5207 hddLog(LOGE, FL("attr report_threshold num scans failed"));
5208 goto fail;
5209 }
5210 pReqMsg->reportThresholdNumScans = nla_get_u8(
5211 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
5212 hddLog(LOG1, FL("Report Threshold num scans %d"),
5213 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305214
5215 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305216 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
5218 goto fail;
5219 }
5220 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305221 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305222 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
5223 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
5224 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
5225 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
5226 }
5227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
5228 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305229
Dino Mycle6fb96c12014-06-10 11:52:40 +05305230 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
5231 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
5232 goto fail;
5233 }
5234
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305235 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305236
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305237 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
5238 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305239
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305240 context = &pHddCtx->ext_scan_context;
5241 spin_lock(&hdd_context_lock);
5242 INIT_COMPLETION(context->response_event);
5243 context->request_id = request_id = pReqMsg->requestId;
5244 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05305245
Dino Mycle6fb96c12014-06-10 11:52:40 +05305246 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
5247 if (!HAL_STATUS_SUCCESS(status)) {
5248 hddLog(VOS_TRACE_LEVEL_ERROR,
5249 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305250 goto fail;
5251 }
5252
Srinivas Dasari91727c12016-03-23 17:59:06 +05305253 pHddCtx->extscan_start_time_since_boot = vos_get_monotonic_boottime();
5254
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305255 /* request was sent -- wait for the response */
5256 rc = wait_for_completion_timeout(&context->response_event,
5257 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5258
5259 if (!rc) {
5260 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
5261 retval = -ETIMEDOUT;
5262 } else {
5263 spin_lock(&hdd_context_lock);
5264 if (context->request_id == request_id)
5265 retval = context->response_status;
5266 else
5267 retval = -EINVAL;
5268 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305269 }
5270
Dino Myclee8843b32014-07-04 14:21:45 +05305271 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305272 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305273 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305274
5275fail:
5276 vos_mem_free(pReqMsg);
5277 return -EINVAL;
5278}
5279
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05305280/*
5281 * done with short names for the global vendor params
5282 * used by wlan_hdd_cfg80211_extscan_start()
5283 */
5284#undef PARAM_MAX
5285#undef PARAM_REQUEST_ID
5286#undef PARAM_BASE_PERIOD
5287#undef PARAMS_MAX_AP_PER_SCAN
5288#undef PARAMS_RPT_THRHLD_PERCENT
5289#undef PARAMS_RPT_THRHLD_NUM_SCANS
5290#undef PARAMS_NUM_BUCKETS
5291
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305292static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
5293 struct wireless_dev *wdev,
5294 const void *data, int dataLen)
5295{
5296 int ret = 0;
5297
5298 vos_ssr_protect(__func__);
5299 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
5300 vos_ssr_unprotect(__func__);
5301
5302 return ret;
5303}
5304
5305static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305306 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305307 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305308{
Dino Myclee8843b32014-07-04 14:21:45 +05305309 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305310 struct net_device *dev = wdev->netdev;
5311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5314 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305315 int retval;
5316 unsigned long rc;
5317 struct hdd_ext_scan_context *context;
5318 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305319
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305320 ENTER();
5321
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305322 if (VOS_FTM_MODE == hdd_get_conparam()) {
5323 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5324 return -EINVAL;
5325 }
5326
Dino Mycle6fb96c12014-06-10 11:52:40 +05305327 status = wlan_hdd_validate_context(pHddCtx);
5328 if (0 != status)
5329 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05305330 return -EINVAL;
5331 }
Dino Myclee8843b32014-07-04 14:21:45 +05305332 /* check the EXTScan Capability */
5333 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305334 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5335 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305336 {
5337 hddLog(VOS_TRACE_LEVEL_ERROR,
5338 FL("EXTScan not enabled/supported by Firmware"));
5339 return -EINVAL;
5340 }
5341
Dino Mycle6fb96c12014-06-10 11:52:40 +05305342 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5343 data, dataLen,
5344 wlan_hdd_extscan_config_policy)) {
5345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5346 return -EINVAL;
5347 }
5348
5349 /* Parse and fetch request Id */
5350 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5352 return -EINVAL;
5353 }
5354
Dino Myclee8843b32014-07-04 14:21:45 +05305355 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305357 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305358
Dino Myclee8843b32014-07-04 14:21:45 +05305359 reqMsg.sessionId = pAdapter->sessionId;
5360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305361
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305362 context = &pHddCtx->ext_scan_context;
5363 spin_lock(&hdd_context_lock);
5364 INIT_COMPLETION(context->response_event);
Sravanti Palakonda7539fb92016-02-26 17:49:21 +05305365 context->request_id = request_id = reqMsg.requestId;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305366 spin_unlock(&hdd_context_lock);
5367
Dino Myclee8843b32014-07-04 14:21:45 +05305368 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305369 if (!HAL_STATUS_SUCCESS(status)) {
5370 hddLog(VOS_TRACE_LEVEL_ERROR,
5371 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305372 return -EINVAL;
5373 }
5374
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05305375 /* request was sent -- wait for the response */
5376 rc = wait_for_completion_timeout(&context->response_event,
5377 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5378
5379 if (!rc) {
5380 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5381 retval = -ETIMEDOUT;
5382 } else {
5383 spin_lock(&hdd_context_lock);
5384 if (context->request_id == request_id)
5385 retval = context->response_status;
5386 else
5387 retval = -EINVAL;
5388 spin_unlock(&hdd_context_lock);
5389 }
5390
5391 return retval;
5392
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305393 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305394 return 0;
5395}
5396
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305397static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5398 struct wireless_dev *wdev,
5399 const void *data, int dataLen)
5400{
5401 int ret = 0;
5402
5403 vos_ssr_protect(__func__);
5404 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5405 vos_ssr_unprotect(__func__);
5406
5407 return ret;
5408}
5409
5410static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305411 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305412 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305413{
Dino Myclee8843b32014-07-04 14:21:45 +05305414 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305415 struct net_device *dev = wdev->netdev;
5416 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5417 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5418 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5419 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305420 struct hdd_ext_scan_context *context;
5421 tANI_U32 request_id;
5422 unsigned long rc;
5423 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305425 ENTER();
5426
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305427 if (VOS_FTM_MODE == hdd_get_conparam()) {
5428 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5429 return -EINVAL;
5430 }
5431
Dino Mycle6fb96c12014-06-10 11:52:40 +05305432 status = wlan_hdd_validate_context(pHddCtx);
5433 if (0 != status)
5434 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305435 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305436 return -EINVAL;
5437 }
Dino Myclee8843b32014-07-04 14:21:45 +05305438 /* check the EXTScan Capability */
5439 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305440 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
5441 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05305442 {
5443 hddLog(VOS_TRACE_LEVEL_ERROR,
5444 FL("EXTScan not enabled/supported by Firmware"));
5445 return -EINVAL;
5446 }
5447
Dino Mycle6fb96c12014-06-10 11:52:40 +05305448 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5449 data, dataLen,
5450 wlan_hdd_extscan_config_policy)) {
5451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5452 return -EINVAL;
5453 }
5454
5455 /* Parse and fetch request Id */
5456 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5458 return -EINVAL;
5459 }
5460
Dino Myclee8843b32014-07-04 14:21:45 +05305461 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305462 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305463 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305464
Dino Myclee8843b32014-07-04 14:21:45 +05305465 reqMsg.sessionId = pAdapter->sessionId;
5466 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305467
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305468 context = &pHddCtx->ext_scan_context;
5469 spin_lock(&hdd_context_lock);
5470 INIT_COMPLETION(context->response_event);
5471 context->request_id = request_id = reqMsg.requestId;
5472 spin_unlock(&hdd_context_lock);
5473
Dino Myclee8843b32014-07-04 14:21:45 +05305474 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305475 if (!HAL_STATUS_SUCCESS(status)) {
5476 hddLog(VOS_TRACE_LEVEL_ERROR,
5477 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305478 return -EINVAL;
5479 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305480
5481 /* request was sent -- wait for the response */
5482 rc = wait_for_completion_timeout(&context->response_event,
5483 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5484 if (!rc) {
5485 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5486 retval = -ETIMEDOUT;
5487 } else {
5488 spin_lock(&hdd_context_lock);
5489 if (context->request_id == request_id)
5490 retval = context->response_status;
5491 else
5492 retval = -EINVAL;
5493 spin_unlock(&hdd_context_lock);
5494 }
5495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305496 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305497 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305498}
5499
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305500static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5501 struct wireless_dev *wdev,
5502 const void *data, int dataLen)
5503{
5504 int ret = 0;
5505
5506 vos_ssr_protect(__func__);
5507 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5508 vos_ssr_unprotect(__func__);
5509
5510 return ret;
5511}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305512#endif /* WLAN_FEATURE_EXTSCAN */
5513
Atul Mittal115287b2014-07-08 13:26:33 +05305514/*EXT TDLS*/
5515static const struct nla_policy
5516wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5517{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305518 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {
5519 .type = NLA_UNSPEC,
5520 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305521 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5522 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5523 {.type = NLA_S32 },
5524 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5525 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5526
5527};
5528
5529static const struct nla_policy
5530wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5531{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305532 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {
5533 .type = NLA_UNSPEC,
5534 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305535
5536};
5537
5538static const struct nla_policy
5539wlan_hdd_tdls_config_state_change_policy[
5540 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5541{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305542 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {
5543 .type = NLA_UNSPEC,
5544 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305545 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5546 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305547 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5548 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5549 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305550
5551};
5552
5553static const struct nla_policy
5554wlan_hdd_tdls_config_get_status_policy[
5555 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5556{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305557 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {
5558 .type = NLA_UNSPEC,
5559 .len = HDD_MAC_ADDR_LEN},
Atul Mittal115287b2014-07-08 13:26:33 +05305560 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5561 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305562 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5563 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5564 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305565
5566};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305567
5568static const struct nla_policy
5569wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5570{
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05305571 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {
5572 .type = NLA_UNSPEC,
5573 .len = VOS_MAC_ADDR_FIRST_3_BYTES},
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305574};
5575
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305576static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305577 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305578 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305579 int data_len)
5580{
5581
5582 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5583 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305585 ENTER();
5586
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305587 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305588 return -EINVAL;
5589 }
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +05305590 if (0 == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305591 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305592 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305593 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305594 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305595 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 return -ENOTSUPP;
5597 }
5598
5599 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5600 data, data_len, wlan_hdd_mac_config)) {
5601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5602 return -EINVAL;
5603 }
5604
5605 /* Parse and fetch mac address */
5606 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5608 return -EINVAL;
5609 }
5610
5611 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5612 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5613 VOS_MAC_ADDR_LAST_3_BYTES);
5614
Siddharth Bhal76972212014-10-15 16:22:51 +05305615 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5616
5617 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305618 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5619 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305620 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5621 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5622 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5623 {
5624 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5625 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5626 VOS_MAC_ADDRESS_LEN);
5627 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305628 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305629
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +05305630 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
5631 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305632
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305633 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305634 return 0;
5635}
5636
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305637static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5638 struct wireless_dev *wdev,
5639 const void *data,
5640 int data_len)
5641{
5642 int ret = 0;
5643
5644 vos_ssr_protect(__func__);
5645 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5646 vos_ssr_unprotect(__func__);
5647
5648 return ret;
5649}
5650
5651static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305652 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305653 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305654 int data_len)
5655{
5656 u8 peer[6] = {0};
5657 struct net_device *dev = wdev->netdev;
5658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5660 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5661 eHalStatus ret;
5662 tANI_S32 state;
5663 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305664 tANI_S32 global_operating_class = 0;
5665 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305666 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305667 int retVal;
5668
5669 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305670
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305671 if (!pAdapter) {
5672 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5673 return -EINVAL;
5674 }
5675
Atul Mittal115287b2014-07-08 13:26:33 +05305676 ret = wlan_hdd_validate_context(pHddCtx);
5677 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305678 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305679 return -EINVAL;
5680 }
5681 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305683 return -ENOTSUPP;
5684 }
5685 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5686 data, data_len,
5687 wlan_hdd_tdls_config_get_status_policy)) {
5688 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5689 return -EINVAL;
5690 }
5691
5692 /* Parse and fetch mac address */
5693 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5694 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5695 return -EINVAL;
5696 }
5697
5698 memcpy(peer, nla_data(
5699 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5700 sizeof(peer));
5701 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5702
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305703 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305704
Atul Mittal115287b2014-07-08 13:26:33 +05305705 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305706 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305707 NLMSG_HDRLEN);
5708
5709 if (!skb) {
5710 hddLog(VOS_TRACE_LEVEL_ERROR,
5711 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5712 return -EINVAL;
5713 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305714 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305715 reason,
5716 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305717 global_operating_class,
5718 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305719 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305720 if (nla_put_s32(skb,
5721 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5722 state) ||
5723 nla_put_s32(skb,
5724 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5725 reason) ||
5726 nla_put_s32(skb,
5727 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5728 global_operating_class) ||
5729 nla_put_s32(skb,
5730 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5731 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305732
5733 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5734 goto nla_put_failure;
5735 }
5736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305737 retVal = cfg80211_vendor_cmd_reply(skb);
5738 EXIT();
5739 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305740
5741nla_put_failure:
5742 kfree_skb(skb);
5743 return -EINVAL;
5744}
5745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305746static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5747 struct wireless_dev *wdev,
5748 const void *data,
5749 int data_len)
5750{
5751 int ret = 0;
5752
5753 vos_ssr_protect(__func__);
5754 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5755 vos_ssr_unprotect(__func__);
5756
5757 return ret;
5758}
5759
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305760static int wlan_hdd_cfg80211_exttdls_callback(
5761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5762 const tANI_U8* mac,
5763#else
5764 tANI_U8* mac,
5765#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305766 tANI_S32 state,
5767 tANI_S32 reason,
5768 void *ctx)
5769{
5770 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305771 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305772 tANI_S32 global_operating_class = 0;
5773 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305774 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305776 ENTER();
5777
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305778 if (!pAdapter) {
5779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5780 return -EINVAL;
5781 }
5782
5783 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305784 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305786 return -EINVAL;
5787 }
5788
5789 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305791 return -ENOTSUPP;
5792 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305793 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5795 NULL,
5796#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305797 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5798 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5799 GFP_KERNEL);
5800
5801 if (!skb) {
5802 hddLog(VOS_TRACE_LEVEL_ERROR,
5803 FL("cfg80211_vendor_event_alloc failed"));
5804 return -EINVAL;
5805 }
5806 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305807 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5808 reason,
5809 state,
5810 global_operating_class,
5811 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305812 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5813 MAC_ADDR_ARRAY(mac));
5814
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305815 if (nla_put(skb,
5816 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5817 VOS_MAC_ADDR_SIZE, mac) ||
5818 nla_put_s32(skb,
5819 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5820 state) ||
5821 nla_put_s32(skb,
5822 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5823 reason) ||
5824 nla_put_s32(skb,
5825 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5826 channel) ||
5827 nla_put_s32(skb,
5828 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5829 global_operating_class)
5830 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5832 goto nla_put_failure;
5833 }
5834
5835 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305836 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305837 return (0);
5838
5839nla_put_failure:
5840 kfree_skb(skb);
5841 return -EINVAL;
5842}
5843
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305844static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305845 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305846 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305847 int data_len)
5848{
5849 u8 peer[6] = {0};
5850 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5852 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5853 eHalStatus status;
5854 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305855 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305856 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305857
5858 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305859
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305860 if (!dev) {
5861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5862 return -EINVAL;
5863 }
5864
5865 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5866 if (!pAdapter) {
5867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5868 return -EINVAL;
5869 }
5870
Atul Mittal115287b2014-07-08 13:26:33 +05305871 status = wlan_hdd_validate_context(pHddCtx);
5872 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305873 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305874 return -EINVAL;
5875 }
5876 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305878 return -ENOTSUPP;
5879 }
5880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5881 data, data_len,
5882 wlan_hdd_tdls_config_enable_policy)) {
5883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5884 return -EINVAL;
5885 }
5886
5887 /* Parse and fetch mac address */
5888 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5890 return -EINVAL;
5891 }
5892
5893 memcpy(peer, nla_data(
5894 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5895 sizeof(peer));
5896 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5897
5898 /* Parse and fetch channel */
5899 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5900 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5901 return -EINVAL;
5902 }
5903 pReqMsg.channel = nla_get_s32(
5904 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5905 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5906
5907 /* Parse and fetch global operating class */
5908 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5909 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5910 return -EINVAL;
5911 }
5912 pReqMsg.global_operating_class = nla_get_s32(
5913 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5914 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5915 pReqMsg.global_operating_class);
5916
5917 /* Parse and fetch latency ms */
5918 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5920 return -EINVAL;
5921 }
5922 pReqMsg.max_latency_ms = nla_get_s32(
5923 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5924 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5925 pReqMsg.max_latency_ms);
5926
5927 /* Parse and fetch required bandwidth kbps */
5928 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5930 return -EINVAL;
5931 }
5932
5933 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5934 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5935 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5936 pReqMsg.min_bandwidth_kbps);
5937
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305938 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305939 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305940 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305941 wlan_hdd_cfg80211_exttdls_callback);
5942
5943 EXIT();
5944 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305945}
5946
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305947static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5948 struct wireless_dev *wdev,
5949 const void *data,
5950 int data_len)
5951{
5952 int ret = 0;
5953
5954 vos_ssr_protect(__func__);
5955 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5956 vos_ssr_unprotect(__func__);
5957
5958 return ret;
5959}
5960
5961static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305962 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305963 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305964 int data_len)
5965{
5966 u8 peer[6] = {0};
5967 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5969 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5970 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305971 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305972 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305973
5974 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305975
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305976 if (!dev) {
5977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5978 return -EINVAL;
5979 }
5980
5981 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5982 if (!pAdapter) {
5983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5984 return -EINVAL;
5985 }
5986
Atul Mittal115287b2014-07-08 13:26:33 +05305987 status = wlan_hdd_validate_context(pHddCtx);
5988 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305990 return -EINVAL;
5991 }
5992 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305994 return -ENOTSUPP;
5995 }
5996 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5997 data, data_len,
5998 wlan_hdd_tdls_config_disable_policy)) {
5999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6000 return -EINVAL;
6001 }
6002 /* Parse and fetch mac address */
6003 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
6004 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
6005 return -EINVAL;
6006 }
6007
6008 memcpy(peer, nla_data(
6009 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
6010 sizeof(peer));
6011 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
6012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306013 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
6014
6015 EXIT();
6016 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05306017}
6018
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306019static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
6020 struct wireless_dev *wdev,
6021 const void *data,
6022 int data_len)
6023{
6024 int ret = 0;
6025
6026 vos_ssr_protect(__func__);
6027 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
6028 vos_ssr_unprotect(__func__);
6029
6030 return ret;
6031}
6032
Dasari Srinivas7875a302014-09-26 17:50:57 +05306033static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306034__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05306035 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306036 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05306037{
6038 struct net_device *dev = wdev->netdev;
6039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6040 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6041 struct sk_buff *skb = NULL;
6042 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306043 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306045 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306046
6047 ret = wlan_hdd_validate_context(pHddCtx);
6048 if (0 != ret)
6049 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306050 return ret;
6051 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306052 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
6053 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
6054 fset |= WIFI_FEATURE_INFRA;
6055 }
6056
6057 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
6058 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
6059 fset |= WIFI_FEATURE_INFRA_5G;
6060 }
6061
6062#ifdef WLAN_FEATURE_P2P
6063 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
6064 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
6065 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
6066 fset |= WIFI_FEATURE_P2P;
6067 }
6068#endif
6069
6070 /* Soft-AP is supported currently by default */
6071 fset |= WIFI_FEATURE_SOFT_AP;
6072
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05306073 /* HOTSPOT is a supplicant feature, enable it by default */
6074 fset |= WIFI_FEATURE_HOTSPOT;
6075
Dasari Srinivas7875a302014-09-26 17:50:57 +05306076#ifdef WLAN_FEATURE_EXTSCAN
6077 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05306078 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
6079 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
6080 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306081 fset |= WIFI_FEATURE_EXTSCAN;
6082 }
6083#endif
6084
Dasari Srinivas7875a302014-09-26 17:50:57 +05306085 if (sme_IsFeatureSupportedByFW(NAN)) {
6086 hddLog(LOG1, FL("NAN is supported by firmware"));
6087 fset |= WIFI_FEATURE_NAN;
6088 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05306089
6090 /* D2D RTT is not supported currently by default */
Sourav Mohapatradf8b23c2017-11-17 17:50:31 +05306091 if (sme_IsFeatureSupportedByFW(RTT) &&
6092 pHddCtx->cfg_ini->enable_rtt_support) {
6093 hddLog(LOG1, FL("RTT is supported by firmware and framework"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05306094 fset |= WIFI_FEATURE_D2AP_RTT;
6095 }
6096
Padma, Santhosh Kumaraac4c4d2015-12-08 16:07:47 +05306097 if (sme_IsFeatureSupportedByFW(RTT3)) {
6098 hddLog(LOG1, FL("RTT3 is supported by firmware"));
6099 fset |= WIFI_FEATURE_RTT3;
6100 }
6101
Dasari Srinivas7875a302014-09-26 17:50:57 +05306102#ifdef FEATURE_WLAN_BATCH_SCAN
6103 if (fset & WIFI_FEATURE_EXTSCAN) {
6104 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
6105 fset &= ~WIFI_FEATURE_BATCH_SCAN;
6106 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
6107 hddLog(LOG1, FL("Batch scan is supported by firmware"));
6108 fset |= WIFI_FEATURE_BATCH_SCAN;
6109 }
6110#endif
6111
6112#ifdef FEATURE_WLAN_SCAN_PNO
6113 if (pHddCtx->cfg_ini->configPNOScanSupport &&
6114 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
6115 hddLog(LOG1, FL("PNO is supported by firmware"));
6116 fset |= WIFI_FEATURE_PNO;
6117 }
6118#endif
6119
6120 /* STA+STA is supported currently by default */
6121 fset |= WIFI_FEATURE_ADDITIONAL_STA;
6122
6123#ifdef FEATURE_WLAN_TDLS
6124 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
6125 sme_IsFeatureSupportedByFW(TDLS)) {
6126 hddLog(LOG1, FL("TDLS is supported by firmware"));
6127 fset |= WIFI_FEATURE_TDLS;
6128 }
6129
6130 /* TDLS_OFFCHANNEL is not supported currently by default */
6131#endif
6132
6133#ifdef WLAN_AP_STA_CONCURRENCY
6134 /* AP+STA concurrency is supported currently by default */
6135 fset |= WIFI_FEATURE_AP_STA;
6136#endif
6137
Mukul Sharma5add0532015-08-17 15:57:47 +05306138#ifdef WLAN_FEATURE_LINK_LAYER_STATS
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306139 if ((TRUE == pHddCtx->cfg_ini->fEnableLLStats) &&
6140 (TRUE == sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS))) {
Mukul Sharma5add0532015-08-17 15:57:47 +05306141 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
6142 hddLog(LOG1, FL("Link layer stats is supported by driver"));
Ajit Vaishya8353cfb2017-11-10 16:22:36 +05306143 }
Mukul Sharma5add0532015-08-17 15:57:47 +05306144#endif
6145
Dasari Srinivas7875a302014-09-26 17:50:57 +05306146 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
6147 NLMSG_HDRLEN);
6148
6149 if (!skb) {
6150 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6151 return -EINVAL;
6152 }
6153 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
6154
6155 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
6156 hddLog(LOGE, FL("nla put fail"));
6157 goto nla_put_failure;
6158 }
6159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306160 ret = cfg80211_vendor_cmd_reply(skb);
6161 EXIT();
6162 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05306163
6164nla_put_failure:
6165 kfree_skb(skb);
6166 return -EINVAL;
6167}
6168
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306169static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306170wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
6171 struct wireless_dev *wdev,
6172 const void *data, int data_len)
6173{
6174 int ret = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306175 vos_ssr_protect(__func__);
6176 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
6177 vos_ssr_unprotect(__func__);
6178
6179 return ret;
6180}
6181
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306182
6183static const struct
6184nla_policy
6185qca_wlan_vendor_wifi_logger_get_ring_data_policy
6186[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
6187 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
6188 = {.type = NLA_U32 },
6189};
6190
6191static int
6192 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6193 struct wireless_dev *wdev,
6194 const void *data,
6195 int data_len)
6196{
6197 int ret;
6198 VOS_STATUS status;
6199 uint32_t ring_id;
6200 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6201 struct nlattr *tb
6202 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
6203
6204 ENTER();
6205
6206 ret = wlan_hdd_validate_context(hdd_ctx);
6207 if (0 != ret) {
6208 return ret;
6209 }
6210
6211 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
6212 data, data_len,
6213 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
6214 hddLog(LOGE, FL("Invalid attribute"));
6215 return -EINVAL;
6216 }
6217
6218 /* Parse and fetch ring id */
6219 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
6220 hddLog(LOGE, FL("attr ATTR failed"));
6221 return -EINVAL;
6222 }
6223
6224 ring_id = nla_get_u32(
6225 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
6226
6227 hddLog(LOG1, FL("Bug report triggered by framework"));
6228
6229 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
6230 WLAN_LOG_INDICATOR_FRAMEWORK,
6231 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05306232 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306233 );
6234 if (VOS_STATUS_SUCCESS != status) {
6235 hddLog(LOGE, FL("Failed to trigger bug report"));
6236
6237 return -EINVAL;
6238 }
6239
6240 return 0;
6241
6242
6243}
6244
6245
6246static int
6247 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
6248 struct wireless_dev *wdev,
6249 const void *data,
6250 int data_len)
6251{
6252 int ret = 0;
6253
6254 vos_ssr_protect(__func__);
6255 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
6256 wdev, data, data_len);
6257 vos_ssr_unprotect(__func__);
6258
6259 return ret;
6260
6261}
6262
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306263#define MAX_CONCURRENT_MATRIX \
6264 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX
6265#define MATRIX_CONFIG_PARAM_SET_SIZE_MAX \
6266 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6267static const struct nla_policy
6268wlan_hdd_get_concurrency_matrix_policy[MAX_CONCURRENT_MATRIX + 1] = {
6269 [MATRIX_CONFIG_PARAM_SET_SIZE_MAX] = {.type = NLA_U32},
6270};
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306271
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306272static int
6273__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306274 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306275 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306276{
6277 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
6278 uint8_t i, feature_sets, max_feature_sets;
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306279 struct nlattr *tb[MAX_CONCURRENT_MATRIX + 1];
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306280 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306281 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6282 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306283
6284 ENTER();
6285
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306286 ret = wlan_hdd_validate_context(pHddCtx);
6287 if (0 != ret)
6288 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306289 return ret;
6290 }
6291
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306292 if (nla_parse(tb, MAX_CONCURRENT_MATRIX, data, data_len,
6293 wlan_hdd_get_concurrency_matrix_policy)) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306294 hddLog(LOGE, FL("Invalid ATTR"));
6295 return -EINVAL;
6296 }
6297
6298 /* Parse and fetch max feature set */
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306299 if (!tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306300 hddLog(LOGE, FL("Attr max feature set size failed"));
6301 return -EINVAL;
6302 }
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306303 max_feature_sets = nla_get_u32(tb[MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306304 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
6305
6306 /* Fill feature combination matrix */
6307 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306308 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6309 WIFI_FEATURE_P2P;
6310
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306311 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6312 WIFI_FEATURE_SOFT_AP;
6313
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306314 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
6315 WIFI_FEATURE_SOFT_AP;
6316
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306317 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
6318 WIFI_FEATURE_SOFT_AP |
6319 WIFI_FEATURE_P2P;
6320
6321 /* Add more feature combinations here */
6322
6323 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
6324 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
6325 hddLog(LOG1, "Feature set matrix");
6326 for (i = 0; i < feature_sets; i++)
6327 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
6328
6329 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
6330 sizeof(u32) * feature_sets +
6331 NLMSG_HDRLEN);
6332
6333 if (reply_skb) {
6334 if (nla_put_u32(reply_skb,
6335 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
6336 feature_sets) ||
6337 nla_put(reply_skb,
6338 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
6339 sizeof(u32) * feature_sets, feature_set_matrix)) {
6340 hddLog(LOGE, FL("nla put fail"));
6341 kfree_skb(reply_skb);
6342 return -EINVAL;
6343 }
6344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306345 ret = cfg80211_vendor_cmd_reply(reply_skb);
6346 EXIT();
6347 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306348 }
6349 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
6350 return -ENOMEM;
6351
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306352}
6353
Rajeev Kumar Sirasanagandla4c00e0d2017-06-13 12:04:09 +05306354#undef MAX_CONCURRENT_MATRIX
6355#undef MATRIX_CONFIG_PARAM_SET_SIZE_MAX
6356
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306357static int
6358wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
6359 struct wireless_dev *wdev,
6360 const void *data, int data_len)
6361{
6362 int ret = 0;
6363
6364 vos_ssr_protect(__func__);
6365 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
6366 data_len);
6367 vos_ssr_unprotect(__func__);
6368
6369 return ret;
6370}
6371
c_manjeecfd1efb2015-09-25 19:32:34 +05306372
6373static int
6374__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6375 struct wireless_dev *wdev,
6376 const void *data, int data_len)
6377{
6378 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6379 int ret;
6380 ENTER();
6381
6382 ret = wlan_hdd_validate_context(pHddCtx);
6383 if (0 != ret)
6384 {
6385 return ret;
6386 }
6387
6388 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
6389 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
6390 {
6391 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
Ajit Vaishyac5ba8482017-11-16 14:10:37 +05306392 return -EOPNOTSUPP;
c_manjeecfd1efb2015-09-25 19:32:34 +05306393 }
6394 /*call common API for FW mem dump req*/
6395 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
6396
Abhishek Singhc783fa72015-12-09 18:07:34 +05306397 if (!ret)
c_manjee04b4c5c2015-10-13 18:35:01 +05306398 {
6399 /*indicate to userspace the status of fw mem dump */
6400 wlan_indicate_mem_dump_complete(true);
6401 }
6402 else
6403 {
6404 /*else send failure to userspace */
6405 wlan_indicate_mem_dump_complete(false);
6406 }
c_manjeecfd1efb2015-09-25 19:32:34 +05306407 EXIT();
6408 return ret;
6409}
6410
6411/**
6412 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
6413 * @wiphy: pointer to wireless wiphy structure.
6414 * @wdev: pointer to wireless_dev structure.
6415 * @data: Pointer to the NL data.
6416 * @data_len:Length of @data
6417 *
6418 * This is called when wlan driver needs to get the firmware memory dump
6419 * via vendor specific command.
6420 *
6421 * Return: 0 on success, error number otherwise.
6422 */
6423
6424static int
6425wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
6426 struct wireless_dev *wdev,
6427 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05306428{
6429 int ret = 0;
6430 vos_ssr_protect(__func__);
6431 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
6432 data_len);
6433 vos_ssr_unprotect(__func__);
6434 return ret;
6435}
c_manjeecfd1efb2015-09-25 19:32:34 +05306436
Sushant Kaushik8e644982015-09-23 12:18:54 +05306437static const struct
6438nla_policy
6439qca_wlan_vendor_wifi_logger_start_policy
6440[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
6441 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
6442 = {.type = NLA_U32 },
6443 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
6444 = {.type = NLA_U32 },
6445 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
6446 = {.type = NLA_U32 },
6447};
6448
6449/**
6450 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
6451 * or disable the collection of packet statistics from the firmware
6452 * @wiphy: WIPHY structure pointer
6453 * @wdev: Wireless device structure pointer
6454 * @data: Pointer to the data received
6455 * @data_len: Length of the data received
6456 *
6457 * This function is used to enable or disable the collection of packet
6458 * statistics from the firmware
6459 *
6460 * Return: 0 on success and errno on failure
6461 */
6462static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6463 struct wireless_dev *wdev,
6464 const void *data,
6465 int data_len)
6466{
6467 eHalStatus status;
6468 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6469 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
6470 tAniWifiStartLog start_log;
6471
6472 status = wlan_hdd_validate_context(hdd_ctx);
6473 if (0 != status) {
6474 return -EINVAL;
6475 }
6476
6477 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
6478 data, data_len,
6479 qca_wlan_vendor_wifi_logger_start_policy)) {
6480 hddLog(LOGE, FL("Invalid attribute"));
6481 return -EINVAL;
6482 }
6483
6484 /* Parse and fetch ring id */
6485 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
6486 hddLog(LOGE, FL("attr ATTR failed"));
6487 return -EINVAL;
6488 }
6489 start_log.ringId = nla_get_u32(
6490 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
6491 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
6492
6493 /* Parse and fetch verbose level */
6494 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
6495 hddLog(LOGE, FL("attr verbose_level failed"));
6496 return -EINVAL;
6497 }
6498 start_log.verboseLevel = nla_get_u32(
6499 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
6500 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
6501
6502 /* Parse and fetch flag */
6503 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
6504 hddLog(LOGE, FL("attr flag failed"));
6505 return -EINVAL;
6506 }
6507 start_log.flag = nla_get_u32(
6508 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
6509 hddLog(LOG1, FL("flag=%d"), start_log.flag);
6510
6511 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05306512 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
6513 !vos_isPktStatsEnabled()))
6514
Sushant Kaushik8e644982015-09-23 12:18:54 +05306515 {
6516 hddLog(LOGE, FL("per pkt stats not enabled"));
6517 return -EINVAL;
6518 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05306519
Sushant Kaushik33200572015-08-05 16:46:20 +05306520 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306521 return 0;
6522}
6523
6524/**
6525 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
6526 * or disable the collection of packet statistics from the firmware
6527 * @wiphy: WIPHY structure pointer
6528 * @wdev: Wireless device structure pointer
6529 * @data: Pointer to the data received
6530 * @data_len: Length of the data received
6531 *
6532 * This function is used to enable or disable the collection of packet
6533 * statistics from the firmware
6534 *
6535 * Return: 0 on success and errno on failure
6536 */
6537static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
6538 struct wireless_dev *wdev,
6539 const void *data,
6540 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05306541{
6542 int ret = 0;
6543
6544 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05306545
6546 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
6547 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05306548 vos_ssr_unprotect(__func__);
6549
6550 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05306551}
6552
6553
Agarwal Ashish738843c2014-09-25 12:27:56 +05306554static const struct nla_policy
6555wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
6556 +1] =
6557{
6558 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
6559};
6560
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306561static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306562 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306563 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306564 int data_len)
6565{
6566 struct net_device *dev = wdev->netdev;
6567 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6568 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6570 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6571 eHalStatus status;
6572 u32 dfsFlag = 0;
6573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306574 ENTER();
6575
Agarwal Ashish738843c2014-09-25 12:27:56 +05306576 status = wlan_hdd_validate_context(pHddCtx);
6577 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306578 return -EINVAL;
6579 }
6580 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6581 data, data_len,
6582 wlan_hdd_set_no_dfs_flag_config_policy)) {
6583 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6584 return -EINVAL;
6585 }
6586
6587 /* Parse and fetch required bandwidth kbps */
6588 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6589 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6590 return -EINVAL;
6591 }
6592
6593 dfsFlag = nla_get_u32(
6594 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6595 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6596 dfsFlag);
6597
6598 pHddCtx->disable_dfs_flag = dfsFlag;
6599
6600 sme_disable_dfs_channel(hHal, dfsFlag);
6601 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306602
6603 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306604 return 0;
6605}
Atul Mittal115287b2014-07-08 13:26:33 +05306606
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306607static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6608 struct wireless_dev *wdev,
6609 const void *data,
6610 int data_len)
6611{
6612 int ret = 0;
6613
6614 vos_ssr_protect(__func__);
6615 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6616 vos_ssr_unprotect(__func__);
6617
6618 return ret;
6619
6620}
6621
Mukul Sharma2a271632014-10-13 14:59:01 +05306622const struct
6623nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6624{
6625 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05306626 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
6627 .type = NLA_UNSPEC,
6628 .len = HDD_MAC_ADDR_LEN},
Mukul Sharma2a271632014-10-13 14:59:01 +05306629};
6630
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306631static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306632 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306633{
6634
6635 u8 bssid[6] = {0};
6636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6637 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6638 eHalStatus status = eHAL_STATUS_SUCCESS;
6639 v_U32_t isFwrRoamEnabled = FALSE;
6640 int ret;
6641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306642 ENTER();
6643
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306644 ret = wlan_hdd_validate_context(pHddCtx);
6645 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306646 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306647 }
6648
6649 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6650 data, data_len,
6651 qca_wlan_vendor_attr);
6652 if (ret){
6653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6654 return -EINVAL;
6655 }
6656
6657 /* Parse and fetch Enable flag */
6658 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6660 return -EINVAL;
6661 }
6662
6663 isFwrRoamEnabled = nla_get_u32(
6664 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6665
6666 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6667
6668 /* Parse and fetch bssid */
6669 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6671 return -EINVAL;
6672 }
6673
6674 memcpy(bssid, nla_data(
6675 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6676 sizeof(bssid));
6677 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6678
6679 //Update roaming
6680 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306681 if (!HAL_STATUS_SUCCESS(status)) {
6682 hddLog(LOGE,
6683 FL("sme_ConfigFwrRoaming failed (err=%d)"), status);
6684 return -EINVAL;
6685 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306686 EXIT();
Abhishek Singhc6ab38f2016-06-28 17:48:16 +05306687 return 0;
Mukul Sharma2a271632014-10-13 14:59:01 +05306688}
6689
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306690static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6691 struct wireless_dev *wdev, const void *data, int data_len)
6692{
6693 int ret = 0;
6694
6695 vos_ssr_protect(__func__);
6696 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6697 vos_ssr_unprotect(__func__);
6698
6699 return ret;
6700}
6701
Sushant Kaushik847890c2015-09-28 16:05:17 +05306702static const struct
6703nla_policy
6704qca_wlan_vendor_get_wifi_info_policy[
6705 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6706 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6707 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6708};
6709
6710
6711/**
6712 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6713 * @wiphy: pointer to wireless wiphy structure.
6714 * @wdev: pointer to wireless_dev structure.
6715 * @data: Pointer to the data to be passed via vendor interface
6716 * @data_len:Length of the data to be passed
6717 *
6718 * This is called when wlan driver needs to send wifi driver related info
6719 * (driver/fw version) to the user space application upon request.
6720 *
6721 * Return: Return the Success or Failure code.
6722 */
6723static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6724 struct wireless_dev *wdev,
6725 const void *data, int data_len)
6726{
6727 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6728 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6729 tSirVersionString version;
6730 uint32 version_len;
6731 uint8 attr;
6732 int status;
6733 struct sk_buff *reply_skb = NULL;
6734
6735 if (VOS_FTM_MODE == hdd_get_conparam()) {
6736 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6737 return -EINVAL;
6738 }
6739
6740 status = wlan_hdd_validate_context(hdd_ctx);
6741 if (0 != status) {
6742 hddLog(LOGE, FL("HDD context is not valid"));
6743 return -EINVAL;
6744 }
6745
6746 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6747 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6748 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6749 return -EINVAL;
6750 }
6751
6752 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6753 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6754 QWLAN_VERSIONSTR);
6755 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6756 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6757 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6758 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6759 hdd_ctx->fw_Version);
6760 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6761 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6762 } else {
6763 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6764 return -EINVAL;
6765 }
6766
6767 version_len = strlen(version);
6768 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6769 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6770 if (!reply_skb) {
6771 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6772 return -ENOMEM;
6773 }
6774
6775 if (nla_put(reply_skb, attr, version_len, version)) {
6776 hddLog(LOGE, FL("nla put fail"));
6777 kfree_skb(reply_skb);
6778 return -EINVAL;
6779 }
6780
6781 return cfg80211_vendor_cmd_reply(reply_skb);
6782}
6783
6784/**
6785 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6786 * @wiphy: pointer to wireless wiphy structure.
6787 * @wdev: pointer to wireless_dev structure.
6788 * @data: Pointer to the data to be passed via vendor interface
6789 * @data_len:Length of the data to be passed
6790 * @data_len: Length of the data received
6791 *
6792 * This function is used to enable or disable the collection of packet
6793 * statistics from the firmware
6794 *
6795 * Return: 0 on success and errno on failure
6796 */
6797
6798static int
6799wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6800 struct wireless_dev *wdev,
6801 const void *data, int data_len)
6802
6803
6804{
6805 int ret = 0;
6806
6807 vos_ssr_protect(__func__);
6808 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6809 wdev, data, data_len);
6810 vos_ssr_unprotect(__func__);
6811
6812 return ret;
6813}
6814
6815
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306816/*
6817 * define short names for the global vendor params
6818 * used by __wlan_hdd_cfg80211_monitor_rssi()
6819 */
6820#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6821#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6822#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6823#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6824#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6825
6826/**---------------------------------------------------------------------------
6827
6828 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6829 monitor start is completed successfully.
6830
6831 \return - None
6832
6833 --------------------------------------------------------------------------*/
6834void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6835{
6836 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6837
6838 if (NULL == pHddCtx)
6839 {
6840 hddLog(VOS_TRACE_LEVEL_ERROR,
6841 "%s: HDD context is NULL",__func__);
6842 return;
6843 }
6844
6845 if (VOS_STATUS_SUCCESS == status)
6846 {
6847 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6848 }
6849 else
6850 {
6851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6852 }
6853
6854 return;
6855}
6856
6857/**---------------------------------------------------------------------------
6858
6859 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6860 stop is completed successfully.
6861
6862 \return - None
6863
6864 --------------------------------------------------------------------------*/
6865void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6866{
6867 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6868
6869 if (NULL == pHddCtx)
6870 {
6871 hddLog(VOS_TRACE_LEVEL_ERROR,
6872 "%s: HDD context is NULL",__func__);
6873 return;
6874 }
6875
6876 if (VOS_STATUS_SUCCESS == status)
6877 {
6878 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6879 }
6880 else
6881 {
6882 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6883 }
6884
6885 return;
6886}
6887
6888/**
6889 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6890 * @wiphy: Pointer to wireless phy
6891 * @wdev: Pointer to wireless device
6892 * @data: Pointer to data
6893 * @data_len: Data length
6894 *
6895 * Return: 0 on success, negative errno on failure
6896 */
6897
6898static int
6899__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6900 struct wireless_dev *wdev,
6901 const void *data,
6902 int data_len)
6903{
6904 struct net_device *dev = wdev->netdev;
6905 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6906 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6907 hdd_station_ctx_t *pHddStaCtx;
6908 struct nlattr *tb[PARAM_MAX + 1];
6909 tpSirRssiMonitorReq pReq;
6910 eHalStatus status;
6911 int ret;
6912 uint32_t control;
6913 static const struct nla_policy policy[PARAM_MAX + 1] = {
6914 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6915 [PARAM_CONTROL] = { .type = NLA_U32 },
6916 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6917 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6918 };
6919
6920 ENTER();
6921
6922 ret = wlan_hdd_validate_context(hdd_ctx);
6923 if (0 != ret) {
6924 return -EINVAL;
6925 }
6926
6927 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6928 hddLog(LOGE, FL("Not in Connected state!"));
6929 return -ENOTSUPP;
6930 }
6931
6932 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6933 hddLog(LOGE, FL("Invalid ATTR"));
6934 return -EINVAL;
6935 }
6936
6937 if (!tb[PARAM_REQUEST_ID]) {
6938 hddLog(LOGE, FL("attr request id failed"));
6939 return -EINVAL;
6940 }
6941
6942 if (!tb[PARAM_CONTROL]) {
6943 hddLog(LOGE, FL("attr control failed"));
6944 return -EINVAL;
6945 }
6946
6947 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6948
6949 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6950 if(NULL == pReq)
6951 {
6952 hddLog(LOGE,
6953 FL("vos_mem_alloc failed "));
6954 return eHAL_STATUS_FAILED_ALLOC;
6955 }
6956 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6957
6958 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6959 pReq->sessionId = pAdapter->sessionId;
6960 pReq->rssiMonitorCbContext = hdd_ctx;
6961 control = nla_get_u32(tb[PARAM_CONTROL]);
6962 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6963
6964 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6965 pReq->requestId, pReq->sessionId, control);
6966
6967 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6968 if (!tb[PARAM_MIN_RSSI]) {
6969 hddLog(LOGE, FL("attr min rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306970 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306971 }
6972
6973 if (!tb[PARAM_MAX_RSSI]) {
6974 hddLog(LOGE, FL("attr max rssi failed"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306975 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306976 }
6977
6978 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6979 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6980 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6981
6982 if (!(pReq->minRssi < pReq->maxRssi)) {
6983 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6984 pReq->minRssi, pReq->maxRssi);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306985 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306986 }
6987 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6988 pReq->minRssi, pReq->maxRssi);
6989 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6990
6991 }
6992 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6993 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6994 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6995 }
6996 else {
6997 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05306998 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306999 }
7000
7001 if (!HAL_STATUS_SUCCESS(status)) {
7002 hddLog(LOGE,
7003 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307004 goto fail;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307005 }
7006
7007 return 0;
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307008fail:
7009 vos_mem_free(pReq);
7010 return -EINVAL;
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307011}
7012
7013/*
7014 * done with short names for the global vendor params
7015 * used by __wlan_hdd_cfg80211_monitor_rssi()
7016 */
7017#undef PARAM_MAX
7018#undef PARAM_CONTROL
7019#undef PARAM_REQUEST_ID
7020#undef PARAM_MAX_RSSI
7021#undef PARAM_MIN_RSSI
7022
7023/**
7024 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
7025 * @wiphy: wiphy structure pointer
7026 * @wdev: Wireless device structure pointer
7027 * @data: Pointer to the data received
7028 * @data_len: Length of @data
7029 *
7030 * Return: 0 on success; errno on failure
7031 */
7032static int
7033wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
7034 const void *data, int data_len)
7035{
7036 int ret;
7037
7038 vos_ssr_protect(__func__);
7039 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
7040 vos_ssr_unprotect(__func__);
7041
7042 return ret;
7043}
7044
7045/**
7046 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
7047 * @hddctx: HDD context
7048 * @data: rssi breached event data
7049 *
7050 * This function reads the rssi breached event %data and fill in the skb with
7051 * NL attributes and send up the NL event.
7052 * This callback execute in atomic context and must not invoke any
7053 * blocking calls.
7054 *
7055 * Return: none
7056 */
7057void hdd_rssi_threshold_breached_cb(void *hddctx,
7058 struct rssi_breach_event *data)
7059{
7060 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
7061 int status;
7062 struct sk_buff *skb;
7063
7064 ENTER();
7065 status = wlan_hdd_validate_context(pHddCtx);
7066
7067 if (0 != status) {
7068 return;
7069 }
7070
7071 if (!data) {
7072 hddLog(LOGE, FL("data is null"));
7073 return;
7074 }
7075
7076 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
7077#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7078 NULL,
7079#endif
7080 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
7081 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
7082 GFP_KERNEL);
7083
7084 if (!skb) {
7085 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
7086 return;
7087 }
7088
7089 hddLog(LOG1, "Req Id: %u Current rssi: %d",
7090 data->request_id, data->curr_rssi);
7091 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
7092 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
7093
7094 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
7095 data->request_id) ||
7096 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
7097 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
7098 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
7099 data->curr_rssi)) {
7100 hddLog(LOGE, FL("nla put fail"));
7101 goto fail;
7102 }
7103
7104 cfg80211_vendor_event(skb, GFP_KERNEL);
7105 return;
7106
7107fail:
7108 kfree_skb(skb);
7109 return;
7110}
7111
7112
7113
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307114/**
7115 * __wlan_hdd_cfg80211_setband() - set band
7116 * @wiphy: Pointer to wireless phy
7117 * @wdev: Pointer to wireless device
7118 * @data: Pointer to data
7119 * @data_len: Data length
7120 *
7121 * Return: 0 on success, negative errno on failure
7122 */
7123static int
7124__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7125 struct wireless_dev *wdev,
7126 const void *data,
7127 int data_len)
7128{
7129 struct net_device *dev = wdev->netdev;
7130 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7131 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
7132 int ret;
7133 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
7134 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
7135
7136 ENTER();
7137
7138 ret = wlan_hdd_validate_context(hdd_ctx);
7139 if (0 != ret) {
7140 hddLog(LOGE, FL("HDD context is not valid"));
7141 return ret;
7142 }
7143
7144 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7145 policy)) {
7146 hddLog(LOGE, FL("Invalid ATTR"));
7147 return -EINVAL;
7148 }
7149
7150 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
7151 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
7152 return -EINVAL;
7153 }
7154
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307155 hdd_ctx->isSetBandByNL = TRUE;
7156 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307157 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05307158 hdd_ctx->isSetBandByNL = FALSE;
7159
7160 EXIT();
7161 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307162}
7163
7164/**
7165 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
7166 * @wiphy: wiphy structure pointer
7167 * @wdev: Wireless device structure pointer
7168 * @data: Pointer to the data received
7169 * @data_len: Length of @data
7170 *
7171 * Return: 0 on success; errno on failure
7172 */
7173static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
7174 struct wireless_dev *wdev,
7175 const void *data,
7176 int data_len)
7177{
7178 int ret = 0;
7179
7180 vos_ssr_protect(__func__);
7181 ret = __wlan_hdd_cfg80211_setband(wiphy,
7182 wdev, data, data_len);
7183 vos_ssr_unprotect(__func__);
7184
7185 return ret;
7186}
7187
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307188#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7189/**
7190 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
7191 * @hdd_ctx: HDD context
7192 * @request_id: [input] request id
7193 * @pattern_id: [output] pattern id
7194 *
7195 * This function loops through request id to pattern id array
7196 * if the slot is available, store the request id and return pattern id
7197 * if entry exists, return the pattern id
7198 *
7199 * Return: 0 on success and errno on failure
7200 */
7201static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7202 uint32_t request_id,
7203 uint8_t *pattern_id)
7204{
7205 uint32_t i;
7206
7207 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7208 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7209 {
7210 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
7211 {
7212 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
7213 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7214 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7215 return 0;
7216 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
7217 request_id) {
7218 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7219 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7220 return 0;
7221 }
7222 }
7223 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7224 return -EINVAL;
7225}
7226
7227/**
7228 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
7229 * @hdd_ctx: HDD context
7230 * @request_id: [input] request id
7231 * @pattern_id: [output] pattern id
7232 *
7233 * This function loops through request id to pattern id array
7234 * reset request id to 0 (slot available again) and
7235 * return pattern id
7236 *
7237 * Return: 0 on success and errno on failure
7238 */
7239static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
7240 uint32_t request_id,
7241 uint8_t *pattern_id)
7242{
7243 uint32_t i;
7244
7245 mutex_lock(&hdd_ctx->op_ctx.op_lock);
7246 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
7247 {
7248 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
7249 {
7250 hdd_ctx->op_ctx.op_table[i].request_id = 0;
7251 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
7252 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7253 return 0;
7254 }
7255 }
7256 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
7257 return -EINVAL;
7258}
7259
7260
7261/*
7262 * define short names for the global vendor params
7263 * used by __wlan_hdd_cfg80211_offloaded_packets()
7264 */
7265#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
7266#define PARAM_REQUEST_ID \
7267 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
7268#define PARAM_CONTROL \
7269 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
7270#define PARAM_IP_PACKET \
7271 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
7272#define PARAM_SRC_MAC_ADDR \
7273 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
7274#define PARAM_DST_MAC_ADDR \
7275 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
7276#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
7277
7278/**
7279 * wlan_hdd_add_tx_ptrn() - add tx pattern
7280 * @adapter: adapter pointer
7281 * @hdd_ctx: hdd context
7282 * @tb: nl attributes
7283 *
7284 * This function reads the NL attributes and forms a AddTxPtrn message
7285 * posts it to SME.
7286 *
7287 */
7288static int
7289wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7290 struct nlattr **tb)
7291{
7292 struct sSirAddPeriodicTxPtrn *add_req;
7293 eHalStatus status;
7294 uint32_t request_id, ret, len;
7295 uint8_t pattern_id = 0;
7296 v_MACADDR_t dst_addr;
7297 uint16_t eth_type = htons(ETH_P_IP);
7298
7299 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
7300 {
7301 hddLog(LOGE, FL("Not in Connected state!"));
7302 return -ENOTSUPP;
7303 }
7304
7305 add_req = vos_mem_malloc(sizeof(*add_req));
7306 if (!add_req)
7307 {
7308 hddLog(LOGE, FL("memory allocation failed"));
7309 return -ENOMEM;
7310 }
7311
7312 /* Parse and fetch request Id */
7313 if (!tb[PARAM_REQUEST_ID])
7314 {
7315 hddLog(LOGE, FL("attr request id failed"));
7316 goto fail;
7317 }
7318
7319 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7320 hddLog(LOG1, FL("Request Id: %u"), request_id);
7321 if (request_id == 0)
7322 {
7323 hddLog(LOGE, FL("request_id cannot be zero"));
Sreelakshmi Konamkideb22532016-04-14 14:59:13 +05307324 goto fail;
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307325 }
7326
7327 if (!tb[PARAM_PERIOD])
7328 {
7329 hddLog(LOGE, FL("attr period failed"));
7330 goto fail;
7331 }
7332 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
7333 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
7334 if (add_req->usPtrnIntervalMs == 0)
7335 {
7336 hddLog(LOGE, FL("Invalid interval zero, return failure"));
7337 goto fail;
7338 }
7339
7340 if (!tb[PARAM_SRC_MAC_ADDR])
7341 {
7342 hddLog(LOGE, FL("attr source mac address failed"));
7343 goto fail;
7344 }
7345 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
7346 VOS_MAC_ADDR_SIZE);
7347 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
7348 MAC_ADDR_ARRAY(add_req->macAddress));
7349
7350 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
7351 VOS_MAC_ADDR_SIZE))
7352 {
7353 hddLog(LOGE,
7354 FL("input src mac address and connected ap bssid are different"));
7355 goto fail;
7356 }
7357
7358 if (!tb[PARAM_DST_MAC_ADDR])
7359 {
7360 hddLog(LOGE, FL("attr dst mac address failed"));
7361 goto fail;
7362 }
7363 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
7364 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
7365 MAC_ADDR_ARRAY(dst_addr.bytes));
7366
7367 if (!tb[PARAM_IP_PACKET])
7368 {
7369 hddLog(LOGE, FL("attr ip packet failed"));
7370 goto fail;
7371 }
7372 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
7373 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
7374
7375 if (add_req->ucPtrnSize < 0 ||
7376 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
7377 HDD_ETH_HEADER_LEN))
7378 {
7379 hddLog(LOGE, FL("Invalid IP packet len: %d"),
7380 add_req->ucPtrnSize);
7381 goto fail;
7382 }
7383
7384 len = 0;
7385 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
7386 len += VOS_MAC_ADDR_SIZE;
7387 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
7388 VOS_MAC_ADDR_SIZE);
7389 len += VOS_MAC_ADDR_SIZE;
7390 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
7391 len += 2;
7392
7393 /*
7394 * This is the IP packet, add 14 bytes Ethernet (802.3) header
7395 * ------------------------------------------------------------
7396 * | 14 bytes Ethernet (802.3) header | IP header and payload |
7397 * ------------------------------------------------------------
7398 */
7399 vos_mem_copy(&add_req->ucPattern[len],
7400 nla_data(tb[PARAM_IP_PACKET]),
7401 add_req->ucPtrnSize);
7402 add_req->ucPtrnSize += len;
7403
7404 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
7405 add_req->ucPattern, add_req->ucPtrnSize);
7406
7407 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7408 if (ret)
7409 {
7410 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7411 goto fail;
7412 }
7413 add_req->ucPtrnId = pattern_id;
7414 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
7415
7416 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
7417 if (!HAL_STATUS_SUCCESS(status))
7418 {
7419 hddLog(LOGE,
7420 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
7421 goto fail;
7422 }
7423
7424 EXIT();
7425 vos_mem_free(add_req);
7426 return 0;
7427
7428fail:
7429 vos_mem_free(add_req);
7430 return -EINVAL;
7431}
7432
7433/**
7434 * wlan_hdd_del_tx_ptrn() - delete tx pattern
7435 * @adapter: adapter pointer
7436 * @hdd_ctx: hdd context
7437 * @tb: nl attributes
7438 *
7439 * This function reads the NL attributes and forms a DelTxPtrn message
7440 * posts it to SME.
7441 *
7442 */
7443static int
7444wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
7445 struct nlattr **tb)
7446{
7447 struct sSirDelPeriodicTxPtrn *del_req;
7448 eHalStatus status;
7449 uint32_t request_id, ret;
7450 uint8_t pattern_id = 0;
7451
7452 /* Parse and fetch request Id */
7453 if (!tb[PARAM_REQUEST_ID])
7454 {
7455 hddLog(LOGE, FL("attr request id failed"));
7456 return -EINVAL;
7457 }
7458 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
7459 if (request_id == 0)
7460 {
7461 hddLog(LOGE, FL("request_id cannot be zero"));
7462 return -EINVAL;
7463 }
7464
7465 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
7466 if (ret)
7467 {
7468 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
7469 return -EINVAL;
7470 }
7471
7472 del_req = vos_mem_malloc(sizeof(*del_req));
7473 if (!del_req)
7474 {
7475 hddLog(LOGE, FL("memory allocation failed"));
7476 return -ENOMEM;
7477 }
7478
7479 vos_mem_set(del_req, sizeof(*del_req), 0);
7480 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
7481 VOS_MAC_ADDR_SIZE);
7482 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
7483 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
7484 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
7485 request_id, pattern_id, del_req->ucPatternIdBitmap);
7486
7487 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
7488 if (!HAL_STATUS_SUCCESS(status))
7489 {
7490 hddLog(LOGE,
7491 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
7492 goto fail;
7493 }
7494
7495 EXIT();
7496 vos_mem_free(del_req);
7497 return 0;
7498
7499fail:
7500 vos_mem_free(del_req);
7501 return -EINVAL;
7502}
7503
7504
7505/**
7506 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
7507 * @wiphy: Pointer to wireless phy
7508 * @wdev: Pointer to wireless device
7509 * @data: Pointer to data
7510 * @data_len: Data length
7511 *
7512 * Return: 0 on success, negative errno on failure
7513 */
7514static int
7515__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7516 struct wireless_dev *wdev,
7517 const void *data,
7518 int data_len)
7519{
7520 struct net_device *dev = wdev->netdev;
7521 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7522 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7523 struct nlattr *tb[PARAM_MAX + 1];
7524 uint8_t control;
7525 int ret;
7526 static const struct nla_policy policy[PARAM_MAX + 1] =
7527 {
7528 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
7529 [PARAM_CONTROL] = { .type = NLA_U32 },
7530 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
7531 .len = VOS_MAC_ADDR_SIZE },
7532 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
7533 .len = VOS_MAC_ADDR_SIZE },
7534 [PARAM_PERIOD] = { .type = NLA_U32 },
7535 };
7536
7537 ENTER();
7538
7539 ret = wlan_hdd_validate_context(hdd_ctx);
7540 if (0 != ret)
7541 {
7542 hddLog(LOGE, FL("HDD context is not valid"));
7543 return ret;
7544 }
7545
7546 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
7547 {
7548 hddLog(LOGE,
7549 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
7550 return -ENOTSUPP;
7551 }
7552
7553 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
7554 {
7555 hddLog(LOGE, FL("Invalid ATTR"));
7556 return -EINVAL;
7557 }
7558
7559 if (!tb[PARAM_CONTROL])
7560 {
7561 hddLog(LOGE, FL("attr control failed"));
7562 return -EINVAL;
7563 }
7564 control = nla_get_u32(tb[PARAM_CONTROL]);
7565 hddLog(LOG1, FL("Control: %d"), control);
7566
7567 if (control == WLAN_START_OFFLOADED_PACKETS)
7568 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
7569 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7570 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7571 else
7572 {
7573 hddLog(LOGE, FL("Invalid control: %d"), control);
7574 return -EINVAL;
7575 }
7576}
7577
7578/*
7579 * done with short names for the global vendor params
7580 * used by __wlan_hdd_cfg80211_offloaded_packets()
7581 */
7582#undef PARAM_MAX
7583#undef PARAM_REQUEST_ID
7584#undef PARAM_CONTROL
7585#undef PARAM_IP_PACKET
7586#undef PARAM_SRC_MAC_ADDR
7587#undef PARAM_DST_MAC_ADDR
7588#undef PARAM_PERIOD
7589
7590/**
7591 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7592 * @wiphy: wiphy structure pointer
7593 * @wdev: Wireless device structure pointer
7594 * @data: Pointer to the data received
7595 * @data_len: Length of @data
7596 *
7597 * Return: 0 on success; errno on failure
7598 */
7599static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7600 struct wireless_dev *wdev,
7601 const void *data,
7602 int data_len)
7603{
7604 int ret = 0;
7605
7606 vos_ssr_protect(__func__);
7607 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7608 wdev, data, data_len);
7609 vos_ssr_unprotect(__func__);
7610
7611 return ret;
7612}
7613#endif
7614
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307615static const struct
7616nla_policy
7617qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
Jeff Johnsonda8c3a72017-06-23 15:59:08 +05307618 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = {
7619 .type = NLA_BINARY,
7620 .len = HDD_MAC_ADDR_LEN},
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307621};
7622
7623/**
7624 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7625 * get link properties like nss, rate flags and operating frequency for
7626 * the connection with the given peer.
7627 * @wiphy: WIPHY structure pointer
7628 * @wdev: Wireless device structure pointer
7629 * @data: Pointer to the data received
7630 * @data_len: Length of the data received
7631 *
7632 * This function return the above link properties on success.
7633 *
7634 * Return: 0 on success and errno on failure
7635 */
7636static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7637 struct wireless_dev *wdev,
7638 const void *data,
7639 int data_len)
7640{
7641 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7642 struct net_device *dev = wdev->netdev;
7643 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7644 hdd_station_ctx_t *hdd_sta_ctx;
7645 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7646 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7647 uint32_t sta_id;
7648 struct sk_buff *reply_skb;
7649 uint32_t rate_flags = 0;
7650 uint8_t nss;
7651 uint8_t final_rate_flags = 0;
7652 uint32_t freq;
7653 v_CONTEXT_t pVosContext = NULL;
7654 ptSapContext pSapCtx = NULL;
7655
7656 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7657 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7658 return -EINVAL;
7659 }
7660
7661 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7662 qca_wlan_vendor_attr_policy)) {
7663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7664 return -EINVAL;
7665 }
7666
7667 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7668 hddLog(VOS_TRACE_LEVEL_ERROR,
7669 FL("Attribute peerMac not provided for mode=%d"),
7670 adapter->device_mode);
7671 return -EINVAL;
7672 }
7673
Ashish Kumar Dhanotiyaddaf0482017-06-23 15:22:42 +05307674 if (nla_len(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) < sizeof(peer_mac)) {
7675 hddLog(VOS_TRACE_LEVEL_ERROR,
7676 FL("Attribute peerMac is invalid=%d"),
7677 adapter->device_mode);
7678 return -EINVAL;
7679 }
7680
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307681 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7682 sizeof(peer_mac));
7683 hddLog(VOS_TRACE_LEVEL_INFO,
7684 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7685 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7686
7687 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7688 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7689 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7690 if ((hdd_sta_ctx->conn_info.connState !=
7691 eConnectionState_Associated) ||
7692 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7693 VOS_MAC_ADDRESS_LEN)) {
7694 hddLog(VOS_TRACE_LEVEL_ERROR,
7695 FL("Not Associated to mac "MAC_ADDRESS_STR),
7696 MAC_ADDR_ARRAY(peer_mac));
7697 return -EINVAL;
7698 }
7699
7700 nss = 1; //pronto supports only one spatial stream
7701 freq = vos_chan_to_freq(
7702 hdd_sta_ctx->conn_info.operationChannel);
7703 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7704
7705 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7706 adapter->device_mode == WLAN_HDD_SOFTAP) {
7707
7708 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7709 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7710 if(pSapCtx == NULL){
7711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7712 FL("psapCtx is NULL"));
7713 return -ENOENT;
7714 }
7715
7716
7717 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7718 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7719 !vos_is_macaddr_broadcast(
7720 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7721 vos_mem_compare(
7722 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7723 peer_mac, VOS_MAC_ADDRESS_LEN))
7724 break;
7725 }
7726
7727 if (WLAN_MAX_STA_COUNT == sta_id) {
7728 hddLog(VOS_TRACE_LEVEL_ERROR,
7729 FL("No active peer with mac="MAC_ADDRESS_STR),
7730 MAC_ADDR_ARRAY(peer_mac));
7731 return -EINVAL;
7732 }
7733
7734 nss = 1; //pronto supports only one spatial stream
7735 freq = vos_chan_to_freq(
7736 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7737 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7738 } else {
7739 hddLog(VOS_TRACE_LEVEL_ERROR,
7740 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7741 MAC_ADDR_ARRAY(peer_mac));
7742 return -EINVAL;
7743 }
7744
7745 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7746 if (rate_flags & eHAL_TX_RATE_VHT80) {
7747 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307748#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7749 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307750 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307751#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307752 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7753 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307754#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7755 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307756 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307757#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307758 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7759 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7760 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7761 final_rate_flags |= RATE_INFO_FLAGS_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307762#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
7763 !defined(WITH_BACKPORTS)
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307764 if (rate_flags & eHAL_TX_RATE_HT40)
7765 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05307766#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307767 }
7768
7769 if (rate_flags & eHAL_TX_RATE_SGI) {
7770 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7771 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7772 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7773 }
7774 }
7775
7776 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7777 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7778
7779 if (NULL == reply_skb) {
7780 hddLog(VOS_TRACE_LEVEL_ERROR,
7781 FL("getLinkProperties: skb alloc failed"));
7782 return -EINVAL;
7783 }
7784
7785 if (nla_put_u8(reply_skb,
7786 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7787 nss) ||
7788 nla_put_u8(reply_skb,
7789 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7790 final_rate_flags) ||
7791 nla_put_u32(reply_skb,
7792 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7793 freq)) {
7794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7795 kfree_skb(reply_skb);
7796 return -EINVAL;
7797 }
7798
7799 return cfg80211_vendor_cmd_reply(reply_skb);
7800}
7801
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307802#define BEACON_MISS_THRESH_2_4 \
7803 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24
7804#define BEACON_MISS_THRESH_5_0 \
7805 QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307806#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7807#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7808#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7809#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307810#define PARAM_BCNMISS_PENALTY_PARAM_COUNT \
7811 QCA_WLAN_VENDOR_ATTR_CONFIG_PENALIZE_AFTER_NCONS_BEACON_MISS
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307812
7813/**
7814 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7815 * vendor command
7816 *
7817 * @wiphy: wiphy device pointer
7818 * @wdev: wireless device pointer
7819 * @data: Vendor command data buffer
7820 * @data_len: Buffer length
7821 *
7822 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7823 *
7824 * Return: EOK or other error codes.
7825 */
7826
7827static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7828 struct wireless_dev *wdev,
7829 const void *data,
7830 int data_len)
7831{
7832 struct net_device *dev = wdev->netdev;
7833 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7834 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7835 hdd_station_ctx_t *pHddStaCtx;
7836 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7837 tpSetWifiConfigParams pReq;
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307838 tModifyRoamParamsReqParams modifyRoamParamsReq;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307839 eHalStatus status;
7840 int ret_val;
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307841 uint8_t hb_thresh_val;
7842
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307843 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7844 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7845 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307846 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7847 [PARAM_BCNMISS_PENALTY_PARAM_COUNT] =
7848 { .type = NLA_U32},
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307849 [BEACON_MISS_THRESH_2_4] = { .type = NLA_U8 },
7850 [BEACON_MISS_THRESH_5_0] = { .type = NLA_U8 },
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307851 };
7852
7853 ENTER();
7854
7855 if (VOS_FTM_MODE == hdd_get_conparam()) {
7856 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7857 return -EINVAL;
7858 }
7859
7860 ret_val = wlan_hdd_validate_context(pHddCtx);
7861 if (ret_val) {
7862 return ret_val;
7863 }
7864
7865 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7866
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307867 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7868 hddLog(LOGE, FL("Invalid ATTR"));
7869 return -EINVAL;
7870 }
7871
7872 /* check the Wifi Capability */
7873 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7874 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7875 {
7876 hddLog(VOS_TRACE_LEVEL_ERROR,
7877 FL("WIFICONFIG not supported by Firmware"));
7878 return -EINVAL;
7879 }
7880
Mahesh A Saptasagar41f9ddd2016-02-09 14:01:03 +05307881 if (tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]) {
7882 modifyRoamParamsReq.param = WIFI_CONFIG_SET_BCNMISS_PENALTY_COUNT;
7883 modifyRoamParamsReq.value =
7884 nla_get_u32(tb[PARAM_BCNMISS_PENALTY_PARAM_COUNT]);
7885
7886 if (eHAL_STATUS_SUCCESS !=
7887 sme_setBcnMissPenaltyCount(pHddCtx->hHal,&modifyRoamParamsReq))
7888 {
7889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Failed", __func__);
7890 ret_val = -EINVAL;
7891 }
7892 return ret_val;
7893 }
7894
7895 /* Moved this down in order to provide provision to set beacon
7896 * miss penalty count irrespective of connection state.
7897 */
7898 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7899 hddLog(LOGE, FL("Not in Connected state!"));
7900 return -ENOTSUPP;
7901 }
7902
7903 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307904
7905 if (!pReq) {
7906 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7907 "%s: Not able to allocate memory for tSetWifiConfigParams",
7908 __func__);
7909 return eHAL_STATUS_E_MALLOC_FAILED;
7910 }
7911
7912 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7913
7914 pReq->sessionId = pAdapter->sessionId;
7915 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7916
7917 if (tb[PARAM_MODULATED_DTIM]) {
7918 pReq->paramValue = nla_get_u32(
7919 tb[PARAM_MODULATED_DTIM]);
7920 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7921 pReq->paramValue);
Arun Khandavalli876886f2015-11-23 11:42:27 +05307922 pHddCtx->cfg_ini->enableDynamicDTIM = pReq->paramValue;
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307923 hdd_set_pwrparams(pHddCtx);
7924 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7925 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7926
7927 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7928 iw_full_power_cbfn, pAdapter,
7929 eSME_FULL_PWR_NEEDED_BY_HDD);
7930 }
7931 else
7932 {
7933 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7934 }
7935 }
7936
7937 if (tb[PARAM_STATS_AVG_FACTOR]) {
7938 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7939 pReq->paramValue = nla_get_u16(
7940 tb[PARAM_STATS_AVG_FACTOR]);
7941 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7942 pReq->paramType, pReq->paramValue);
7943 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7944
7945 if (eHAL_STATUS_SUCCESS != status)
7946 {
7947 vos_mem_free(pReq);
7948 pReq = NULL;
7949 ret_val = -EPERM;
7950 return ret_val;
7951 }
7952 }
7953
7954
7955 if (tb[PARAM_GUARD_TIME]) {
7956 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7957 pReq->paramValue = nla_get_u32(
7958 tb[PARAM_GUARD_TIME]);
7959 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7960 pReq->paramType, pReq->paramValue);
7961 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7962
7963 if (eHAL_STATUS_SUCCESS != status)
7964 {
7965 vos_mem_free(pReq);
7966 pReq = NULL;
7967 ret_val = -EPERM;
7968 return ret_val;
7969 }
7970
7971 }
7972
Ravi Kumar bokka7d032762016-12-12 23:33:01 +05307973 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]) {
7974 hb_thresh_val = nla_get_u8(
7975 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_24]);
7976
7977 hddLog(LOG1, "WLAN set heartbeat threshold for 2.4Ghz %d",
7978 hb_thresh_val);
7979 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
7980 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
7981 NULL, eANI_BOOLEAN_FALSE);
7982
7983 status = sme_update_hb_threshold(
7984 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
7985 WNI_CFG_HEART_BEAT_THRESHOLD,
7986 hb_thresh_val, eCSR_BAND_24);
7987 if (eHAL_STATUS_SUCCESS != status) {
7988 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
7989 vos_mem_free(pReq);
7990 pReq = NULL;
7991 return -EPERM;
7992 }
7993 }
7994
7995 if (tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]) {
7996 hb_thresh_val = nla_get_u8(
7997 tb[QCA_WLAN_VENDOR_ATTR_CONFIG_BEACON_MISS_THRESHOLD_5]);
7998
7999 hddLog(LOG1, "WLAN set heartbeat threshold for 5Ghz %d",
8000 hb_thresh_val);
8001 ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal,
8002 WNI_CFG_HEART_BEAT_THRESHOLD, hb_thresh_val,
8003 NULL, eANI_BOOLEAN_FALSE);
8004
8005 status = sme_update_hb_threshold(
8006 (WLAN_HDD_GET_CTX(pAdapter))->hHal,
8007 WNI_CFG_HEART_BEAT_THRESHOLD,
8008 hb_thresh_val, eCSR_BAND_5G);
8009 if (eHAL_STATUS_SUCCESS != status) {
8010 hddLog(LOGE, "WLAN set heartbeat threshold FAILED %d", status);
8011 vos_mem_free(pReq);
8012 pReq = NULL;
8013 return -EPERM;
8014 }
8015 }
8016
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308017 EXIT();
8018 return ret_val;
8019}
8020
8021/**
8022 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
8023 * vendor command
8024 *
8025 * @wiphy: wiphy device pointer
8026 * @wdev: wireless device pointer
8027 * @data: Vendor command data buffer
8028 * @data_len: Buffer length
8029 *
8030 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
8031 *
8032 * Return: EOK or other error codes.
8033 */
8034static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
8035 struct wireless_dev *wdev,
8036 const void *data,
8037 int data_len)
8038{
8039 int ret;
8040
8041 vos_ssr_protect(__func__);
8042 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
8043 data, data_len);
8044 vos_ssr_unprotect(__func__);
8045
8046 return ret;
8047}
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308048
8049/*
8050 * define short names for the global vendor params
8051 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8052 */
8053#define STATS_SET_INVALID \
8054 QCA_ATTR_NUD_STATS_SET_INVALID
8055#define STATS_SET_START \
8056 QCA_ATTR_NUD_STATS_SET_START
8057#define STATS_GW_IPV4 \
8058 QCA_ATTR_NUD_STATS_GW_IPV4
8059#define STATS_SET_MAX \
8060 QCA_ATTR_NUD_STATS_SET_MAX
8061
8062const struct nla_policy
8063qca_wlan_vendor_set_nud_stats[STATS_SET_MAX +1] =
8064{
8065 [STATS_SET_START] = {.type = NLA_FLAG },
8066 [STATS_GW_IPV4] = {.type = NLA_U32 },
8067};
8068
8069/**
8070 * hdd_set_nud_stats_cb() - hdd callback api to get status
8071 * @data: pointer to adapter
8072 * @rsp: status
8073 *
8074 * Return: None
8075 */
8076static void hdd_set_nud_stats_cb(void *data, VOS_STATUS rsp)
8077{
8078
8079 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
8080
8081 if (NULL == adapter)
8082 return;
8083
8084 if (VOS_STATUS_SUCCESS == rsp) {
8085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8086 "%s success received STATS_SET_START", __func__);
8087 } else {
8088 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8089 "%s STATS_SET_START Failed!!", __func__);
8090 }
8091 return;
8092}
8093
8094/**
8095 * __wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8096 * @wiphy: pointer to wireless wiphy structure.
8097 * @wdev: pointer to wireless_dev structure.
8098 * @data: pointer to apfind configuration data.
8099 * @data_len: the length in byte of apfind data.
8100 *
8101 * This is called when wlan driver needs to send arp stats to
8102 * firmware.
8103 *
8104 * Return: An error code or 0 on success.
8105 */
8106static int __wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8107 struct wireless_dev *wdev,
8108 const void *data, int data_len)
8109{
8110 struct nlattr *tb[STATS_SET_MAX + 1];
8111 struct net_device *dev = wdev->netdev;
8112 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8113 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308114 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308115 setArpStatsParams arp_stats_params;
8116 int err = 0;
8117
8118 ENTER();
8119
8120 err = wlan_hdd_validate_context(hdd_ctx);
8121 if (0 != err)
8122 return err;
8123
8124 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8125 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8126 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8127 return -EINVAL;
8128 }
8129
8130 err = nla_parse(tb, STATS_SET_MAX, data, data_len,
8131 qca_wlan_vendor_set_nud_stats);
8132 if (err)
8133 {
8134 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8135 "%s STATS_SET_START ATTR", __func__);
8136 return err;
8137 }
8138
8139 if (tb[STATS_SET_START])
8140 {
8141 if (!tb[STATS_GW_IPV4]) {
8142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8143 "%s STATS_SET_START CMD", __func__);
8144 return -EINVAL;
8145 }
8146 arp_stats_params.flag = true;
8147 arp_stats_params.ip_addr = nla_get_u32(tb[STATS_GW_IPV4]);
8148 } else {
8149 arp_stats_params.flag = false;
8150 }
Anurag Chouhan630c5562017-03-23 14:51:47 +05308151 if (arp_stats_params.flag)
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8153 "%s STATS_SET_START Cleared!!", __func__);
Anurag Chouhan630c5562017-03-23 14:51:47 +05308154 vos_mem_zero(&adapter->hdd_stats.hddArpStats,
8155 sizeof(adapter->hdd_stats.hddArpStats));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308156
8157 arp_stats_params.pkt_type = 1; // ARP packet type
8158
Sravan Kumar Kairamd9e8cbb2017-01-17 12:17:28 +05308159 if (arp_stats_params.flag) {
8160 hdd_ctx->track_arp_ip = arp_stats_params.ip_addr;
8161 WLANTL_SetARPFWDatapath(pVosContext, true);
8162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8163 "%s Set FW in data path for ARP with tgt IP :%d",
8164 __func__, hdd_ctx->track_arp_ip);
8165 }
8166 else {
8167 WLANTL_SetARPFWDatapath(pVosContext, false);
8168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8169 "%s Remove FW from data path", __func__);
8170 }
8171
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308172 arp_stats_params.rsp_cb_fn = hdd_set_nud_stats_cb;
8173 arp_stats_params.data_ctx = adapter;
8174
8175 if (eHAL_STATUS_SUCCESS !=
8176 sme_set_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8178 "%s STATS_SET_START CMD Failed!!", __func__);
8179 return -EINVAL;
8180 }
8181
8182 EXIT();
8183
8184 return err;
8185}
8186
8187/**
8188 * wlan_hdd_cfg80211_set_nud_stats() - set arp stats command to firmware
8189 * @wiphy: pointer to wireless wiphy structure.
8190 * @wdev: pointer to wireless_dev structure.
8191 * @data: pointer to apfind configuration data.
8192 * @data_len: the length in byte of apfind data.
8193 *
8194 * This is called when wlan driver needs to send arp stats to
8195 * firmware.
8196 *
8197 * Return: An error code or 0 on success.
8198 */
8199static int wlan_hdd_cfg80211_set_nud_stats(struct wiphy *wiphy,
8200 struct wireless_dev *wdev,
8201 const void *data, int data_len)
8202{
8203 int ret;
8204
8205 vos_ssr_protect(__func__);
8206 ret = __wlan_hdd_cfg80211_set_nud_stats(wiphy, wdev, data, data_len);
8207 vos_ssr_unprotect(__func__);
8208
8209 return ret;
8210}
8211#undef STATS_SET_INVALID
8212#undef STATS_SET_START
8213#undef STATS_GW_IPV4
8214#undef STATS_SET_MAX
8215
8216/*
8217 * define short names for the global vendor params
8218 * used by wlan_hdd_cfg80211_setarp_stats_cmd()
8219 */
8220#define STATS_GET_INVALID \
8221 QCA_ATTR_NUD_STATS_SET_INVALID
8222#define COUNT_FROM_NETDEV \
8223 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8224#define COUNT_TO_LOWER_MAC \
8225 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8226#define RX_COUNT_BY_LOWER_MAC \
8227 QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8228#define COUNT_TX_SUCCESS \
8229 QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8230#define RSP_RX_COUNT_BY_LOWER_MAC \
8231 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8232#define RSP_RX_COUNT_BY_UPPER_MAC \
8233 QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8234#define RSP_COUNT_TO_NETDEV \
8235 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8236#define RSP_COUNT_OUT_OF_ORDER_DROP \
8237 QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8238#define AP_LINK_ACTIVE \
8239 QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8240#define AP_LINK_DAD \
8241 QCA_ATTR_NUD_STATS_AP_LINK_DAD
8242#define STATS_GET_MAX \
8243 QCA_ATTR_NUD_STATS_GET_MAX
8244
8245const struct nla_policy
8246qca_wlan_vendor_get_nud_stats[STATS_GET_MAX +1] =
8247{
8248 [COUNT_FROM_NETDEV] = {.type = NLA_U16 },
8249 [COUNT_TO_LOWER_MAC] = {.type = NLA_U16 },
8250 [RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8251 [COUNT_TX_SUCCESS] = {.type = NLA_U16 },
8252 [RSP_RX_COUNT_BY_LOWER_MAC] = {.type = NLA_U16 },
8253 [RSP_RX_COUNT_BY_UPPER_MAC] = {.type = NLA_U16 },
8254 [RSP_COUNT_TO_NETDEV] = {.type = NLA_U16 },
8255 [RSP_COUNT_OUT_OF_ORDER_DROP] = {.type = NLA_U16 },
8256 [AP_LINK_ACTIVE] = {.type = NLA_FLAG },
8257 [AP_LINK_DAD] = {.type = NLA_FLAG },
8258};
8259
8260static void hdd_get_nud_stats_cb(void *data, rsp_stats *rsp)
8261{
8262
8263 hdd_adapter_t *adapter = (hdd_adapter_t *)data;
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308264 hdd_context_t *hdd_ctx;
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308265 struct hdd_nud_stats_context *context;
8266 int status;
8267
8268 ENTER();
8269
8270 if (NULL == adapter)
8271 return;
8272
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308273 if (!rsp) {
8274 hddLog(LOGE, FL("data is null"));
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308275 return;
8276 }
8277
Hanumanth Reddy Pothula8f528c72018-02-26 16:49:25 +05308278 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
8279 status = wlan_hdd_validate_context(hdd_ctx);
8280 if (0 != status) {
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308281 return;
8282 }
8283
8284 adapter->hdd_stats.hddArpStats.tx_fw_cnt = rsp->tx_fw_cnt;
8285 adapter->hdd_stats.hddArpStats.rx_fw_cnt = rsp->rx_fw_cnt;
8286 adapter->hdd_stats.hddArpStats.tx_ack_cnt = rsp->tx_ack_cnt;
8287 adapter->dad |= rsp->dad;
8288
8289 spin_lock(&hdd_context_lock);
8290 context = &hdd_ctx->nud_stats_context;
8291 complete(&context->response_event);
8292 spin_unlock(&hdd_context_lock);
8293
8294 return;
8295}
8296static int __wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8297 struct wireless_dev *wdev,
8298 const void *data, int data_len)
8299{
8300 int err = 0;
8301 unsigned long rc;
8302 struct hdd_nud_stats_context *context;
8303 struct net_device *dev = wdev->netdev;
8304 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
8305 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8306 getArpStatsParams arp_stats_params;
8307 struct sk_buff *skb;
8308
8309 ENTER();
8310
8311 err = wlan_hdd_validate_context(hdd_ctx);
8312 if (0 != err)
8313 return err;
8314
8315 arp_stats_params.pkt_type = WLAN_NUD_STATS_ARP_PKT_TYPE;
8316 arp_stats_params.get_rsp_cb_fn = hdd_get_nud_stats_cb;
8317 arp_stats_params.data_ctx = adapter;
8318
8319 spin_lock(&hdd_context_lock);
8320 context = &hdd_ctx->nud_stats_context;
8321 INIT_COMPLETION(context->response_event);
8322 spin_unlock(&hdd_context_lock);
8323
8324 if (!sme_IsFeatureSupportedByFW(NUD_DEBUG)) {
8325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8326 "%s NUD_DEBUG feature not supported by firmware!!", __func__);
8327 return -EINVAL;
8328 }
8329
8330 if (eHAL_STATUS_SUCCESS !=
8331 sme_get_nud_debug_stats(hdd_ctx->hHal, &arp_stats_params)) {
8332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8333 "%s STATS_SET_START CMD Failed!!", __func__);
8334 return -EINVAL;
8335 }
8336
8337 rc = wait_for_completion_timeout(&context->response_event,
8338 msecs_to_jiffies(WLAN_WAIT_TIME_NUD_STATS));
8339 if (!rc)
8340 {
8341 hddLog(LOGE,
8342 FL("Target response timed out request "));
8343 return -ETIMEDOUT;
8344 }
8345
8346 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
8347 WLAN_NUD_STATS_LEN);
8348 if (!skb)
8349 {
8350 hddLog(VOS_TRACE_LEVEL_ERROR,
8351 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
8352 __func__);
8353 return -ENOMEM;
8354 }
8355
8356 if (nla_put_u16(skb, COUNT_FROM_NETDEV,
8357 adapter->hdd_stats.hddArpStats.txCount) ||
8358 nla_put_u16(skb, COUNT_TO_LOWER_MAC,
8359 adapter->hdd_stats.hddArpStats.tx_host_fw_sent) ||
8360 nla_put_u16(skb, RX_COUNT_BY_LOWER_MAC,
8361 adapter->hdd_stats.hddArpStats.tx_fw_cnt) ||
8362 nla_put_u16(skb, COUNT_TX_SUCCESS,
8363 adapter->hdd_stats.hddArpStats.tx_ack_cnt) ||
8364 nla_put_u16(skb, RSP_RX_COUNT_BY_LOWER_MAC,
8365 adapter->hdd_stats.hddArpStats.rx_fw_cnt) ||
8366 nla_put_u16(skb, RSP_RX_COUNT_BY_UPPER_MAC,
8367 adapter->hdd_stats.hddArpStats.rxCount) ||
8368 nla_put_u16(skb, RSP_COUNT_TO_NETDEV,
8369 adapter->hdd_stats.hddArpStats.rxDelivered) ||
8370 nla_put_u16(skb, RSP_COUNT_OUT_OF_ORDER_DROP,
8371 adapter->hdd_stats.hddArpStats.rx_host_drop_reorder)) {
8372 hddLog(LOGE, FL("nla put fail"));
8373 kfree_skb(skb);
8374 return -EINVAL;
8375 }
8376 if (adapter->con_status)
8377 nla_put_flag(skb, AP_LINK_ACTIVE);
8378 if (adapter->dad)
8379 nla_put_flag(skb, AP_LINK_DAD);
8380
8381 cfg80211_vendor_cmd_reply(skb);
8382 return err;
8383}
8384
8385static int wlan_hdd_cfg80211_get_nud_stats(struct wiphy *wiphy,
8386 struct wireless_dev *wdev,
8387 const void *data, int data_len)
8388{
8389 int ret;
8390
8391 vos_ssr_protect(__func__);
8392 ret = __wlan_hdd_cfg80211_get_nud_stats(wiphy, wdev, data, data_len);
8393 vos_ssr_unprotect(__func__);
8394
8395 return ret;
8396}
8397
8398#undef QCA_ATTR_NUD_STATS_SET_INVALID
8399#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_FROM_NETDEV
8400#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TO_LOWER_MAC
8401#undef QCA_ATTR_NUD_STATS_ARP_REQ_RX_COUNT_BY_LOWER_MAC
8402#undef QCA_ATTR_NUD_STATS_ARP_REQ_COUNT_TX_SUCCESS
8403#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_LOWER_MAC
8404#undef QCA_ATTR_NUD_STATS_ARP_RSP_RX_COUNT_BY_UPPER_MAC
8405#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_TO_NETDEV
8406#undef QCA_ATTR_NUD_STATS_ARP_RSP_COUNT_OUT_OF_ORDER_DROP
8407#undef QCA_ATTR_NUD_STATS_AP_LINK_ACTIVE
8408#undef QCA_ATTR_NUD_STATS_GET_MAX
8409
8410
8411
Kapil Guptaee33bf12016-12-20 18:27:37 +05308412#ifdef WLAN_FEATURE_APFIND
8413/**
8414 * __wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8415 * @wiphy: pointer to wireless wiphy structure.
8416 * @wdev: pointer to wireless_dev structure.
8417 * @data: pointer to apfind configuration data.
8418 * @data_len: the length in byte of apfind data.
8419 *
8420 * This is called when wlan driver needs to send APFIND configurations to
8421 * firmware.
8422 *
8423 * Return: An error code or 0 on success.
8424 */
8425static int __wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8426 struct wireless_dev *wdev,
8427 const void *data, int data_len)
8428{
8429 struct sme_ap_find_request_req apfind_req;
8430 VOS_STATUS status;
8431 int ret_val;
8432 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
8433
8434 ENTER();
8435
8436 ret_val = wlan_hdd_validate_context(hdd_ctx);
8437 if (ret_val)
8438 return ret_val;
8439
8440 if (VOS_FTM_MODE == hdd_get_conparam()) {
8441 hddLog(LOGE, FL("Command not allowed in FTM mode"));
8442 return -EPERM;
8443 }
8444
8445 apfind_req.request_data_len = data_len;
8446 apfind_req.request_data = data;
8447
8448 status = sme_apfind_set_cmd(&apfind_req);
8449 if (VOS_STATUS_SUCCESS != status) {
8450 ret_val = -EIO;
8451 }
8452 return ret_val;
8453}
8454
8455/**
8456 * wlan_hdd_cfg80211_apfind_cmd() - set configuration to firmware
8457 * @wiphy: pointer to wireless wiphy structure.
8458 * @wdev: pointer to wireless_dev structure.
8459 * @data: pointer to apfind configuration data.
8460 * @data_len: the length in byte of apfind data.
8461 *
8462 * This is called when wlan driver needs to send APFIND configurations to
8463 * firmware.
8464 *
8465 * Return: An error code or 0 on success.
8466 */
8467static int wlan_hdd_cfg80211_apfind_cmd(struct wiphy *wiphy,
8468 struct wireless_dev *wdev,
8469 const void *data, int data_len)
8470{
8471 int ret;
8472
8473 vos_ssr_protect(__func__);
8474 ret = __wlan_hdd_cfg80211_apfind_cmd(wiphy, wdev, data, data_len);
8475 vos_ssr_unprotect(__func__);
8476
8477 return ret;
8478}
8479#endif /* WLAN_FEATURE_APFIND */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308480const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
8481{
Mukul Sharma2a271632014-10-13 14:59:01 +05308482 {
8483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
8485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8486 WIPHY_VENDOR_CMD_NEED_NETDEV |
8487 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308488 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05308489 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05308490
8491 {
8492 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8493 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
8494 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8495 WIPHY_VENDOR_CMD_NEED_NETDEV |
8496 WIPHY_VENDOR_CMD_NEED_RUNNING,
8497 .doit = wlan_hdd_cfg80211_nan_request
8498 },
8499
Sunil Duttc69bccb2014-05-26 21:30:20 +05308500#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8501 {
8502 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8503 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
8504 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8505 WIPHY_VENDOR_CMD_NEED_NETDEV |
8506 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308507 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05308508 },
8509
8510 {
8511 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8512 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
8513 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8514 WIPHY_VENDOR_CMD_NEED_NETDEV |
8515 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308516 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05308517 },
8518
8519 {
8520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
8522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8523 WIPHY_VENDOR_CMD_NEED_NETDEV |
8524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308525 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05308526 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308527#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308528#ifdef WLAN_FEATURE_EXTSCAN
8529 {
8530 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8531 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
8532 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8533 WIPHY_VENDOR_CMD_NEED_NETDEV |
8534 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308535 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05308536 },
8537 {
8538 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8539 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
8540 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8541 WIPHY_VENDOR_CMD_NEED_NETDEV |
8542 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308543 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05308544 },
8545 {
8546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
8548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8549 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308550 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05308551 },
8552 {
8553 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8554 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
8555 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8556 WIPHY_VENDOR_CMD_NEED_NETDEV |
8557 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308558 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05308559 },
8560 {
8561 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8562 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
8563 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8564 WIPHY_VENDOR_CMD_NEED_NETDEV |
8565 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308566 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05308567 },
8568 {
8569 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8570 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
8571 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8572 WIPHY_VENDOR_CMD_NEED_NETDEV |
8573 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308574 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308575 },
8576 {
8577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
8579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8580 WIPHY_VENDOR_CMD_NEED_NETDEV |
8581 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308582 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05308583 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308584#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308585/*EXT TDLS*/
8586 {
8587 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8588 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
8589 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8590 WIPHY_VENDOR_CMD_NEED_NETDEV |
8591 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308592 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05308593 },
8594 {
8595 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8596 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
8597 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8598 WIPHY_VENDOR_CMD_NEED_NETDEV |
8599 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308600 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05308601 },
8602 {
8603 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8604 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
8605 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8606 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308607 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05308608 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05308609 {
8610 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8611 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
8612 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8613 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308614 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05308615 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05308616 {
8617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
8619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8620 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308621 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05308622 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308623 {
8624 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8625 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
8626 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8627 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308628 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05308629 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308630 {
8631 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8632 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
8633 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8634 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05308635 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05308636 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308637 {
8638 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05308639 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
8640 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8641 WIPHY_VENDOR_CMD_NEED_NETDEV |
8642 WIPHY_VENDOR_CMD_NEED_RUNNING,
8643 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
8644 },
8645 {
8646 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05308647 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
8648 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8649 WIPHY_VENDOR_CMD_NEED_NETDEV |
8650 WIPHY_VENDOR_CMD_NEED_RUNNING,
8651 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05308652 },
8653 {
8654 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8655 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
8656 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8657 WIPHY_VENDOR_CMD_NEED_NETDEV,
8658 .doit = wlan_hdd_cfg80211_wifi_logger_start
8659 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05308660 {
8661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
8663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8664 WIPHY_VENDOR_CMD_NEED_NETDEV|
8665 WIPHY_VENDOR_CMD_NEED_RUNNING,
8666 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05308667 },
8668 {
8669 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8670 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
8671 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8672 WIPHY_VENDOR_CMD_NEED_NETDEV |
8673 WIPHY_VENDOR_CMD_NEED_RUNNING,
8674 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308675 },
8676 {
8677 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8678 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
8679 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8680 WIPHY_VENDOR_CMD_NEED_NETDEV |
8681 WIPHY_VENDOR_CMD_NEED_RUNNING,
8682 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308683 },
8684#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
8685 {
8686 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8687 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
8688 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8689 WIPHY_VENDOR_CMD_NEED_NETDEV |
8690 WIPHY_VENDOR_CMD_NEED_RUNNING,
8691 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308692 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05308693#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05308694 {
8695 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8696 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8697 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8698 WIPHY_VENDOR_CMD_NEED_NETDEV |
8699 WIPHY_VENDOR_CMD_NEED_RUNNING,
8700 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05308701 },
8702 {
8703 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8704 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
8705 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8706 WIPHY_VENDOR_CMD_NEED_NETDEV |
8707 WIPHY_VENDOR_CMD_NEED_RUNNING,
8708 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Kapil Guptaee33bf12016-12-20 18:27:37 +05308709 },
8710#ifdef WLAN_FEATURE_APFIND
8711 {
8712 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8713 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_APFIND,
8714 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8715 WIPHY_VENDOR_CMD_NEED_NETDEV,
8716 .doit = wlan_hdd_cfg80211_apfind_cmd
8717 },
8718#endif /* WLAN_FEATURE_APFIND */
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308719 {
8720 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8721 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_SET,
8722 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8723 WIPHY_VENDOR_CMD_NEED_NETDEV |
8724 WIPHY_VENDOR_CMD_NEED_RUNNING,
8725 .doit = wlan_hdd_cfg80211_set_nud_stats
8726 },
8727 {
8728 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8729 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8730 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8731 WIPHY_VENDOR_CMD_NEED_NETDEV |
8732 WIPHY_VENDOR_CMD_NEED_RUNNING,
8733 .doit = wlan_hdd_cfg80211_get_nud_stats
8734 },
Anurag Chouhanfcd20172017-07-19 17:25:19 +05308735 {
8736 .info.vendor_id = QCA_NL80211_VENDOR_ID,
8737 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_STATION,
8738 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
8739 WIPHY_VENDOR_CMD_NEED_NETDEV |
8740 WIPHY_VENDOR_CMD_NEED_RUNNING,
8741 .doit = hdd_cfg80211_get_station_cmd
8742 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308743};
8744
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008745/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05308746static const
8747struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008748{
8749#ifdef FEATURE_WLAN_CH_AVOID
8750 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05308751 .vendor_id = QCA_NL80211_VENDOR_ID,
8752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008753 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05308754#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
8755#ifdef WLAN_FEATURE_LINK_LAYER_STATS
8756 {
8757 /* Index = 1*/
8758 .vendor_id = QCA_NL80211_VENDOR_ID,
8759 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
8760 },
8761 {
8762 /* Index = 2*/
8763 .vendor_id = QCA_NL80211_VENDOR_ID,
8764 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
8765 },
8766 {
8767 /* Index = 3*/
8768 .vendor_id = QCA_NL80211_VENDOR_ID,
8769 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
8770 },
8771 {
8772 /* Index = 4*/
8773 .vendor_id = QCA_NL80211_VENDOR_ID,
8774 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
8775 },
8776 {
8777 /* Index = 5*/
8778 .vendor_id = QCA_NL80211_VENDOR_ID,
8779 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
8780 },
8781 {
8782 /* Index = 6*/
8783 .vendor_id = QCA_NL80211_VENDOR_ID,
8784 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
8785 },
8786#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05308787#ifdef WLAN_FEATURE_EXTSCAN
8788 {
8789 .vendor_id = QCA_NL80211_VENDOR_ID,
8790 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
8791 },
8792 {
8793 .vendor_id = QCA_NL80211_VENDOR_ID,
8794 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
8795 },
8796 {
8797 .vendor_id = QCA_NL80211_VENDOR_ID,
8798 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
8799 },
8800 {
8801 .vendor_id = QCA_NL80211_VENDOR_ID,
8802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
8803 },
8804 {
8805 .vendor_id = QCA_NL80211_VENDOR_ID,
8806 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
8807 },
8808 {
8809 .vendor_id = QCA_NL80211_VENDOR_ID,
8810 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
8811 },
8812 {
8813 .vendor_id = QCA_NL80211_VENDOR_ID,
8814 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
8815 },
8816 {
8817 .vendor_id = QCA_NL80211_VENDOR_ID,
8818 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
8819 },
8820 {
8821 .vendor_id = QCA_NL80211_VENDOR_ID,
8822 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
8823 },
8824 {
8825 .vendor_id = QCA_NL80211_VENDOR_ID,
8826 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
8827 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05308828#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05308829/*EXT TDLS*/
8830 {
8831 .vendor_id = QCA_NL80211_VENDOR_ID,
8832 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
8833 },
c_manjeecfd1efb2015-09-25 19:32:34 +05308834 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
8835 .vendor_id = QCA_NL80211_VENDOR_ID,
8836 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
8837 },
8838
Srinivas Dasari030bad32015-02-18 23:23:54 +05308839
Srinivas Dasaribd1cf642017-01-23 14:54:41 +05308840 [QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX] = {
Srinivas Dasari030bad32015-02-18 23:23:54 +05308841 .vendor_id = QCA_NL80211_VENDOR_ID,
8842 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
8843 },
8844
Sushant Kaushik084f6592015-09-10 13:11:56 +05308845 {
8846 .vendor_id = QCA_NL80211_VENDOR_ID,
8847 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05308848 },
8849 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
8850 .vendor_id = QCA_NL80211_VENDOR_ID,
8851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
8852 },
Padma, Santhosh Kumar7bbc7d92015-12-08 20:23:19 +05308853 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX] = {
8854 .vendor_id = QCA_NL80211_VENDOR_ID,
8855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST
8856 },
Anurag Chouhan6ee81542017-02-09 18:09:27 +05308857 [QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET_INDEX] = {
8858 .vendor_id = QCA_NL80211_VENDOR_ID,
8859 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NUD_STATS_GET,
8860 },
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +05308861 [QCA_NL80211_VENDOR_SUBCMD_HANG_REASON_INDEX] = {
8862 .vendor_id = QCA_NL80211_VENDOR_ID,
8863 .subcmd = QCA_NL80211_VENDOR_SUBCMD_HANG,
8864 },
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +05308865 [QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX] = {
8866 .vendor_id = QCA_NL80211_VENDOR_ID,
8867 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
8868 },
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008869};
8870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308872 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308873 * This function is called by hdd_wlan_startup()
8874 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308875 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308877struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07008878{
8879 struct wiphy *wiphy;
8880 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881 /*
8882 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07008883 */
8884 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
8885
8886 if (!wiphy)
8887 {
8888 /* Print error and jump into err label and free the memory */
8889 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
8890 return NULL;
8891 }
8892
Sunil Duttc69bccb2014-05-26 21:30:20 +05308893
Jeff Johnson295189b2012-06-20 16:38:30 -07008894 return wiphy;
8895}
8896
Anurag Chouhan343af7e2016-12-16 13:11:19 +05308897#if (LINUX_VERSION_CODE > KERNEL_VERSION(4,4,0)) || \
8898 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
8899/**
8900 * hdd_config_sched_scan_plans_to_wiphy() - configure sched scan plans to wiphy
8901 * @wiphy: pointer to wiphy
8902 * @config: pointer to config
8903 *
8904 * Return: None
8905 */
8906static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8907 hdd_config_t *config)
8908{
8909 wiphy->max_sched_scan_plans = MAX_SCHED_SCAN_PLANS;
8910 if (config->max_sched_scan_plan_interval)
8911 wiphy->max_sched_scan_plan_interval =
8912 config->max_sched_scan_plan_interval;
8913 if (config->max_sched_scan_plan_iterations)
8914 wiphy->max_sched_scan_plan_iterations =
8915 config->max_sched_scan_plan_iterations;
8916}
8917#else
8918static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy,
8919 hdd_config_t *config)
8920{
8921}
8922#endif
8923
Jeff Johnson295189b2012-06-20 16:38:30 -07008924/*
8925 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308926 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07008927 * private ioctl to change the band value
8928 */
8929int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
8930{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308931 int i, j;
8932 eNVChannelEnabledType channelEnabledState;
8933
Jeff Johnsone7245742012-09-05 17:12:55 -07008934 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308935
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308936 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008937 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308938
8939 if (NULL == wiphy->bands[i])
8940 {
8941 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
8942 __func__, i);
8943 continue;
8944 }
8945
8946 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8947 {
8948 struct ieee80211_supported_band *band = wiphy->bands[i];
8949
8950 channelEnabledState = vos_nv_getChannelEnabledState(
8951 band->channels[j].hw_value);
8952
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308953 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308954 {
Abhishek Singh678227a2014-11-04 10:52:38 +05308955 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308956 continue;
8957 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05308958 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308959 {
8960 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8961 continue;
8962 }
8963
8964 if (NV_CHANNEL_DISABLE == channelEnabledState ||
8965 NV_CHANNEL_INVALID == channelEnabledState)
8966 {
8967 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8968 }
8969 else if (NV_CHANNEL_DFS == channelEnabledState)
8970 {
8971 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8972 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
8973 }
8974 else
8975 {
8976 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
8977 |IEEE80211_CHAN_RADAR);
8978 }
8979 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008980 }
8981 return 0;
8982}
8983/*
8984 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308985 * This function is called by hdd_wlan_startup()
8986 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07008987 * This function is used to initialize and register wiphy structure.
8988 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308989int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008990 struct wiphy *wiphy,
8991 hdd_config_t *pCfg
8992 )
8993{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308994 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05308995 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8996
Jeff Johnsone7245742012-09-05 17:12:55 -07008997 ENTER();
8998
Jeff Johnson295189b2012-06-20 16:38:30 -07008999 /* Now bind the underlying wlan device with wiphy */
9000 set_wiphy_dev(wiphy, dev);
9001
9002 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009003
Kiet Lam6c583332013-10-14 05:37:09 +05309004#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07009005 /* the flag for the other case would be initialzed in
9006 vos_init_wiphy_from_nv_bin */
Manjeet Singh9e19de62016-08-18 18:26:41 +05309007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9008 wiphy->regulatory_flags |= REGULATORY_STRICT_REG;
9009#else
Amar Singhal0a402232013-10-11 20:57:16 -07009010 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05309011#endif
Manjeet Singh9e19de62016-08-18 18:26:41 +05309012#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009013
Amar Singhalfddc28c2013-09-05 13:03:40 -07009014 /* This will disable updating of NL channels from passive to
9015 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309016#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
9017 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
9018#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07009019 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309020#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07009021
Amar Singhala49cbc52013-10-08 18:37:44 -07009022
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07009024 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
9025 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
9026 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07009027 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309028#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Rajeev Kumar Sirasanagandla0d6dd752016-08-17 15:01:39 +05309029 wiphy->regulatory_flags |= REGULATORY_COUNTRY_IE_IGNORE;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05309030#else
9031 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
9032#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009033#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07009034
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009035#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009036 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08009037#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009038 || pCfg->isFastRoamIniFeatureEnabled
9039#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009040#ifdef FEATURE_WLAN_ESE
9041 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07009042#endif
9043 )
9044 {
9045 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
9046 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08009047#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009048#ifdef FEATURE_WLAN_TDLS
9049 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
9050 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
9051#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309052#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05309053 if (pCfg->configPNOScanSupport)
9054 {
9055 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9056 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
9057 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
9058 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
9059 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309060#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009061
Abhishek Singh10d85972015-04-17 10:27:23 +05309062#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9063 wiphy->features |= NL80211_FEATURE_HT_IBSS;
9064#endif
9065
Amar Singhalfddc28c2013-09-05 13:03:40 -07009066#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009067 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
9068 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07009069 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07009070 driver need to determine what to do with both
9071 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07009072
9073 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07009074#else
9075 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07009076#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009077
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309078 wiphy->max_scan_ssids = MAX_SCAN_SSID;
9079
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05309080 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07009081
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309082 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
9083
Jeff Johnson295189b2012-06-20 16:38:30 -07009084 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05309085 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9086 | BIT(NL80211_IFTYPE_ADHOC)
9087 | BIT(NL80211_IFTYPE_P2P_CLIENT)
9088 | BIT(NL80211_IFTYPE_P2P_GO)
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309089 | BIT(NL80211_IFTYPE_AP)
9090 | BIT(NL80211_IFTYPE_MONITOR);
Jeff Johnson295189b2012-06-20 16:38:30 -07009091
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309092 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009093 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309094#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
9095 if( pCfg->enableMCC )
9096 {
9097 /* Currently, supports up to two channels */
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309098 wlan_hdd_iface_combination[0].num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009099
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309100 if( !pCfg->allowMCCGODiffBI )
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309101 wlan_hdd_iface_combination[0].beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009102
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309103 }
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +05309104 wiphy->iface_combinations = wlan_hdd_iface_combination;
9105 wiphy->n_iface_combinations = ARRAY_SIZE(wlan_hdd_iface_combination);
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009106#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05309107 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08009108
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 /* Before registering we need to update the ht capabilitied based
9110 * on ini values*/
9111 if( !pCfg->ShortGI20MhzEnable )
9112 {
9113 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
9114 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
Jeff Johnson295189b2012-06-20 16:38:30 -07009115 }
9116
9117 if( !pCfg->ShortGI40MhzEnable )
9118 {
9119 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
9120 }
9121
9122 if( !pCfg->nChannelBondingMode5GHz )
9123 {
9124 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
9125 }
Agrawal Ashish97dec502015-11-26 20:20:58 +05309126 /*
9127 * In case of static linked driver at the time of driver unload,
9128 * module exit doesn't happens. Module cleanup helps in cleaning
9129 * of static memory.
9130 * If driver load happens statically, at the time of driver unload,
9131 * wiphy flags don't get reset because of static memory.
9132 * It's better not to store channel in static memory.
9133 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309134 wiphy->bands[HDD_NL80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
9135 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309136 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_2_4_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309137 if (wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309138 {
9139 hddLog(VOS_TRACE_LEVEL_ERROR,
9140 FL("Not enough memory to allocate channels"));
9141 return -ENOMEM;
9142 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309143 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309144 &hdd_channels_2_4_GHZ[0],
9145 sizeof(hdd_channels_2_4_GHZ));
Jeff Johnson295189b2012-06-20 16:38:30 -07009146
Agrawal Ashish97dec502015-11-26 20:20:58 +05309147 if (true == hdd_is_5g_supported(pHddCtx))
9148 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309149 wiphy->bands[HDD_NL80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
9150 wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels =
Agrawal Ashish97dec502015-11-26 20:20:58 +05309151 (struct ieee80211_channel *)vos_mem_malloc(sizeof(hdd_channels_5_GHZ));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309152 if (wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels == NULL)
Agrawal Ashish97dec502015-11-26 20:20:58 +05309153 {
9154 hddLog(VOS_TRACE_LEVEL_ERROR,
9155 FL("Not enough memory to allocate channels"));
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309156 vos_mem_free(wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels);
9157 wiphy->bands[HDD_NL80211_BAND_2GHZ]->channels = NULL;
Agrawal Ashish97dec502015-11-26 20:20:58 +05309158 return -ENOMEM;
9159 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309160 vos_mem_copy(wiphy->bands[HDD_NL80211_BAND_5GHZ]->channels,
Agrawal Ashish97dec502015-11-26 20:20:58 +05309161 &hdd_channels_5_GHZ[0],
9162 sizeof(hdd_channels_5_GHZ));
9163 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309164
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309165 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309166 {
9167
9168 if (NULL == wiphy->bands[i])
9169 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05309170 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309171 __func__, i);
9172 continue;
9173 }
9174
9175 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9176 {
9177 struct ieee80211_supported_band *band = wiphy->bands[i];
9178
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309179 if (HDD_NL80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309180 {
9181 // Enable social channels for P2P
9182 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
9183 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
9184 else
9185 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9186 continue;
9187 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309188 else if (HDD_NL80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05309189 {
9190 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
9191 continue;
9192 }
9193 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009194 }
9195 /*Initialise the supported cipher suite details*/
9196 wiphy->cipher_suites = hdd_cipher_suites;
9197 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
9198
9199 /*signal strength in mBm (100*dBm) */
9200 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9201
9202#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05309203 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07009204#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009205
Sunil Duttc69bccb2014-05-26 21:30:20 +05309206 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
9207 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08009208 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
9209 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
9210
Anurag Chouhan343af7e2016-12-16 13:11:19 +05309211 hdd_config_sched_scan_plans_to_wiphy(wiphy, pCfg);
9212
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309213 EXIT();
9214 return 0;
9215}
9216
9217/* In this function we are registering wiphy. */
9218int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
9219{
9220 ENTER();
9221 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 if (0 > wiphy_register(wiphy))
9223 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309224 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
9226 return -EIO;
9227 }
9228
9229 EXIT();
9230 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309231}
Jeff Johnson295189b2012-06-20 16:38:30 -07009232
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309233/* In this function we are updating channel list when,
9234 regulatory domain is FCC and country code is US.
9235 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
9236 As per FCC smart phone is not a indoor device.
9237 GO should not opeate on indoor channels */
9238void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
9239{
9240 int j;
9241 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9242 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
9243 //Default counrtycode from NV at the time of wiphy initialization.
9244 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
9245 &defaultCountryCode[0]))
9246 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009247 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309248 }
9249 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
9250 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309251 if (NULL == wiphy->bands[HDD_NL80211_BAND_5GHZ])
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309252 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309253 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[HDD_NL80211_BAND_5GHZ] is NULL",__func__ );
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309254 return;
9255 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309256 for (j = 0; j < wiphy->bands[HDD_NL80211_BAND_5GHZ]->n_channels; j++)
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309257 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +05309258 struct ieee80211_supported_band *band = wiphy->bands[HDD_NL80211_BAND_5GHZ];
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05309259 // Mark UNII -1 band channel as passive
9260 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
9261 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
9262 }
9263 }
9264}
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309265/* This function registers for all frame which supplicant is interested in */
9266void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009267{
Jeff Johnson295189b2012-06-20 16:38:30 -07009268 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9269 /* Register for all P2P action, public action etc frames */
9270 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
Jeff Johnsone7245742012-09-05 17:12:55 -07009271 ENTER();
Abhishek Singh16e05762015-11-30 14:29:27 +05309272 /* Register frame indication call back */
9273 sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame);
Jeff Johnson295189b2012-06-20 16:38:30 -07009274 /* Right now we are registering these frame when driver is getting
9275 initialized. Once we will move to 2.6.37 kernel, in which we have
9276 frame register ops, we will move this code as a part of that */
9277 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309278 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9280
9281 /* GAS Initial Response */
9282 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9283 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309284
Jeff Johnson295189b2012-06-20 16:38:30 -07009285 /* GAS Comeback Request */
9286 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9287 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9288
9289 /* GAS Comeback Response */
9290 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9291 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9292
9293 /* P2P Public Action */
9294 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309295 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 P2P_PUBLIC_ACTION_FRAME_SIZE );
9297
9298 /* P2P Action */
9299 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9300 (v_U8_t*)P2P_ACTION_FRAME,
9301 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07009302
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05309303 /* WNM BSS Transition Request frame */
9304 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9305 (v_U8_t*)WNM_BSS_ACTION_FRAME,
9306 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009307
9308 /* WNM-Notification */
9309 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
9310 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9311 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009312}
9313
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05309314void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009315{
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9317 /* Register for all P2P action, public action etc frames */
9318 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
9319
Jeff Johnsone7245742012-09-05 17:12:55 -07009320 ENTER();
9321
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 /* Right now we are registering these frame when driver is getting
9323 initialized. Once we will move to 2.6.37 kernel, in which we have
9324 frame register ops, we will move this code as a part of that */
9325 /* GAS Initial Request */
9326
9327 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9328 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
9329
9330 /* GAS Initial Response */
9331 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9332 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309333
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 /* GAS Comeback Request */
9335 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9336 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
9337
9338 /* GAS Comeback Response */
9339 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9340 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
9341
9342 /* P2P Public Action */
9343 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309344 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 P2P_PUBLIC_ACTION_FRAME_SIZE );
9346
9347 /* P2P Action */
9348 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9349 (v_U8_t*)P2P_ACTION_FRAME,
9350 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07009351 /* WNM-Notification */
9352 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
9353 (v_U8_t*)WNM_NOTIFICATION_FRAME,
9354 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07009355}
9356
9357#ifdef FEATURE_WLAN_WAPI
9358void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05309359 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07009360{
9361 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9362 tCsrRoamSetKey setKey;
9363 v_BOOL_t isConnected = TRUE;
9364 int status = 0;
9365 v_U32_t roamId= 0xFF;
9366 tANI_U8 *pKeyPtr = NULL;
9367 int n = 0;
9368
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309369 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
9370 __func__, hdd_device_modetoString(pAdapter->device_mode),
9371 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009372
Gopichand Nakkalae7480202013-02-11 15:24:22 +05309373 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 setKey.keyId = key_index; // Store Key ID
9375 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
9376 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
9377 setKey.paeRole = 0 ; // the PAE role
9378 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9379 {
9380 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
9381 }
9382 else
9383 {
9384 isConnected = hdd_connIsConnected(pHddStaCtx);
9385 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
9386 }
9387 setKey.keyLength = key_Len;
9388 pKeyPtr = setKey.Key;
9389 memcpy( pKeyPtr, key, key_Len);
9390
Arif Hussain6d2a3322013-11-17 19:50:10 -08009391 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07009392 __func__, key_Len);
9393 for (n = 0 ; n < key_Len; n++)
9394 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
9395 __func__,n,setKey.Key[n]);
9396
9397 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9398 if ( isConnected )
9399 {
9400 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9401 pAdapter->sessionId, &setKey, &roamId );
9402 }
9403 if ( status != 0 )
9404 {
9405 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9406 "[%4d] sme_RoamSetKey returned ERROR status= %d",
9407 __LINE__, status );
9408 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9409 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309410 /* Need to clear any trace of key value in the memory.
9411 * Thus zero out the memory even though it is local
9412 * variable.
9413 */
9414 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07009415}
9416#endif /* FEATURE_WLAN_WAPI*/
9417
9418#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309419int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07009420 beacon_data_t **ppBeacon,
9421 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009422#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009424 beacon_data_t **ppBeacon,
9425 struct cfg80211_beacon_data *params,
9426 int dtim_period)
9427#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309428{
Jeff Johnson295189b2012-06-20 16:38:30 -07009429 int size;
9430 beacon_data_t *beacon = NULL;
9431 beacon_data_t *old = NULL;
Kapil Gupta137ef892016-12-13 19:38:00 +05309432 int head_len, tail_len, proberesp_ies_len, assocresp_ies_len;
9433 const u8 *head, *tail, *proberesp_ies, *assocresp_ies;
Jeff Johnson295189b2012-06-20 16:38:30 -07009434
Jeff Johnsone7245742012-09-05 17:12:55 -07009435 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309437 {
9438 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9439 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309441 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009442
9443 old = pAdapter->sessionCtx.ap.beacon;
9444
9445 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309446 {
9447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9448 FL("session(%d) old and new heads points to NULL"),
9449 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309451 }
9452
9453 if (params->tail && !params->tail_len)
9454 {
9455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9456 FL("tail_len is zero but tail is not NULL"));
9457 return -EINVAL;
9458 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009459
Jeff Johnson295189b2012-06-20 16:38:30 -07009460#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
9461 /* Kernel 3.0 is not updating dtim_period for set beacon */
9462 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309463 {
9464 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9465 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009468#endif
9469
Kapil Gupta137ef892016-12-13 19:38:00 +05309470 if (params->head)
9471 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009472 head_len = params->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309473 head = params->head;
9474 } else
9475 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009476 head_len = old->head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309477 head = old->head;
9478 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009479
Kapil Gupta137ef892016-12-13 19:38:00 +05309480 if (params->tail || !old)
9481 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 tail_len = params->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309483 tail = params->tail;
9484 } else
9485 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 tail_len = old->tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309487 tail = old->tail;
9488 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009489
Kapil Gupta137ef892016-12-13 19:38:00 +05309490 if (params->proberesp_ies || !old)
9491 {
9492 proberesp_ies_len = params->proberesp_ies_len;
9493 proberesp_ies = params->proberesp_ies;
9494 } else
9495 {
9496 proberesp_ies_len = old->proberesp_ies_len;
9497 proberesp_ies = old->proberesp_ies;
9498 }
9499
9500 if (params->assocresp_ies || !old)
9501 {
9502 assocresp_ies_len = params->assocresp_ies_len;
9503 assocresp_ies = params->assocresp_ies;
9504 } else
9505 {
9506 assocresp_ies_len = old->assocresp_ies_len;
9507 assocresp_ies = old->assocresp_ies;
9508 }
9509
9510 size = sizeof(beacon_data_t) + head_len + tail_len +
9511 proberesp_ies_len + assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009512
9513 beacon = kzalloc(size, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -07009514 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309515 {
9516 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9517 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009518 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309519 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009520
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009521#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Kapil Gupta137ef892016-12-13 19:38:00 +05309522 if (params->dtim_period)
Jeff Johnson295189b2012-06-20 16:38:30 -07009523 beacon->dtim_period = params->dtim_period;
9524 else
9525 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009526#else
Kapil Gupta137ef892016-12-13 19:38:00 +05309527 if (dtim_period)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009528 beacon->dtim_period = dtim_period;
9529 else
9530 beacon->dtim_period = old->dtim_period;
9531#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309532
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
9534 beacon->tail = beacon->head + head_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309535 beacon->proberesp_ies = beacon->tail + tail_len;
9536 beacon->assocresp_ies = beacon->proberesp_ies + proberesp_ies_len;
9537
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 beacon->head_len = head_len;
9539 beacon->tail_len = tail_len;
Kapil Gupta137ef892016-12-13 19:38:00 +05309540 beacon->proberesp_ies_len = proberesp_ies_len;
9541 beacon->assocresp_ies_len= assocresp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
c_manjee527ecac2017-01-25 12:25:27 +05309543 if (head && head_len)
9544 memcpy(beacon->head, head, head_len);
9545 if (tail && tail_len)
9546 memcpy(beacon->tail, tail, tail_len);
9547 if (proberesp_ies && proberesp_ies_len)
9548 memcpy(beacon->proberesp_ies, proberesp_ies, proberesp_ies_len);
9549 if (assocresp_ies && assocresp_ies_len)
9550 memcpy(beacon->assocresp_ies, assocresp_ies, assocresp_ies_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009551
9552 *ppBeacon = beacon;
9553
9554 kfree(old);
9555
9556 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009557}
Jeff Johnson295189b2012-06-20 16:38:30 -07009558
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309559v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
9560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
9561 const v_U8_t *pIes,
9562#else
9563 v_U8_t *pIes,
9564#endif
9565 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009566{
9567 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309568 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07009569 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309570
Jeff Johnson295189b2012-06-20 16:38:30 -07009571 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 elem_id = ptr[0];
9574 elem_len = ptr[1];
9575 left -= 2;
9576 if(elem_len > left)
9577 {
9578 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009579 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009580 eid,elem_len,left);
9581 return NULL;
9582 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 {
9585 return ptr;
9586 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309587
Jeff Johnson295189b2012-06-20 16:38:30 -07009588 left -= elem_len;
9589 ptr += (elem_len + 2);
9590 }
9591 return NULL;
9592}
9593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594/* Check if rate is 11g rate or not */
9595static int wlan_hdd_rate_is_11g(u8 rate)
9596{
Sanjay Devnani28322e22013-06-21 16:13:40 -07009597 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 u8 i;
9599 for (i = 0; i < 8; i++)
9600 {
9601 if(rate == gRateArray[i])
9602 return TRUE;
9603 }
9604 return FALSE;
9605}
9606
9607/* Check for 11g rate and set proper 11g only mode */
9608static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
9609 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
9610{
9611 u8 i, num_rates = pIe[0];
9612
9613 pIe += 1;
9614 for ( i = 0; i < num_rates; i++)
9615 {
9616 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
9617 {
9618 /* If rate set have 11g rate than change the mode to 11G */
9619 *pSapHw_mode = eSAP_DOT11_MODE_11g;
9620 if (pIe[i] & BASIC_RATE_MASK)
9621 {
9622 /* If we have 11g rate as basic rate, it means mode
9623 is 11g only mode.
9624 */
9625 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
9626 *pCheckRatesfor11g = FALSE;
9627 }
9628 }
9629 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
9630 {
9631 *require_ht = TRUE;
9632 }
9633 }
9634 return;
9635}
9636
9637static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
9638{
9639 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9640 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9641 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9642 u8 checkRatesfor11g = TRUE;
9643 u8 require_ht = FALSE;
9644 u8 *pIe=NULL;
9645
9646 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
9647
9648 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
9649 pBeacon->head_len, WLAN_EID_SUPP_RATES);
9650 if (pIe != NULL)
9651 {
9652 pIe += 1;
9653 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9654 &pConfig->SapHw_mode);
9655 }
9656
9657 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9658 WLAN_EID_EXT_SUPP_RATES);
9659 if (pIe != NULL)
9660 {
9661
9662 pIe += 1;
9663 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
9664 &pConfig->SapHw_mode);
9665 }
9666
9667 if( pConfig->channel > 14 )
9668 {
9669 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
9670 }
9671
9672 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
9673 WLAN_EID_HT_CAPABILITY);
9674
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309675 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009676 {
9677 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
9678 if(require_ht)
9679 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
9680 }
9681}
9682
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309683static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
9684 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
9685{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009686 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309687 v_U8_t *pIe = NULL;
9688 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9689
9690 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
9691 pBeacon->tail, pBeacon->tail_len);
9692
9693 if (pIe)
9694 {
9695 ielen = pIe[1] + 2;
9696 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9697 {
9698 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
9699 }
9700 else
9701 {
9702 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
9703 return -EINVAL;
9704 }
9705 *total_ielen += ielen;
9706 }
9707 return 0;
9708}
9709
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009710static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
9711 v_U8_t *genie, v_U8_t *total_ielen)
9712{
9713 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9714 int left = pBeacon->tail_len;
9715 v_U8_t *ptr = pBeacon->tail;
9716 v_U8_t elem_id, elem_len;
9717 v_U16_t ielen = 0;
9718
9719 if ( NULL == ptr || 0 == left )
9720 return;
9721
9722 while (left >= 2)
9723 {
9724 elem_id = ptr[0];
9725 elem_len = ptr[1];
9726 left -= 2;
9727 if (elem_len > left)
9728 {
9729 hddLog( VOS_TRACE_LEVEL_ERROR,
9730 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
9731 elem_id, elem_len, left);
9732 return;
9733 }
Ashish Kumar Dhanotiya6af276b2017-08-22 16:53:48 +05309734 if ((IE_EID_VENDOR == elem_id) && (elem_len >= WPS_OUI_TYPE_SIZE))
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009735 {
9736 /* skipping the VSIE's which we don't want to include or
9737 * it will be included by existing code
9738 */
9739 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
9740#ifdef WLAN_FEATURE_WFD
9741 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
9742#endif
9743 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9744 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9745 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
9746 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
9747 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
9748 {
9749 ielen = ptr[1] + 2;
9750 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
9751 {
9752 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
9753 *total_ielen += ielen;
9754 }
9755 else
9756 {
9757 hddLog( VOS_TRACE_LEVEL_ERROR,
9758 "IE Length is too big "
9759 "IEs eid=%d elem_len=%d total_ie_lent=%d",
9760 elem_id, elem_len, *total_ielen);
9761 }
9762 }
9763 }
9764
9765 left -= elem_len;
9766 ptr += (elem_len + 2);
9767 }
9768 return;
9769}
9770
Kapil Gupta137ef892016-12-13 19:38:00 +05309771int wlan_hdd_cfg80211_update_apies(hdd_adapter_t *pHostapdAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07009772{
9773 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309774 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07009776 int ret = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +05309777 beacon_data_t *pBeacon = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009778
9779 genie = vos_mem_malloc(MAX_GENIE_LEN);
9780
9781 if(genie == NULL) {
9782
9783 return -ENOMEM;
9784 }
9785
Kapil Gupta137ef892016-12-13 19:38:00 +05309786 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309787 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9788 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309790 hddLog(LOGE,
9791 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309792 ret = -EINVAL;
9793 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 }
9795
9796#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309797 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9798 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
9799 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309800 hddLog(LOGE,
9801 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309802 ret = -EINVAL;
9803 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009804 }
9805#endif
9806
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309807 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
9808 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309810 hddLog(LOGE,
9811 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05309812 ret = -EINVAL;
9813 goto done;
9814 }
9815
9816 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
9817 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07009818 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009820
9821 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9822 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
9823 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
9824 {
9825 hddLog(LOGE,
9826 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 ret = -EINVAL;
9828 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 }
9830
9831 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9832 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
9833 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9834 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9835 ==eHAL_STATUS_FAILURE)
9836 {
9837 hddLog(LOGE,
9838 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009839 ret = -EINVAL;
9840 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009841 }
9842
9843 // Added for ProResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309844 if ((pBeacon->proberesp_ies != NULL) && (pBeacon->proberesp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 {
Kapil Gupta137ef892016-12-13 19:38:00 +05309846 u16 rem_probe_resp_ie_len = pBeacon->proberesp_ies_len;
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 u8 probe_rsp_ie_len[3] = {0};
9848 u8 counter = 0;
9849 /* Check Probe Resp Length if it is greater then 255 then Store
9850 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
9851 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
9852 Store More then 255 bytes into One Variable.
9853 */
9854 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
9855 {
9856 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
9857 {
9858 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
9859 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
9860 }
9861 else
9862 {
9863 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
9864 rem_probe_resp_ie_len = 0;
9865 }
9866 }
9867
9868 rem_probe_resp_ie_len = 0;
9869
9870 if (probe_rsp_ie_len[0] > 0)
9871 {
9872 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9873 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
Kapil Gupta137ef892016-12-13 19:38:00 +05309874 (tANI_U8*)&pBeacon->
9875 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009876 probe_rsp_ie_len[0], NULL,
9877 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9878 {
9879 hddLog(LOGE,
9880 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009881 ret = -EINVAL;
9882 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009883 }
9884 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
9885 }
9886
9887 if (probe_rsp_ie_len[1] > 0)
9888 {
9889 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9890 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
Kapil Gupta137ef892016-12-13 19:38:00 +05309891 (tANI_U8*)&pBeacon->
9892 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 probe_rsp_ie_len[1], NULL,
9894 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9895 {
9896 hddLog(LOGE,
9897 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009898 ret = -EINVAL;
9899 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009900 }
9901 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
9902 }
9903
9904 if (probe_rsp_ie_len[2] > 0)
9905 {
9906 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9907 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
Kapil Gupta137ef892016-12-13 19:38:00 +05309908 (tANI_U8*)&pBeacon->
9909 proberesp_ies[rem_probe_resp_ie_len],
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 probe_rsp_ie_len[2], NULL,
9911 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9912 {
9913 hddLog(LOGE,
9914 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009915 ret = -EINVAL;
9916 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009917 }
9918 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
9919 }
9920
9921 if (probe_rsp_ie_len[1] == 0 )
9922 {
9923 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9924 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
9925 eANI_BOOLEAN_FALSE) )
9926 {
9927 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009928 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 }
9930 }
9931
9932 if (probe_rsp_ie_len[2] == 0 )
9933 {
9934 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9935 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
9936 eANI_BOOLEAN_FALSE) )
9937 {
9938 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009939 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 }
9941 }
9942
9943 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9944 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
9945 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9946 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9947 == eHAL_STATUS_FAILURE)
9948 {
9949 hddLog(LOGE,
9950 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009951 ret = -EINVAL;
9952 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009953 }
9954 }
9955 else
9956 {
9957 // Reset WNI_CFG_PROBE_RSP Flags
9958 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
9959
9960 hddLog(VOS_TRACE_LEVEL_INFO,
9961 "%s: No Probe Response IE received in set beacon",
9962 __func__);
9963 }
9964
9965 // Added for AssocResp IE
Kapil Gupta137ef892016-12-13 19:38:00 +05309966 if ((pBeacon->assocresp_ies != NULL) && (pBeacon->assocresp_ies_len != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 {
9968 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
Kapil Gupta137ef892016-12-13 19:38:00 +05309969 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)pBeacon->assocresp_ies,
9970 pBeacon->assocresp_ies_len, NULL,
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
9972 {
9973 hddLog(LOGE,
9974 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009975 ret = -EINVAL;
9976 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 }
9978
9979 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9980 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
9981 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
9982 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
9983 == eHAL_STATUS_FAILURE)
9984 {
9985 hddLog(LOGE,
9986 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07009987 ret = -EINVAL;
9988 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07009989 }
9990 }
9991 else
9992 {
9993 hddLog(VOS_TRACE_LEVEL_INFO,
9994 "%s: No Assoc Response IE received in set beacon",
9995 __func__);
9996
9997 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
9998 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9999 eANI_BOOLEAN_FALSE) )
10000 {
10001 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010002 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 }
10004 }
10005
Jeff Johnsone7245742012-09-05 17:12:55 -070010006done:
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +053010008 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010009}
Jeff Johnson295189b2012-06-20 16:38:30 -070010010
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010011/*
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 * FUNCTION: wlan_hdd_validate_operation_channel
10013 * called by wlan_hdd_cfg80211_start_bss() and
10014 * wlan_hdd_cfg80211_set_channel()
10015 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 * channel list.
10017 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -070010018VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010019{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010020
Jeff Johnson295189b2012-06-20 16:38:30 -070010021 v_U32_t num_ch = 0;
10022 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
10023 u32 indx = 0;
10024 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010025 v_U8_t fValidChannel = FALSE, count = 0;
10026 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010027
Jeff Johnson295189b2012-06-20 16:38:30 -070010028 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10029
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010030 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070010031 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010032 /* Validate the channel */
10033 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010035 if ( channel == rfChannels[count].channelNum )
10036 {
10037 fValidChannel = TRUE;
10038 break;
10039 }
10040 }
10041 if (fValidChannel != TRUE)
10042 {
10043 hddLog(VOS_TRACE_LEVEL_ERROR,
10044 "%s: Invalid Channel [%d]", __func__, channel);
10045 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010046 }
10047 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010048 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053010050 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
10051 valid_ch, &num_ch))
10052 {
10053 hddLog(VOS_TRACE_LEVEL_ERROR,
10054 "%s: failed to get valid channel list", __func__);
10055 return VOS_STATUS_E_FAILURE;
10056 }
10057 for (indx = 0; indx < num_ch; indx++)
10058 {
10059 if (channel == valid_ch[indx])
10060 {
10061 break;
10062 }
10063 }
10064
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010065 if (indx >= num_ch)
10066 {
10067 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10068 {
10069 eCsrBand band;
10070 unsigned int freq;
10071
10072 sme_GetFreqBand(hHal, &band);
10073
10074 if (eCSR_BAND_5G == band)
10075 {
10076#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10077 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10078 {
10079 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010080 HDD_NL80211_BAND_2GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010081 }
10082 else
10083 {
10084 freq = ieee80211_channel_to_frequency(channel,
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010085 HDD_NL80211_BAND_5GHZ);
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010086 }
10087#else
10088 freq = ieee80211_channel_to_frequency(channel);
10089#endif
10090 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
10091 return VOS_STATUS_SUCCESS;
10092 }
10093 }
10094
10095 hddLog(VOS_TRACE_LEVEL_ERROR,
10096 "%s: Invalid Channel [%d]", __func__, channel);
10097 return VOS_STATUS_E_FAILURE;
10098 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +053010100
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102
Jeff Johnson295189b2012-06-20 16:38:30 -070010103}
10104
Viral Modi3a32cc52013-02-08 11:14:52 -080010105/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010106 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -080010107 * This function is used to set the channel number
10108 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010109static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -080010110 struct ieee80211_channel *chan,
10111 enum nl80211_channel_type channel_type
10112 )
10113{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010114 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -080010115 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -070010116 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -080010117 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010118 hdd_context_t *pHddCtx;
10119 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010120
10121 ENTER();
10122
10123 if( NULL == dev )
10124 {
10125 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010126 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010127 return -ENODEV;
10128 }
10129 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010130
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010131 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10132 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
10133 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -080010134 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010135 "%s: device_mode = %s (%d) freq = %d", __func__,
10136 hdd_device_modetoString(pAdapter->device_mode),
10137 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010138
10139 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10140 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010141 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -080010142 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010143 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010144 }
10145
10146 /*
10147 * Do freq to chan conversion
10148 * TODO: for 11a
10149 */
10150
10151 channel = ieee80211_frequency_to_channel(freq);
10152
10153 /* Check freq range */
10154 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
10155 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
10156 {
10157 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010158 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -080010159 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
10160 WNI_CFG_CURRENT_CHANNEL_STAMAX);
10161 return -EINVAL;
10162 }
10163
10164 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
10165
Gopichand Nakkala6ab19562013-03-07 13:59:42 +053010166 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
10167 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -080010168 {
10169 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
10170 {
10171 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010172 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -080010173 return -EINVAL;
10174 }
10175 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10176 "%s: set channel to [%d] for device mode =%d",
10177 __func__, channel,pAdapter->device_mode);
10178 }
10179 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -080010180 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -080010181 )
10182 {
10183 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10184 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
10185 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10186
10187 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
10188 {
10189 /* Link is up then return cant set channel*/
10190 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010191 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -080010192 return -EINVAL;
10193 }
10194
10195 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
10196 pHddStaCtx->conn_info.operationChannel = channel;
10197 pRoamProfile->ChannelInfo.ChannelList =
10198 &pHddStaCtx->conn_info.operationChannel;
10199 }
10200 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -080010201 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -080010202 )
10203 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010204 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
10205 {
10206 if(VOS_STATUS_SUCCESS !=
10207 wlan_hdd_validate_operation_channel(pAdapter,channel))
10208 {
10209 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010210 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010211 return -EINVAL;
10212 }
10213 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10214 }
10215 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -080010216 {
10217 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
10218
10219 /* If auto channel selection is configured as enable/ 1 then ignore
10220 channel set by supplicant
10221 */
10222 if ( cfg_param->apAutoChannelSelection )
10223 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010224 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
10225 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -080010226 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010227 "%s: set channel to auto channel (0) for device mode =%s (%d)",
10228 __func__, hdd_device_modetoString(pAdapter->device_mode),
10229 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -080010230 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010231 else
10232 {
10233 if(VOS_STATUS_SUCCESS !=
10234 wlan_hdd_validate_operation_channel(pAdapter,channel))
10235 {
10236 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010237 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +053010238 return -EINVAL;
10239 }
10240 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
10241 }
Viral Modi3a32cc52013-02-08 11:14:52 -080010242 }
10243 }
10244 else
10245 {
10246 hddLog(VOS_TRACE_LEVEL_FATAL,
10247 "%s: Invalid device mode failed to set valid channel", __func__);
10248 return -EINVAL;
10249 }
10250 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010251 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -080010252}
10253
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010254static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
10255 struct net_device *dev,
10256 struct ieee80211_channel *chan,
10257 enum nl80211_channel_type channel_type
10258 )
10259{
10260 int ret;
10261
10262 vos_ssr_protect(__func__);
10263 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
10264 vos_ssr_unprotect(__func__);
10265
10266 return ret;
10267}
10268
Anurag Chouhan83026002016-12-13 22:46:21 +053010269#ifdef DHCP_SERVER_OFFLOAD
10270void hdd_dhcp_server_offload_done(void *fw_dhcp_srv_offload_cb_context,
10271 VOS_STATUS status)
10272{
10273 hdd_adapter_t* adapter = (hdd_adapter_t*)fw_dhcp_srv_offload_cb_context;
10274
10275 ENTER();
10276
10277 if (NULL == adapter)
10278 {
10279 hddLog(VOS_TRACE_LEVEL_ERROR,
10280 "%s: adapter is NULL",__func__);
10281 return;
10282 }
10283
10284 adapter->dhcp_status.dhcp_offload_status = status;
10285 vos_event_set(&adapter->dhcp_status.vos_event);
10286 return;
10287}
10288
10289/**
10290 * wlan_hdd_set_dhcp_server_offload() - set dhcp server offload
10291 * @hostapd_adapter: pointer to hostapd adapter.
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010292 * @re_init: flag set if api called post ssr
Anurag Chouhan83026002016-12-13 22:46:21 +053010293 *
10294 * Return: None
10295 */
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010296VOS_STATUS wlan_hdd_set_dhcp_server_offload(hdd_adapter_t *hostapd_adapter,
10297 bool re_init)
Anurag Chouhan83026002016-12-13 22:46:21 +053010298{
10299 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(hostapd_adapter);
10300 sir_dhcp_srv_offload_info dhcp_srv_info;
10301 tANI_U8 num_entries = 0;
10302 tANI_U8 srv_ip[IPADDR_NUM_ENTRIES];
10303 tANI_U8 num;
10304 tANI_U32 temp;
10305 VOS_STATUS ret;
10306
10307 ENTER();
10308
Anurag Chouhan638f5e22017-03-06 12:28:43 +053010309 if (!re_init) {
10310 ret = wlan_hdd_validate_context(hdd_ctx);
10311 if (0 != ret)
10312 return VOS_STATUS_E_INVAL;
10313 }
Anurag Chouhan83026002016-12-13 22:46:21 +053010314
10315 /* Prepare the request to send to SME */
10316 dhcp_srv_info = vos_mem_malloc(sizeof(*dhcp_srv_info));
10317 if (NULL == dhcp_srv_info) {
10318 hddLog(VOS_TRACE_LEVEL_ERROR,
10319 "%s: could not allocate tDhcpSrvOffloadInfo!", __func__);
10320 return VOS_STATUS_E_NOMEM;
10321 }
10322
10323 vos_mem_zero(dhcp_srv_info, sizeof(*dhcp_srv_info));
10324
10325 dhcp_srv_info->bssidx = hostapd_adapter->sessionId;
10326 dhcp_srv_info->dhcp_srv_offload_enabled = TRUE;
10327 dhcp_srv_info->dhcp_client_num = hdd_ctx->cfg_ini->dhcp_max_num_clients;
10328 dhcp_srv_info->start_lsb = hdd_ctx->cfg_ini->dhcp_start_lsb;
10329 dhcp_srv_info->dhcp_offload_callback = hdd_dhcp_server_offload_done;
10330 dhcp_srv_info->dhcp_server_offload_cb_context = hostapd_adapter;
10331
10332 hdd_string_to_u8_array(hdd_ctx->cfg_ini->dhcp_srv_ip,
10333 srv_ip,
10334 &num_entries,
Yeshwanth Sriram Guntuka8d9b29c2017-12-12 15:44:57 +053010335 IPADDR_NUM_ENTRIES, ".", false);
Anurag Chouhan83026002016-12-13 22:46:21 +053010336 if (num_entries != IPADDR_NUM_ENTRIES) {
10337 hddLog(VOS_TRACE_LEVEL_ERROR,
10338 "%s: incorrect IP address (%s) assigned for DHCP server!",
10339 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10340 vos_mem_free(dhcp_srv_info);
10341 return VOS_STATUS_E_FAILURE;
10342 }
10343
10344 if ((srv_ip[0] >= 224) && (srv_ip[0] <= 239)) {
10345 hddLog(VOS_TRACE_LEVEL_ERROR,
10346 "%s: invalid IP address (%s)! It could NOT be multicast IP address!",
10347 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10348 vos_mem_free(dhcp_srv_info);
10349 return VOS_STATUS_E_FAILURE;
10350 }
10351
10352 if (srv_ip[IPADDR_NUM_ENTRIES-1] >= DHCP_START_POOL_ADDRESS) {
10353 hddLog(VOS_TRACE_LEVEL_ERROR,
10354 "%s: invalid IP address (%s)! The last field must be less than 100!",
10355 __func__, hdd_ctx->cfg_ini->dhcp_srv_ip);
10356 vos_mem_free(dhcp_srv_info);
10357 return VOS_STATUS_E_FAILURE;
10358 }
10359
10360 for (num = 0; num < num_entries; num++) {
10361 temp = srv_ip[num];
10362 dhcp_srv_info->dhcp_srv_ip |= (temp << (8 * num));
10363 }
10364
10365 if (eHAL_STATUS_SUCCESS !=
10366 sme_set_dhcp_srv_offload(hdd_ctx->hHal, dhcp_srv_info)) {
10367 hddLog(VOS_TRACE_LEVEL_ERROR,
10368 "%s: sme_set_dhcp_srv_offload fail!", __func__);
10369 vos_mem_free(dhcp_srv_info);
10370 return VOS_STATUS_E_FAILURE;
10371 }
10372
10373 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10374 "%s: enable DHCP Server offload successfully!", __func__);
10375
10376 vos_mem_free(dhcp_srv_info);
10377 return 0;
10378}
10379#endif /* DHCP_SERVER_OFFLOAD */
10380
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010381/*
10382 * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
10383 * @wiphy_chan: wiphy channel number
10384 * @rfChannel: channel hw value
10385 * @disable: Disable/enable the flags
10386 *
10387 * Modify wiphy flags and cds state if channel is indoor.
10388 *
10389 * Return: void
10390 */
10391void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
10392 v_U32_t rfChannel, bool disable)
10393{
10394 v_U32_t channelLoop;
10395 eRfChannels channelEnum = INVALID_RF_CHANNEL;
10396
10397 for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
10398
10399 if (rfChannels[channelLoop].channelNum == rfChannel) {
10400 channelEnum = (eRfChannels)channelLoop;
10401 break;
10402 }
10403 }
10404
10405 if (INVALID_RF_CHANNEL == channelEnum)
10406 return;
10407
10408 if (disable) {
10409 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10410 wiphy_chan->flags |=
10411 IEEE80211_CHAN_DISABLED;
10412 regChannels[channelEnum].enabled =
10413 NV_CHANNEL_DISABLE;
10414 }
10415 } else {
10416 if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
10417 wiphy_chan->flags &=
10418 ~IEEE80211_CHAN_DISABLED;
10419 /*
10420 * Indoor channels are marked as DFS
10421 * during regulatory processing
10422 */
10423
10424 regChannels[channelEnum].enabled =
10425 NV_CHANNEL_DFS;
10426 }
10427 }
10428
10429}
10430
10431void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
10432 bool disable)
10433{
10434 int band_num;
10435 int chan_num;
10436 v_U32_t rfChannel;
10437 struct ieee80211_channel *wiphy_chan;
10438 struct wiphy *wiphy;
10439
10440 ENTER();
10441 hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
10442
10443 wiphy = hdd_ctx->wiphy;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053010444 for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010445
10446 if (wiphy->bands[band_num] == NULL)
10447 continue;
10448
10449 for (chan_num = 0;
10450 chan_num < wiphy->bands[band_num]->n_channels;
10451 chan_num++) {
10452
10453 wiphy_chan =
10454 &(wiphy->bands[band_num]->channels[chan_num]);
10455 rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
10456
10457 hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
10458 disable);
10459 }
10460 }
10461 EXIT();
10462}
10463
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010464/*
10465 * FUNCTION: wlan_hdd_disconnect
10466 * This function is used to issue a disconnect request to SME
10467 */
10468int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
10469{
10470 int status, result = 0;
10471 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10473 long ret;
10474 eConnectionState prev_conn_state;
10475 uint32_t wait_time = WLAN_WAIT_TIME_DISCONNECT;
10476
10477 ENTER();
10478
10479 status = wlan_hdd_validate_context(pHddCtx);
10480 if (0 != status)
10481 {
10482 return status;
10483 }
10484 /* Indicate sme of disconnect so that in progress connection or preauth
10485 * can be aborted
10486 */
10487 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
10488 pAdapter->sessionId);
10489 pHddCtx->isAmpAllowed = VOS_TRUE;
10490
10491 /* Need to apply spin lock before decreasing active sessions
10492 * as there can be chance for double decrement if context switch
10493 * Calls hdd_DisConnectHandler.
10494 */
10495
10496 prev_conn_state = pHddStaCtx->conn_info.connState;
10497
10498 spin_lock_bh(&pAdapter->lock_for_active_session);
10499 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
10500 {
10501 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
10502 }
10503 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
10504 spin_unlock_bh(&pAdapter->lock_for_active_session);
10505 vos_flush_delayed_work(&pHddCtx->ecsa_chan_change_work);
10506
10507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10508 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
10509
10510 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10511
10512 /*
10513 * stop tx queues before deleting STA/BSS context from the firmware.
10514 * tx has to be disabled because the firmware can get busy dropping
10515 * the tx frames after BSS/STA has been deleted and will not send
10516 * back a response resulting in WDI timeout
10517 */
10518 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
10519 netif_tx_disable(pAdapter->dev);
10520 netif_carrier_off(pAdapter->dev);
10521
10522 wlan_hdd_check_and_stop_mon(pAdapter, true);
10523
10524 /*issue disconnect*/
10525 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10526 pAdapter->sessionId, reason);
10527 if((eHAL_STATUS_CMD_NOT_QUEUED == status) &&
10528 prev_conn_state != eConnectionState_Connecting)
10529 {
10530 hddLog(LOG1,
10531 FL("status = %d, already disconnected"), status);
10532 result = 0;
10533 /*
10534 * Wait here instead of returning directly. This will block the
10535 * next connect command and allow processing of the disconnect
10536 * in SME else we might hit some race conditions leading to SME
10537 * and HDD out of sync. As disconnect is already in progress,
10538 * wait here for 1 sec instead of 5 sec.
10539 */
10540 wait_time = WLAN_WAIT_DISCONNECT_ALREADY_IN_PROGRESS;
10541 goto wait_for_disconnect;
10542 }
10543 /*
10544 * Wait here instead of returning directly, this will block the next
10545 * connect command and allow processing of the scan for ssid and
10546 * the previous connect command in CSR. Else we might hit some
10547 * race conditions leading to SME and HDD out of sync.
10548 */
10549 else if(eHAL_STATUS_CMD_NOT_QUEUED == status)
10550 {
10551 hddLog(LOG1,
10552 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
10553 }
10554 else if ( 0 != status )
10555 {
10556 hddLog(LOGE,
10557 FL("csrRoamDisconnect failure, returned %d"),
10558 (int)status);
10559 result = -EINVAL;
10560 goto disconnected;
10561 }
10562wait_for_disconnect:
10563 ret = wait_for_completion_timeout(&pAdapter->disconnect_comp_var,
10564 msecs_to_jiffies(wait_time));
10565 if (!ret && (eHAL_STATUS_CMD_NOT_QUEUED != status))
10566 {
10567 hddLog(LOGE,
10568 "%s: Failed to disconnect, timed out", __func__);
10569 result = -ETIMEDOUT;
10570 }
10571disconnected:
10572 hddLog(LOG1,
10573 FL("Set HDD connState to eConnectionState_NotConnected"));
10574 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
10575#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,11,0)
10576 /* Sending disconnect event to userspace for kernel version < 3.11
10577 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
10578 */
10579 hddLog(LOG1, FL("Send disconnected event to userspace"));
10580
10581 wlan_hdd_cfg80211_indicate_disconnect(pAdapter->dev, true,
10582 WLAN_REASON_UNSPECIFIED);
10583#endif
10584
10585 EXIT();
10586 return result;
10587}
10588
10589/*
10590 * hdd_check_and_disconnect_sta_on_invalid_channel() - Disconnect STA if it is
10591 * on indoor channel
10592 * @hdd_ctx: pointer to hdd context
10593 *
10594 * STA should be disconnected before starting the SAP if it is on indoor
10595 * channel.
10596 *
10597 * Return: void
10598 */
10599void hdd_check_and_disconnect_sta_on_invalid_channel(hdd_context_t *hdd_ctx)
10600{
10601
10602 hdd_adapter_t *sta_adapter;
10603 tANI_U8 sta_chan;
10604
10605 sta_chan = hdd_get_operating_channel(hdd_ctx, WLAN_HDD_INFRA_STATION);
10606
10607 if (!sta_chan) {
10608 hddLog(LOG1, FL("STA not connected"));
10609 return;
10610 }
10611
10612 hddLog(LOG1, FL("STA connected on chan %hu"), sta_chan);
10613
10614 if (sme_IsChannelValid(hdd_ctx->hHal, sta_chan)) {
10615 hddLog(LOG1, FL("STA connected on chan %hu and it is valid"),
10616 sta_chan);
10617 return;
10618 }
10619
10620 sta_adapter = hdd_get_adapter(hdd_ctx, WLAN_HDD_INFRA_STATION);
10621
10622 if (!sta_adapter) {
10623 hddLog(LOG1, FL("STA adapter doesn't exist"));
10624 return;
10625 }
10626
10627 hddLog(LOG1, FL("chan %hu not valid, issue disconnect"), sta_chan);
10628 /* Issue Disconnect request */
10629 wlan_hdd_disconnect(sta_adapter, eCSR_DISCONNECT_REASON_DEAUTH);
10630}
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010631
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010632int wlan_hdd_restore_channels(hdd_context_t *hdd_ctx)
10633{
10634 struct hdd_cache_channels *cache_chann;
10635 struct wiphy *wiphy;
10636 int freq, status, rfChannel;
10637 int i, band_num, channel_num;
10638 struct ieee80211_channel *wiphy_channel;
10639
10640 ENTER();
10641
10642 if (!hdd_ctx) {
10643 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10644 return -EINVAL;
10645 }
10646
10647 wiphy = hdd_ctx->wiphy;
10648
10649 mutex_lock(&hdd_ctx->cache_channel_lock);
10650
10651 cache_chann = hdd_ctx->orginal_channels;
10652
10653 if (!cache_chann || !cache_chann->num_channels) {
10654 hddLog(VOS_TRACE_LEVEL_INFO,
10655 "%s channel list is NULL or num channels are zero",
10656 __func__);
10657 mutex_unlock(&hdd_ctx->cache_channel_lock);
10658 return -EINVAL;
10659 }
10660
10661 for (i = 0; i < cache_chann->num_channels; i++) {
10662 status = hdd_wlan_get_freq(
10663 cache_chann->channel_info[i].channel_num,
10664 &freq);
10665
10666 for (band_num = 0; band_num < IEEE80211_NUM_BANDS; band_num++) {
10667 for (channel_num = 0; channel_num <
10668 wiphy->bands[band_num]->n_channels;
10669 channel_num++) {
10670 wiphy_channel = &(wiphy->bands[band_num]->
10671 channels[channel_num]);
10672 if (wiphy_channel->center_freq == freq) {
10673 rfChannel = wiphy_channel->hw_value;
10674 /*
10675 *Restore the orginal states
10676 *of the channels
10677 */
10678 vos_nv_set_channel_state(
10679 rfChannel,
10680 cache_chann->
10681 channel_info[i].reg_status);
10682 wiphy_channel->flags =
10683 cache_chann->
10684 channel_info[i].wiphy_status;
10685 break;
10686 }
10687 }
10688 if (channel_num < wiphy->bands[band_num]->n_channels)
10689 break;
10690 }
10691 }
10692
10693 mutex_unlock(&hdd_ctx->cache_channel_lock);
10694
10695 status = sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10696 if (status)
10697 hddLog(VOS_TRACE_LEVEL_ERROR, "Can't Restore channel list");
10698 EXIT();
10699
10700 return 0;
10701}
10702
10703/*
10704 * wlan_hdd_disable_channels() - Cache the the channels
10705 * and current state of the channels from the channel list
10706 * received in the command and disable the channels on the
10707 * wiphy and NV table.
10708 * @hdd_ctx: Pointer to hdd context
10709 *
10710 * @return: 0 on success, Error code on failure
10711 */
10712
10713static int wlan_hdd_disable_channels(hdd_context_t *hdd_ctx)
10714{
10715 struct hdd_cache_channels *cache_chann;
10716 struct wiphy *wiphy;
10717 int freq, status, rfChannel;
10718 int i, band_num, band_ch_num;
10719 struct ieee80211_channel *wiphy_channel;
10720
10721 if (!hdd_ctx) {
10722 hddLog(VOS_TRACE_LEVEL_FATAL, "HDD Context is NULL");
10723 return -EINVAL;
10724 }
10725
10726 wiphy = hdd_ctx->wiphy;
10727
10728 mutex_lock(&hdd_ctx->cache_channel_lock);
10729 cache_chann = hdd_ctx->orginal_channels;
10730
10731 if (!cache_chann || !cache_chann->num_channels) {
10732 hddLog(VOS_TRACE_LEVEL_INFO,
10733 "%s channel list is NULL or num channels are zero",
10734 __func__);
10735 mutex_unlock(&hdd_ctx->cache_channel_lock);
10736 return -EINVAL;
10737 }
10738
10739 for (i = 0; i < cache_chann->num_channels; i++) {
10740 status = hdd_wlan_get_freq(
10741 cache_chann->channel_info[i].channel_num,
10742 &freq);
10743
10744 for (band_num = 0; band_num < IEEE80211_NUM_BANDS;
10745 band_num++) {
10746 for (band_ch_num = 0; band_ch_num <
10747 wiphy->bands[band_num]->n_channels;
10748 band_ch_num++) {
10749 wiphy_channel = &(wiphy->bands[band_num]->
10750 channels[band_ch_num]);
10751 if (wiphy_channel->center_freq == freq) {
10752 rfChannel = wiphy_channel->hw_value;
10753 /*
10754 * Cache the current states of
10755 * the channels
10756 */
10757 cache_chann->
10758 channel_info[i].reg_status =
10759 vos_nv_getChannelEnabledState(
10760 rfChannel);
10761
10762 cache_chann->
10763 channel_info[i].wiphy_status =
10764 wiphy_channel->flags;
10765 hddLog(VOS_TRACE_LEVEL_INFO,
10766 "Disable channel %d reg_stat %d wiphy_stat 0x%x",
10767 cache_chann->
10768 channel_info[i].channel_num,
10769 cache_chann->
10770 channel_info[i].reg_status,
10771 wiphy_channel->flags);
10772
10773 vos_nv_set_channel_state(
10774 rfChannel,
10775 NV_CHANNEL_DISABLE);
10776 wiphy_channel->flags |=
10777 IEEE80211_CHAN_DISABLED;
10778 break;
10779 }
10780 }
10781 if (band_ch_num < wiphy->bands[band_num]->n_channels)
10782 break;
10783 }
10784 }
10785
10786 mutex_unlock(&hdd_ctx->cache_channel_lock);
10787 sme_update_channel_list((tpAniSirGlobal)hdd_ctx->hHal);
10788 return 0;
10789}
10790
Jeff Johnson295189b2012-06-20 16:38:30 -070010791#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10792static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10793 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010794#else
10795static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
10796 struct cfg80211_beacon_data *params,
10797 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010798 enum nl80211_hidden_ssid hidden_ssid,
10799 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010800#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010801{
10802 tsap_Config_t *pConfig;
10803 beacon_data_t *pBeacon = NULL;
10804 struct ieee80211_mgmt *pMgmt_frame;
10805 v_U8_t *pIe=NULL;
10806 v_U16_t capab_info;
10807 eCsrAuthType RSNAuthType;
10808 eCsrEncryptionType RSNEncryptType;
10809 eCsrEncryptionType mcRSNEncryptType;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053010810 int status = VOS_STATUS_SUCCESS, ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010811 tpWLAN_SAPEventCB pSapEventCallback;
10812 hdd_hostapd_state_t *pHostapdState;
Jeff Johnson295189b2012-06-20 16:38:30 -070010813 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010814 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010815 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010816 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -080010818 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +053010819 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -070010820 v_BOOL_t MFPCapable = VOS_FALSE;
10821 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +053010822 v_BOOL_t sapEnable11AC =
10823 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Kapil Gupta137ef892016-12-13 19:38:00 +053010824 u_int16_t prev_rsn_length = 0;
10825
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 ENTER();
10827
Nitesh Shah9b066282017-06-06 18:05:52 +053010828 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053010829 iniConfig = pHddCtx->cfg_ini;
10830
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010831 /* Mark the indoor channel (passive) to disable */
10832 if (iniConfig->disable_indoor_channel) {
10833 hdd_update_indoor_channel(pHddCtx, true);
10834
10835 if (!VOS_IS_STATUS_SUCCESS(
10836 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
10837 hdd_update_indoor_channel(pHddCtx, false);
10838 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
10839 FL("Can't start BSS: update channel list failed"));
10840 return eHAL_STATUS_FAILURE;
10841 }
Ganesh Kondabattini19813af2018-01-25 17:32:44 +053010842
10843 /* check if STA is on indoor channel */
10844 if (hdd_is_sta_sap_scc_allowed_on_dfs_chan(pHddCtx))
10845 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053010846 }
10847
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010848 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP) {
10849 /* Disable the channels received in command SET_DISABLE_CHANNEL_LIST*/
10850 wlan_hdd_disable_channels(pHddCtx);
10851 hdd_check_and_disconnect_sta_on_invalid_channel(pHddCtx);
10852 }
10853
Jeff Johnson295189b2012-06-20 16:38:30 -070010854 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
10855
10856 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
10857
10858 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
10859
10860 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
10861
10862 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
10863
10864 //channel is already set in the set_channel Call back
10865 //pConfig->channel = pCommitConfig->channel;
10866
10867 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010868 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
10870
10871 pConfig->dtim_period = pBeacon->dtim_period;
10872
Arif Hussain6d2a3322013-11-17 19:50:10 -080010873 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 pConfig->dtim_period);
10875
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -080010876 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -070010877 {
10878 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070010879 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +053010880 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
10881 {
10882 tANI_BOOLEAN restartNeeded;
10883 pConfig->ieee80211d = 1;
10884 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
10885 sme_setRegInfo(hHal, pConfig->countryCode);
10886 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
10887 }
10888 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 {
Jeff Johnson32d95a32012-09-10 13:15:23 -070010890 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -070010891 pConfig->ieee80211d = 1;
10892 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
10893 sme_setRegInfo(hHal, pConfig->countryCode);
10894 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -070010895 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010896 else
10897 {
10898 pConfig->ieee80211d = 0;
10899 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010900 /*
10901 * If auto channel is configured i.e. channel is 0,
10902 * so skip channel validation.
10903 */
10904 if( AUTO_CHANNEL_SELECT != pConfig->channel )
10905 {
10906 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
10907 {
10908 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010909 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010910 ret = -EINVAL;
10911 goto error;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010912 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010913 pConfig->user_config_channel = pConfig->channel;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010914 }
10915 else
10916 {
10917 if(1 != pHddCtx->is_dynamic_channel_range_set)
10918 {
10919 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
10920 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
10921 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
10922 }
Ganesh Kondabattini3655a6d2018-01-08 20:25:39 +053010923 pHddCtx->is_dynamic_channel_range_set = 0;
10924 pConfig->user_config_channel = SAP_DEFAULT_24GHZ_CHANNEL;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +053010925 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 }
Jeff Johnson32d95a32012-09-10 13:15:23 -070010927 else
Jeff Johnson295189b2012-06-20 16:38:30 -070010928 {
10929 pConfig->ieee80211d = 0;
10930 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010931
10932#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
10933 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10934 pConfig->authType = eSAP_OPEN_SYSTEM;
10935 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10936 pConfig->authType = eSAP_SHARED_KEY;
10937 else
10938 pConfig->authType = eSAP_AUTO_SWITCH;
10939#else
10940 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
10941 pConfig->authType = eSAP_OPEN_SYSTEM;
10942 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
10943 pConfig->authType = eSAP_SHARED_KEY;
10944 else
10945 pConfig->authType = eSAP_AUTO_SWITCH;
10946#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010947
10948 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010949
10950 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
Agrawal Ashisha8e8a722016-10-18 19:07:45 +053010952#ifdef SAP_AUTH_OFFLOAD
10953 /* In case of sap offload, hostapd.conf is configuted with open mode and
10954 * security is configured from ini file. Due to open mode in hostapd.conf
10955 * privacy bit is set to false which will result in not sending,
10956 * data packets as encrypted.
10957 * If enable_sap_auth_offload is enabled in ini and
10958 * sap_auth_offload_sec_type is type of WPA2-PSK,
10959 * driver will set privacy bit to 1.
10960 */
10961 if (pHddCtx->cfg_ini->enable_sap_auth_offload &&
10962 pHddCtx->cfg_ini->sap_auth_offload_sec_type)
10963 pConfig->privacy = VOS_TRUE;
10964#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010965
10966 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
10967
10968 /*Set wps station to configured*/
10969 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
10970
10971 if(pIe)
10972 {
10973 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
10974 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010975 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053010976 ret = -EINVAL;
10977 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 }
10979 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
10980 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -070010981 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -070010982 /* Check 15 bit of WPS IE as it contain information for wps state
10983 * WPS state
10984 */
10985 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
10986 {
10987 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
10988 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
10989 {
10990 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
10991 }
10992 }
10993 }
10994 else
10995 {
10996 pConfig->wps_state = SAP_WPS_DISABLED;
10997 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010998 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -070010999
c_hpothufe599e92014-06-16 11:38:55 +053011000 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11001 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
11002 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
11003 eCSR_ENCRYPT_TYPE_NONE;
11004
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 pConfig->RSNWPAReqIELength = 0;
Kapil Gupta137ef892016-12-13 19:38:00 +053011006 memset(&pConfig->RSNWPAReqIE[0], 0, sizeof(pConfig->RSNWPAReqIE));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011007 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -070011008 WLAN_EID_RSN);
11009 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011010 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011012 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11013 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11014 pConfig->RSNWPAReqIELength);
11015 else
11016 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11017 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011018 /* The actual processing may eventually be more extensive than
11019 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 * by the app.
11021 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011022 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11024 &RSNEncryptType,
11025 &mcRSNEncryptType,
11026 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011027 &MFPCapable,
11028 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011029 pConfig->RSNWPAReqIE[1]+2,
11030 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011031
11032 if( VOS_STATUS_SUCCESS == status )
11033 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011034 /* Now copy over all the security attributes you have
11035 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011036 * */
11037 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11038 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11039 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11040 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011041 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011042 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11044 }
11045 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011046
Jeff Johnson295189b2012-06-20 16:38:30 -070011047 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11048 pBeacon->tail, pBeacon->tail_len);
11049
11050 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
11051 {
Kapil Gupta137ef892016-12-13 19:38:00 +053011052 if (pConfig->RSNWPAReqIE[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 {
11054 /*Mixed mode WPA/WPA2*/
Kapil Gupta137ef892016-12-13 19:38:00 +053011055 prev_rsn_length = pConfig->RSNWPAReqIELength;
Jeff Johnson295189b2012-06-20 16:38:30 -070011056 pConfig->RSNWPAReqIELength += pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011057 if (pConfig->RSNWPAReqIELength <=
11058 (sizeof(pConfig->RSNWPAReqIE) - prev_rsn_length))
11059 memcpy(&pConfig->RSNWPAReqIE[0] + prev_rsn_length, pIe,
11060 pIe[1] + 2);
11061 else
11062 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11063 pConfig->RSNWPAReqIELength);
11064
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 }
11066 else
11067 {
11068 pConfig->RSNWPAReqIELength = pIe[1] + 2;
Kapil Gupta137ef892016-12-13 19:38:00 +053011069 if (pConfig->RSNWPAReqIELength <= sizeof(pConfig->RSNWPAReqIE))
11070 memcpy(&pConfig->RSNWPAReqIE[0], pIe,
11071 pConfig->RSNWPAReqIELength);
11072 else
11073 hddLog(LOGE, "RSNWPA IE MAX Length exceeded; length =%d",
11074 pConfig->RSNWPAReqIELength);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011075 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
11077 &RSNEncryptType,
11078 &mcRSNEncryptType,
11079 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -080011080 &MFPCapable,
11081 &MFPRequired,
Kapil Gupta137ef892016-12-13 19:38:00 +053011082 pConfig->RSNWPAReqIE[1]+2,
11083 pConfig->RSNWPAReqIE);
Jeff Johnson295189b2012-06-20 16:38:30 -070011084
11085 if( VOS_STATUS_SUCCESS == status )
11086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011087 /* Now copy over all the security attributes you have
11088 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -070011089 * */
11090 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
11091 pConfig->mcRSNEncryptType = mcRSNEncryptType;
11092 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
11093 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +053011094 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011095 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
11097 }
11098 }
11099 }
11100
Kapil Gupta137ef892016-12-13 19:38:00 +053011101 if (pConfig->RSNWPAReqIELength > sizeof(pConfig->RSNWPAReqIE)) {
Jeff Johnson4416a782013-03-25 14:17:50 -070011102 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011103 ret = -EINVAL;
11104 goto error;
Jeff Johnson4416a782013-03-25 14:17:50 -070011105 }
11106
Jeff Johnson295189b2012-06-20 16:38:30 -070011107 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
11108
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011109#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011110 if (params->ssid != NULL)
11111 {
11112 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
11113 pConfig->SSIDinfo.ssid.length = params->ssid_len;
11114 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11115 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11116 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011117#else
11118 if (ssid != NULL)
11119 {
11120 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
11121 pConfig->SSIDinfo.ssid.length = ssid_len;
11122 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
11123 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
11124 }
11125#endif
11126
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011127 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -070011128 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011129
Jeff Johnson295189b2012-06-20 16:38:30 -070011130 /* default value */
11131 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
11132 pConfig->num_accept_mac = 0;
11133 pConfig->num_deny_mac = 0;
11134
11135 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11136 pBeacon->tail, pBeacon->tail_len);
11137
11138 /* pIe for black list is following form:
11139 type : 1 byte
11140 length : 1 byte
11141 OUI : 4 bytes
11142 acl type : 1 byte
11143 no of mac addr in black list: 1 byte
11144 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011145 */
11146 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 {
11148 pConfig->SapMacaddr_acl = pIe[6];
11149 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011150 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011151 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011152 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
11153 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011154 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11155 for (i = 0; i < pConfig->num_deny_mac; i++)
11156 {
11157 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11158 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011159 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011160 }
11161 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
11162 pBeacon->tail, pBeacon->tail_len);
11163
11164 /* pIe for white list is following form:
11165 type : 1 byte
11166 length : 1 byte
11167 OUI : 4 bytes
11168 acl type : 1 byte
11169 no of mac addr in white list: 1 byte
11170 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011171 */
11172 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011173 {
11174 pConfig->SapMacaddr_acl = pIe[6];
11175 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -080011176 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011177 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011178 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
11179 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
11181 for (i = 0; i < pConfig->num_accept_mac; i++)
11182 {
11183 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
11184 acl_entry++;
11185 }
11186 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053011187
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 wlan_hdd_set_sapHwmode(pHostapdAdapter);
11189
Jeff Johnsone7245742012-09-05 17:12:55 -070011190#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011191 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011192 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
11193 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +053011194 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
11195 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -080011196 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
11197 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +053011198 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
11199 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -070011200 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011201 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -070011202 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011203 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011204
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011205 /* If ACS disable and selected channel <= 14
11206 * OR
11207 * ACS enabled and ACS operating band is choosen as 2.4
11208 * AND
11209 * VHT in 2.4G Disabled
11210 * THEN
11211 * Fallback to 11N mode
11212 */
11213 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
11214 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +053011215 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +053011216 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011217 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +053011218 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
11219 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -070011220 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
11221 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011222 }
11223#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011224
Jeff Johnson295189b2012-06-20 16:38:30 -070011225 // ht_capab is not what the name conveys,this is used for protection bitmap
11226 pConfig->ht_capab =
11227 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
11228
Kapil Gupta137ef892016-12-13 19:38:00 +053011229 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter))
Jeff Johnson295189b2012-06-20 16:38:30 -070011230 {
11231 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011232 ret = -EINVAL;
11233 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011234 }
11235
11236 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011237 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
11239 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011240 pConfig->obssProtEnabled =
11241 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -070011242
Chet Lanctot8cecea22014-02-11 19:09:36 -080011243#ifdef WLAN_FEATURE_11W
11244 pConfig->mfpCapable = MFPCapable;
11245 pConfig->mfpRequired = MFPRequired;
11246 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
11247 pConfig->mfpCapable, pConfig->mfpRequired);
11248#endif
11249
Arif Hussain6d2a3322013-11-17 19:50:10 -080011250 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011252 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
11253 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
11254 (int)pConfig->channel);
11255 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
11256 pConfig->SapHw_mode, pConfig->privacy,
11257 pConfig->authType);
11258 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
11259 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
11260 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
11261 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -070011262
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011263 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -070011264 {
11265 //Bss already started. just return.
11266 //TODO Probably it should update some beacon params.
11267 hddLog( LOGE, "Bss Already started...Ignore the request");
11268 EXIT();
11269 return 0;
11270 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011271
Agarwal Ashish51325b52014-06-16 16:50:49 +053011272 if (vos_max_concurrent_connections_reached()) {
11273 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011274 ret = -EINVAL;
11275 goto error;
Agarwal Ashish51325b52014-06-16 16:50:49 +053011276 }
11277
Jeff Johnson295189b2012-06-20 16:38:30 -070011278 pConfig->persona = pHostapdAdapter->device_mode;
11279
Peng Xu2446a892014-09-05 17:21:18 +053011280 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
11281 if ( NULL != psmeConfig)
11282 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011283 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +053011284 sme_GetConfigParam(hHal, psmeConfig);
11285 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011286#ifdef WLAN_FEATURE_AP_HT40_24G
11287 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11288 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
11289 && pHddCtx->cfg_ini->apHT40_24GEnabled)
11290 {
11291 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
11292 sme_UpdateConfig (hHal, psmeConfig);
11293 }
11294#endif
Peng Xu2446a892014-09-05 17:21:18 +053011295 vos_mem_free(psmeConfig);
11296 }
Peng Xuafc34e32014-09-25 13:23:55 +053011297 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +053011298
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011299 set_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11300
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 pSapEventCallback = hdd_hostapd_SAPEventCB;
11302 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
11303 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
11304 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011305 hddLog(LOGE,FL("SAP Start Bss fail"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011306 ret = -EINVAL;
11307 goto error;
Jeff Johnson295189b2012-06-20 16:38:30 -070011308 }
11309
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011310 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -070011311 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
11312
11313 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011314
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011316 {
11317 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011318 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -070011319 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 VOS_ASSERT(0);
11321 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011322
Jeff Johnson295189b2012-06-20 16:38:30 -070011323 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053011324 if (WLANSAP_get_sessionId(pVosContext, &pHostapdAdapter->sessionId) !=
11325 VOS_STATUS_SUCCESS)
11326 {
11327 hddLog(LOGE,FL("Fail to get Softap sessionID"));
11328 VOS_ASSERT(0);
11329 }
Kaushik, Sushantf6070802014-10-15 15:09:23 +053011330 /* Initialize WMM configuation */
11331 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011332 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011333
Anurag Chouhan83026002016-12-13 22:46:21 +053011334#ifdef DHCP_SERVER_OFFLOAD
11335 /* set dhcp server offload */
11336 if (iniConfig->enable_dhcp_srv_offload &&
11337 sme_IsFeatureSupportedByFW(SAP_OFFLOADS)) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011338 vos_event_reset(&pHostapdAdapter->dhcp_status.vos_event);
Anurag Chouhan638f5e22017-03-06 12:28:43 +053011339 status = wlan_hdd_set_dhcp_server_offload(pHostapdAdapter, false);
Anurag Chouhan83026002016-12-13 22:46:21 +053011340 if (!VOS_IS_STATUS_SUCCESS(status))
11341 {
11342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11343 ("HDD DHCP Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011344 vos_event_reset(&pHostapdState->vosEvent);
11345 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11346 status = vos_wait_single_event(&pHostapdState->vosEvent,
11347 10000);
11348 if (!VOS_IS_STATUS_SUCCESS(status)) {
11349 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011350 ret = -EINVAL;
11351 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011352 }
11353 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011354 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011355 status = vos_wait_single_event(&pHostapdAdapter->dhcp_status.vos_event, 2000);
11356 if (!VOS_IS_STATUS_SUCCESS(status) || pHostapdAdapter->dhcp_status.dhcp_offload_status)
11357 {
11358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11359 ("ERROR: DHCP HDD vos wait for single_event failed!! %d"),
11360 pHostapdAdapter->dhcp_status.dhcp_offload_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011361 vos_event_reset(&pHostapdState->vosEvent);
11362 if (VOS_STATUS_SUCCESS == WLANSAP_StopBss(pHddCtx->pvosContext)) {
11363 status = vos_wait_single_event(&pHostapdState->vosEvent,
11364 10000);
11365 if (!VOS_IS_STATUS_SUCCESS(status)) {
11366 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011367 ret = -EINVAL;
11368 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011369 }
11370 }
Anurag Chouhan83026002016-12-13 22:46:21 +053011371 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011372#ifdef MDNS_OFFLOAD
11373 if (iniConfig->enable_mdns_offload) {
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011374 vos_event_reset(&pHostapdAdapter->mdns_status.vos_event);
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011375 status = wlan_hdd_set_mdns_offload(pHostapdAdapter);
11376 if (VOS_IS_STATUS_SUCCESS(status))
11377 {
11378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11379 ("HDD MDNS Server Offload Failed!!"));
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011380 vos_event_reset(&pHostapdState->vosEvent);
11381 if (VOS_STATUS_SUCCESS ==
11382 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11383 status = vos_wait_single_event(&pHostapdState->vosEvent,
11384 10000);
11385 if (!VOS_IS_STATUS_SUCCESS(status)) {
11386 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011387 ret = -EINVAL;
11388 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011389 }
11390 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011391 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011392 status = vos_wait_single_event(&pHostapdAdapter->
11393 mdns_status.vos_event, 2000);
11394 if (!VOS_IS_STATUS_SUCCESS(status) ||
11395 pHostapdAdapter->mdns_status.mdns_enable_status ||
11396 pHostapdAdapter->mdns_status.mdns_fqdn_status ||
11397 pHostapdAdapter->mdns_status.mdns_resp_status)
11398 {
11399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11400 ("MDNS HDD vos wait for single_event failed!! enable %d fqdn %d resp %d"),
11401 pHostapdAdapter->mdns_status.mdns_enable_status,
11402 pHostapdAdapter->mdns_status.mdns_fqdn_status,
11403 pHostapdAdapter->mdns_status.mdns_resp_status);
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011404 vos_event_reset(&pHostapdState->vosEvent);
11405 if (VOS_STATUS_SUCCESS ==
11406 WLANSAP_StopBss(pHddCtx->pvosContext)) {
11407 status = vos_wait_single_event(&pHostapdState->vosEvent,
11408 10000);
11409 if (!VOS_IS_STATUS_SUCCESS(status)) {
11410 hddLog(LOGE, FL("SAP Stop Failed"));
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011411 ret = -EINVAL;
11412 goto error;
Anurag Chouhanb2951ae2017-03-12 13:41:35 +053011413 }
11414 }
Anurag Chouhan0b29de02016-12-16 13:18:40 +053011415 }
11416 }
11417#endif /* MDNS_OFFLOAD */
11418 } else {
11419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11420 ("DHCP Disabled ini %d, FW %d"),
11421 iniConfig->enable_dhcp_srv_offload,
11422 sme_IsFeatureSupportedByFW(SAP_OFFLOADS));
Anurag Chouhan83026002016-12-13 22:46:21 +053011423 }
11424#endif /* DHCP_SERVER_OFFLOAD */
11425
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011426#ifdef WLAN_FEATURE_P2P_DEBUG
11427 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
11428 {
11429 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
11430 {
11431 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11432 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011433 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011434 }
11435 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
11436 {
11437 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
11438 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -080011439 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011440 }
11441 }
11442#endif
Ashish Kumar Dhanotiya42aa5152017-01-03 20:25:57 +053011443 /* Check and restart SAP if it is on Unsafe channel */
11444 hdd_check_for_unsafe_ch(pHostapdAdapter, pHddCtx);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011445
Jeff Johnson295189b2012-06-20 16:38:30 -070011446 pHostapdState->bCommit = TRUE;
11447 EXIT();
11448
11449 return 0;
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011450error:
Ashish Kumar Dhanotiya32d092b2018-02-20 21:43:57 +053011451 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
11452 wlan_hdd_restore_channels(pHddCtx);
Sourav Mohapatra5817dc42017-12-18 17:45:16 +053011453 /* Revert the indoor to passive marking if START BSS fails */
11454 if (iniConfig->disable_indoor_channel) {
11455 hdd_update_indoor_channel(pHddCtx, false);
11456 sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
11457 }
11458
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011459 clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
11460 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011461}
11462
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011463#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011464static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011465 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 struct beacon_parameters *params)
11467{
11468 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011469 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011470 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011471
11472 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011473
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011474 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11475 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
11476 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011477 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
11478 hdd_device_modetoString(pAdapter->device_mode),
11479 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011480
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011481 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11482 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011483 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011484 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011485 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011486 }
11487
Agarwal Ashish51325b52014-06-16 16:50:49 +053011488 if (vos_max_concurrent_connections_reached()) {
11489 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
11490 return -EINVAL;
11491 }
11492
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011493 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011494 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 )
11496 {
11497 beacon_data_t *old,*new;
11498
11499 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011500
Jeff Johnson295189b2012-06-20 16:38:30 -070011501 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011502 {
11503 hddLog(VOS_TRACE_LEVEL_WARN,
11504 FL("already beacon info added to session(%d)"),
11505 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011507 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011508
11509 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11510
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011511 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 {
11513 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011514 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 return -EINVAL;
11516 }
11517
11518 pAdapter->sessionCtx.ap.beacon = new;
11519
11520 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11521 }
11522
11523 EXIT();
11524 return status;
11525}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011526
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011527static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
11528 struct net_device *dev,
11529 struct beacon_parameters *params)
11530{
11531 int ret;
11532
11533 vos_ssr_protect(__func__);
11534 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
11535 vos_ssr_unprotect(__func__);
11536
11537 return ret;
11538}
11539
11540static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011541 struct net_device *dev,
11542 struct beacon_parameters *params)
11543{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011544 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011545 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11546 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011547 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011548
11549 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011550
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011551 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11552 TRACE_CODE_HDD_CFG80211_SET_BEACON,
11553 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
11554 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11555 __func__, hdd_device_modetoString(pAdapter->device_mode),
11556 pAdapter->device_mode);
11557
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011558 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11559 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011560 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011561 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011562 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011563 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011564
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011565 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011567 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 {
11569 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011570
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011572
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011574 {
11575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11576 FL("session(%d) old and new heads points to NULL"),
11577 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011579 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011580
11581 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
11582
11583 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011584 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011585 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 return -EINVAL;
11587 }
11588
11589 pAdapter->sessionCtx.ap.beacon = new;
11590
11591 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
11592 }
11593
11594 EXIT();
11595 return status;
11596}
11597
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011598static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
11599 struct net_device *dev,
11600 struct beacon_parameters *params)
11601{
11602 int ret;
11603
11604 vos_ssr_protect(__func__);
11605 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
11606 vos_ssr_unprotect(__func__);
11607
11608 return ret;
11609}
11610
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011611#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11612
11613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011614static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011615 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011616#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011617static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011618 struct net_device *dev)
11619#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011620{
11621 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -070011622 hdd_context_t *pHddCtx = NULL;
11623 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011624 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011625 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070011626
11627 ENTER();
11628
11629 if (NULL == pAdapter)
11630 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011632 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 return -ENODEV;
11634 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011635
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11637 TRACE_CODE_HDD_CFG80211_STOP_AP,
11638 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011639 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11640 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011641 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011642 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011643 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -070011644 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011645
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011646 pScanInfo = &pHddCtx->scan_info;
11647
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011648 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11649 __func__, hdd_device_modetoString(pAdapter->device_mode),
11650 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011651
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011652 ret = wlan_hdd_scan_abort(pAdapter);
11653
Girish Gowli4bf7a632014-06-12 13:42:11 +053011654 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -070011655 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11657 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011658
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011659 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -070011660 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11662 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -080011663
Jeff Johnsone7245742012-09-05 17:12:55 -070011664 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011665 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -070011666 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053011667 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011668 }
11669
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +053011670 /* Delete all associated STAs before stopping AP/P2P GO */
11671 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +053011672 hdd_hostapd_stop(dev);
11673
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070011676 )
11677 {
11678 beacon_data_t *old;
11679
11680 old = pAdapter->sessionCtx.ap.beacon;
11681
11682 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011683 {
11684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11685 FL("session(%d) beacon data points to NULL"),
11686 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -070011687 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011689
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011691
11692 mutex_lock(&pHddCtx->sap_lock);
11693 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
11694 {
Jeff Johnson4416a782013-03-25 14:17:50 -070011695 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 {
11697 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11698
11699 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
11700
11701 if (!VOS_IS_STATUS_SUCCESS(status))
11702 {
11703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011704 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -070011705 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011706 }
11707 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +053011709 /* BSS stopped, clear the active sessions for this device mode */
11710 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011711 }
11712 mutex_unlock(&pHddCtx->sap_lock);
11713
11714 if(status != VOS_STATUS_SUCCESS)
11715 {
11716 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011717 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011718 return -EINVAL;
11719 }
11720
Jeff Johnson4416a782013-03-25 14:17:50 -070011721 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
11723 ==eHAL_STATUS_FAILURE)
11724 {
11725 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011726 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 }
11728
Jeff Johnson4416a782013-03-25 14:17:50 -070011729 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
11731 eANI_BOOLEAN_FALSE) )
11732 {
11733 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011734 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -070011735 }
11736
11737 // Reset WNI_CFG_PROBE_RSP Flags
11738 wlan_hdd_reset_prob_rspies(pAdapter);
11739
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011740 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11741
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 pAdapter->sessionCtx.ap.beacon = NULL;
11743 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -070011744#ifdef WLAN_FEATURE_P2P_DEBUG
11745 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
11746 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
11747 {
11748 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
11749 "GO got removed");
11750 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
11751 }
11752#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011753 }
11754 EXIT();
11755 return status;
11756}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011757
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011758#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11759static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
11760 struct net_device *dev)
11761{
11762 int ret;
11763
11764 vos_ssr_protect(__func__);
11765 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
11766 vos_ssr_unprotect(__func__);
11767
11768 return ret;
11769}
11770#else
11771static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
11772 struct net_device *dev)
11773{
11774 int ret;
11775
11776 vos_ssr_protect(__func__);
11777 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
11778 vos_ssr_unprotect(__func__);
11779
11780 return ret;
11781}
11782#endif
11783
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011784#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
11785
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011786static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011787 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011788 struct cfg80211_ap_settings *params)
11789{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011790 hdd_adapter_t *pAdapter;
11791 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011792 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011793
11794 ENTER();
11795
Girish Gowlib143d7a2015-02-18 19:39:55 +053011796 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011797 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011798 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +053011799 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011800 return -ENODEV;
11801 }
11802
11803 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
11804 if (NULL == pAdapter)
11805 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011807 "%s: HDD adapter is Null", __func__);
11808 return -ENODEV;
11809 }
11810
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011811 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11812 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
11813 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011814 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
11815 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011816 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011817 "%s: HDD adapter magic is invalid", __func__);
11818 return -ENODEV;
11819 }
11820
Hanumanth Reddy Pothula1428c612017-03-06 11:35:34 +053011821 clear_bit(SOFTAP_INIT_DONE, &pAdapter->event_flags);
11822
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011823 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011824 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011825 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011826 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011827 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011828 }
11829
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011830 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
11831 __func__, hdd_device_modetoString(pAdapter->device_mode),
11832 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011833
11834 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011835 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011836 )
11837 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011838 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011839
11840 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011841
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011842 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011843 {
11844 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
11845 FL("already beacon info added to session(%d)"),
11846 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011847 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011848 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011849
Girish Gowlib143d7a2015-02-18 19:39:55 +053011850#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
11851 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11852 &new,
11853 &params->beacon);
11854#else
11855 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
11856 &new,
11857 &params->beacon,
11858 params->dtim_period);
11859#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011860
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011861 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011862 {
11863 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +053011864 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011865 return -EINVAL;
11866 }
11867 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -080011868#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -070011869 wlan_hdd_cfg80211_set_channel(wiphy, dev,
11870#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
11871 params->channel, params->channel_type);
11872#else
11873 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
11874#endif
Viral Modi3a32cc52013-02-08 11:14:52 -080011875#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011876 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011877 params->ssid_len, params->hidden_ssid,
11878 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011879 }
11880
11881 EXIT();
11882 return status;
11883}
11884
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011885static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
11886 struct net_device *dev,
11887 struct cfg80211_ap_settings *params)
11888{
11889 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011890
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011891 vos_ssr_protect(__func__);
11892 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
11893 vos_ssr_unprotect(__func__);
11894
11895 return ret;
11896}
11897
11898static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011899 struct net_device *dev,
11900 struct cfg80211_beacon_data *params)
11901{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011902 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011903 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011904 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011905
11906 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011907
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011908 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11909 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
11910 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080011911 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011912 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011913
11914 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11915 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011916 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011917 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011918 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070011919 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011920
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011921 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011922 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011923 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011924 {
11925 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011926
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011927 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011928
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011929 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011930 {
11931 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11932 FL("session(%d) beacon data points to NULL"),
11933 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011934 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011935 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011936
11937 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
11938
11939 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011941 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011942 return -EINVAL;
11943 }
11944
11945 pAdapter->sessionCtx.ap.beacon = new;
11946
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053011947 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
11948 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011949 }
11950
11951 EXIT();
11952 return status;
11953}
11954
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011955static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
11956 struct net_device *dev,
11957 struct cfg80211_beacon_data *params)
11958{
11959 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011960
Mukul Sharmab0e0a982014-12-15 18:58:53 +053011961 vos_ssr_protect(__func__);
11962 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
11963 vos_ssr_unprotect(__func__);
11964
11965 return ret;
11966}
11967
11968#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070011969
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053011970static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011971 struct net_device *dev,
11972 struct bss_parameters *params)
11973{
11974 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011975 hdd_context_t *pHddCtx;
11976 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011977
11978 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011979
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011980 if (NULL == pAdapter)
11981 {
11982 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11983 "%s: HDD adapter is Null", __func__);
11984 return -ENODEV;
11985 }
11986 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011987 ret = wlan_hdd_validate_context(pHddCtx);
11988 if (0 != ret)
11989 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011990 return ret;
11991 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011992 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11993 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
11994 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011995 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11996 __func__, hdd_device_modetoString(pAdapter->device_mode),
11997 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011998
11999 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012001 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 {
12003 /* ap_isolate == -1 means that in change bss, upper layer doesn't
12004 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012005 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 {
12007 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012008 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012009 }
12010
12011 EXIT();
12012 return 0;
12013}
12014
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012015static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
12016 struct net_device *dev,
12017 struct bss_parameters *params)
12018{
12019 int ret;
12020
12021 vos_ssr_protect(__func__);
12022 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
12023 vos_ssr_unprotect(__func__);
12024
12025 return ret;
12026}
Kiet Lam10841362013-11-01 11:36:50 +053012027/* FUNCTION: wlan_hdd_change_country_code_cd
12028* to wait for contry code completion
12029*/
12030void* wlan_hdd_change_country_code_cb(void *pAdapter)
12031{
12032 hdd_adapter_t *call_back_pAdapter = pAdapter;
12033 complete(&call_back_pAdapter->change_country_code);
12034 return NULL;
12035}
12036
Jeff Johnson295189b2012-06-20 16:38:30 -070012037/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012038 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070012039 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
12040 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012041int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012042 struct net_device *ndev,
12043 enum nl80211_iftype type,
12044 u32 *flags,
12045 struct vif_params *params
12046 )
12047{
12048 struct wireless_dev *wdev;
12049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012050 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070012051 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012052 tCsrRoamProfile *pRoamProfile = NULL;
12053 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012054 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012055 eMib_dot11DesiredBssType connectedBssType;
12056 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012057 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070012058
12059 ENTER();
12060
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012061 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012062 {
12063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12064 "%s: Adapter context is null", __func__);
12065 return VOS_STATUS_E_FAILURE;
12066 }
12067
12068 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12069 if (!pHddCtx)
12070 {
12071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12072 "%s: HDD context is null", __func__);
12073 return VOS_STATUS_E_FAILURE;
12074 }
12075
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012076 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12077 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
12078 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012079 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012080 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012081 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012082 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 }
12084
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012085 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12086 __func__, hdd_device_modetoString(pAdapter->device_mode),
12087 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012088
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053012089 if (pHddCtx->concurrency_mode == VOS_STA_MON) {
12090 hddLog(VOS_TRACE_LEVEL_FATAL,
12091 "%s: STA + MON is in progress, cannot change interface",
12092 __func__);
12093 }
12094
Agarwal Ashish51325b52014-06-16 16:50:49 +053012095 if (vos_max_concurrent_connections_reached()) {
12096 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12097 return -EINVAL;
12098 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012099 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070012100 wdev = ndev->ieee80211_ptr;
12101
12102#ifdef WLAN_BTAMP_FEATURE
12103 if((NL80211_IFTYPE_P2P_CLIENT == type)||
12104 (NL80211_IFTYPE_ADHOC == type)||
12105 (NL80211_IFTYPE_AP == type)||
12106 (NL80211_IFTYPE_P2P_GO == type))
12107 {
12108 pHddCtx->isAmpAllowed = VOS_FALSE;
12109 // stop AMP traffic
12110 status = WLANBAP_StopAmp();
12111 if(VOS_STATUS_SUCCESS != status )
12112 {
12113 pHddCtx->isAmpAllowed = VOS_TRUE;
12114 hddLog(VOS_TRACE_LEVEL_FATAL,
12115 "%s: Failed to stop AMP", __func__);
12116 return -EINVAL;
12117 }
12118 }
12119#endif //WLAN_BTAMP_FEATURE
12120 /* Reset the current device mode bit mask*/
12121 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
12122
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053012123 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
12124 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
12125 (type == NL80211_IFTYPE_P2P_GO)))
12126 {
12127 /* Notify Mode change in case of concurrency.
12128 * Below function invokes TDLS teardown Functionality Since TDLS is
12129 * not Supported in case of concurrency i.e Once P2P session
12130 * is detected disable offchannel and teardown TDLS links
12131 */
12132 hddLog(LOG1,
12133 FL("Device mode = %d Interface type = %d"),
12134 pAdapter->device_mode, type);
12135 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
12136 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053012137
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070012139 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070012140 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 )
12142 {
12143 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012144 if (!pWextState)
12145 {
12146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12147 "%s: pWextState is null", __func__);
12148 return VOS_STATUS_E_FAILURE;
12149 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012150 pRoamProfile = &pWextState->roamProfile;
12151 LastBSSType = pRoamProfile->BSSType;
12152
12153 switch (type)
12154 {
12155 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012156 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 hddLog(VOS_TRACE_LEVEL_INFO,
12158 "%s: setting interface Type to INFRASTRUCTURE", __func__);
12159 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012160#ifdef WLAN_FEATURE_11AC
12161 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
12162 {
12163 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
12164 }
12165#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070012167 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012168 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012169 //Check for sub-string p2p to confirm its a p2p interface
12170 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012171 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053012172#ifdef FEATURE_WLAN_TDLS
12173 mutex_lock(&pHddCtx->tdls_lock);
12174 wlan_hdd_tdls_exit(pAdapter, TRUE);
12175 mutex_unlock(&pHddCtx->tdls_lock);
12176#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012177 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12178 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12179 }
12180 else
12181 {
12182 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012183 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012184 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012185 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053012186
Jeff Johnson295189b2012-06-20 16:38:30 -070012187 case NL80211_IFTYPE_ADHOC:
12188 hddLog(VOS_TRACE_LEVEL_INFO,
12189 "%s: setting interface Type to ADHOC", __func__);
12190 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
12191 pRoamProfile->phyMode =
12192 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070012193 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053012195 hdd_set_ibss_ops( pAdapter );
12196 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053012197
12198 status = hdd_sta_id_hash_attach(pAdapter);
12199 if (VOS_STATUS_SUCCESS != status) {
12200 hddLog(VOS_TRACE_LEVEL_ERROR,
12201 FL("Failed to initialize hash for IBSS"));
12202 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012203 break;
12204
12205 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012206 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012207 {
12208 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12209 "%s: setting interface Type to %s", __func__,
12210 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
12211
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012212 //Cancel any remain on channel for GO mode
12213 if (NL80211_IFTYPE_P2P_GO == type)
12214 {
12215 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
12216 }
Mohit Khanna0f232092012-09-11 14:46:08 -070012217 if (NL80211_IFTYPE_AP == type)
12218 {
12219 /* As Loading WLAN Driver one interface being created for p2p device
12220 * address. This will take one HW STA and the max number of clients
12221 * that can connect to softAP will be reduced by one. so while changing
12222 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
12223 * interface as it is not required in SoftAP mode.
12224 */
12225
12226 // Get P2P Adapter
12227 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
12228
12229 if (pP2pAdapter)
12230 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053012231 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053012232 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070012233 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
12234 }
12235 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053012236 //Disable IMPS & BMPS for SAP/GO
12237 if(VOS_STATUS_E_FAILURE ==
12238 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
12239 {
12240 //Fail to Exit BMPS
12241 VOS_ASSERT(0);
12242 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053012243
12244 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
12245
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012246#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070012247
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012248 /* A Mutex Lock is introduced while changing the mode to
12249 * protect the concurrent access for the Adapters by TDLS
12250 * module.
12251 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012252 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012253#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053012255 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012256 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070012257 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12258 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012259#ifdef FEATURE_WLAN_TDLS
12260 mutex_unlock(&pHddCtx->tdls_lock);
12261#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012262 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
12263 (pConfig->apRandomBssidEnabled))
12264 {
12265 /* To meet Android requirements create a randomized
12266 MAC address of the form 02:1A:11:Fx:xx:xx */
12267 get_random_bytes(&ndev->dev_addr[3], 3);
12268 ndev->dev_addr[0] = 0x02;
12269 ndev->dev_addr[1] = 0x1A;
12270 ndev->dev_addr[2] = 0x11;
12271 ndev->dev_addr[3] |= 0xF0;
12272 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
12273 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080012274 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
12275 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070012276 }
12277
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 hdd_set_ap_ops( pAdapter->dev );
12279
Kiet Lam10841362013-11-01 11:36:50 +053012280 /* This is for only SAP mode where users can
12281 * control country through ini.
12282 * P2P GO follows station country code
12283 * acquired during the STA scanning. */
12284 if((NL80211_IFTYPE_AP == type) &&
12285 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
12286 {
12287 int status = 0;
12288 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
12289 "%s: setting country code from INI ", __func__);
12290 init_completion(&pAdapter->change_country_code);
12291 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
12292 (void *)(tSmeChangeCountryCallback)
12293 wlan_hdd_change_country_code_cb,
12294 pConfig->apCntryCode, pAdapter,
12295 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053012296 eSIR_FALSE,
12297 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053012298 if (eHAL_STATUS_SUCCESS == status)
12299 {
12300 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012301 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053012302 &pAdapter->change_country_code,
12303 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012304 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053012305 {
12306 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012307 FL("SME Timed out while setting country code %ld"),
12308 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080012309
12310 if (pHddCtx->isLogpInProgress)
12311 {
12312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12313 "%s: LOGP in Progress. Ignore!!!", __func__);
12314 return -EAGAIN;
12315 }
Kiet Lam10841362013-11-01 11:36:50 +053012316 }
12317 }
12318 else
12319 {
12320 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012321 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053012322 return -EINVAL;
12323 }
12324 }
Hanumanth Reddy Pothula15bc0fa2017-02-03 17:24:17 +053012325 status = hdd_init_ap_mode(pAdapter, false);
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 if(status != VOS_STATUS_SUCCESS)
12327 {
12328 hddLog(VOS_TRACE_LEVEL_FATAL,
12329 "%s: Error initializing the ap mode", __func__);
12330 return -EINVAL;
12331 }
12332 hdd_set_conparam(1);
12333
Nirav Shah7e3c8132015-06-22 23:51:42 +053012334 status = hdd_sta_id_hash_attach(pAdapter);
12335 if (VOS_STATUS_SUCCESS != status)
12336 {
12337 hddLog(VOS_TRACE_LEVEL_ERROR,
12338 FL("Failed to initialize hash for AP"));
12339 return -EINVAL;
12340 }
12341
Jeff Johnson295189b2012-06-20 16:38:30 -070012342 /*interface type changed update in wiphy structure*/
12343 if(wdev)
12344 {
12345 wdev->iftype = type;
12346 pHddCtx->change_iface = type;
12347 }
12348 else
12349 {
12350 hddLog(VOS_TRACE_LEVEL_ERROR,
12351 "%s: ERROR !!!! Wireless dev is NULL", __func__);
12352 return -EINVAL;
12353 }
12354 goto done;
12355 }
12356
12357 default:
12358 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12359 __func__);
12360 return -EOPNOTSUPP;
12361 }
12362 }
12363 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012364 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 )
12366 {
12367 switch(type)
12368 {
12369 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070012370 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053012372
12373 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012374#ifdef FEATURE_WLAN_TDLS
12375
12376 /* A Mutex Lock is introduced while changing the mode to
12377 * protect the concurrent access for the Adapters by TDLS
12378 * module.
12379 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012380 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012381#endif
c_hpothu002231a2015-02-05 14:58:51 +053012382 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080012384 //Check for sub-string p2p to confirm its a p2p interface
12385 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012386 {
12387 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
12388 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
12389 }
12390 else
12391 {
12392 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080012394 }
Agrawal Ashishcfe83282016-09-29 13:03:45 +053012395
12396 /* set con_mode to STA only when no SAP concurrency mode */
12397 if (!(hdd_get_concurrency_mode() & (VOS_SAP | VOS_P2P_GO)))
12398 hdd_set_conparam(0);
Jeff Johnson295189b2012-06-20 16:38:30 -070012399 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
12401 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053012402#ifdef FEATURE_WLAN_TDLS
12403 mutex_unlock(&pHddCtx->tdls_lock);
12404#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053012405 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070012406 if( VOS_STATUS_SUCCESS != status )
12407 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070012408 /* In case of JB, for P2P-GO, only change interface will be called,
12409 * This is the right place to enable back bmps_imps()
12410 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012411 if (pHddCtx->hdd_wlan_suspended)
12412 {
12413 hdd_set_pwrparams(pHddCtx);
12414 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012415 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070012416 goto done;
12417 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070012419 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070012420 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
12421 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 goto done;
12423 default:
12424 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
12425 __func__);
12426 return -EOPNOTSUPP;
12427
12428 }
12429
12430 }
12431 else
12432 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012433 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
12434 __func__, hdd_device_modetoString(pAdapter->device_mode),
12435 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012436 return -EOPNOTSUPP;
12437 }
12438
12439
12440 if(pRoamProfile)
12441 {
12442 if ( LastBSSType != pRoamProfile->BSSType )
12443 {
12444 /*interface type changed update in wiphy structure*/
12445 wdev->iftype = type;
12446
12447 /*the BSS mode changed, We need to issue disconnect
12448 if connected or in IBSS disconnect state*/
12449 if ( hdd_connGetConnectedBssType(
12450 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
12451 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
12452 {
12453 /*need to issue a disconnect to CSR.*/
12454 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12455 if( eHAL_STATUS_SUCCESS ==
12456 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12457 pAdapter->sessionId,
12458 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12459 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012460 ret = wait_for_completion_interruptible_timeout(
12461 &pAdapter->disconnect_comp_var,
12462 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12463 if (ret <= 0)
12464 {
12465 hddLog(VOS_TRACE_LEVEL_ERROR,
12466 FL("wait on disconnect_comp_var failed %ld"), ret);
12467 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012468 }
12469 }
12470 }
12471 }
12472
12473done:
12474 /*set bitmask based on updated value*/
12475 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070012476
12477 /* Only STA mode support TM now
12478 * all other mode, TM feature should be disabled */
12479 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
12480 (~VOS_STA & pHddCtx->concurrency_mode) )
12481 {
12482 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
12483 }
12484
Jeff Johnson295189b2012-06-20 16:38:30 -070012485#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012486 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012487 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 {
12489 //we are ok to do AMP
12490 pHddCtx->isAmpAllowed = VOS_TRUE;
12491 }
12492#endif //WLAN_BTAMP_FEATURE
12493 EXIT();
12494 return 0;
12495}
12496
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053012497/*
12498 * FUNCTION: wlan_hdd_cfg80211_change_iface
12499 * wrapper function to protect the actual implementation from SSR.
12500 */
12501int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
12502 struct net_device *ndev,
12503 enum nl80211_iftype type,
12504 u32 *flags,
12505 struct vif_params *params
12506 )
12507{
12508 int ret;
12509
12510 vos_ssr_protect(__func__);
12511 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
12512 vos_ssr_unprotect(__func__);
12513
12514 return ret;
12515}
12516
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012517#ifdef FEATURE_WLAN_TDLS
12518static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012519 struct net_device *dev,
12520#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12521 const u8 *mac,
12522#else
12523 u8 *mac,
12524#endif
12525 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012526{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012527 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012528 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012529 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012530 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012531 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012532 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012533
12534 ENTER();
12535
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012536 if (!dev) {
12537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
12538 return -EINVAL;
12539 }
12540
12541 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
12542 if (!pAdapter) {
12543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
12544 return -EINVAL;
12545 }
12546
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012547 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012548 {
12549 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12550 "Invalid arguments");
12551 return -EINVAL;
12552 }
Hoonki Lee27511902013-03-14 18:19:06 -070012553
12554 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
12555 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
12556 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070012558 "%s: TDLS mode is disabled OR not enabled in FW."
12559 MAC_ADDRESS_STR " Request declined.",
12560 __func__, MAC_ADDR_ARRAY(mac));
12561 return -ENOTSUPP;
12562 }
12563
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012564 if (pHddCtx->isLogpInProgress)
12565 {
12566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12567 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053012568 wlan_hdd_tdls_set_link_status(pAdapter,
12569 mac,
12570 eTDLS_LINK_IDLE,
12571 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012572 return -EBUSY;
12573 }
12574
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012575 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053012576 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012577
12578 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012580 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
12581 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053012582 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012583 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012584 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012585
12586 /* in add station, we accept existing valid staId if there is */
12587 if ((0 == update) &&
12588 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
12589 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012590 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012591 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012592 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012593 " link_status %d. staId %d. add station ignored.",
12594 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012595 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012596 return 0;
12597 }
12598 /* in change station, we accept only when staId is valid */
12599 if ((1 == update) &&
12600 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
12601 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
12602 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012603 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012604 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012605 "%s: " MAC_ADDRESS_STR
12606 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012607 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
12608 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
12609 mutex_unlock(&pHddCtx->tdls_lock);
12610 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012611 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012612 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012613
12614 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053012615 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012616 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12618 "%s: " MAC_ADDRESS_STR
12619 " TDLS setup is ongoing. Request declined.",
12620 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070012621 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012622 }
12623
12624 /* first to check if we reached to maximum supported TDLS peer.
12625 TODO: for now, return -EPERM looks working fine,
12626 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012627 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
12628 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012629 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12631 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053012632 " TDLS Max peer already connected. Request declined."
12633 " Num of peers (%d), Max allowed (%d).",
12634 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
12635 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012636 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012637 }
12638 else
12639 {
12640 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012641 mutex_lock(&pHddCtx->tdls_lock);
12642 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012643 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012644 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012645 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12647 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
12648 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012649 return -EPERM;
12650 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053012651 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012652 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012653 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053012654 wlan_hdd_tdls_set_link_status(pAdapter,
12655 mac,
12656 eTDLS_LINK_CONNECTING,
12657 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012658
Jeff Johnsond75fe012013-04-06 10:53:06 -070012659 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012660 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012661 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012663 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012664 if(StaParams->htcap_present)
12665 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012667 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012669 "ht_capa->extended_capabilities: %0x",
12670 StaParams->HTCap.extendedHtCapInfo);
12671 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012673 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012675 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070012676 if(StaParams->vhtcap_present)
12677 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070012679 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
12680 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
12681 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
12682 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012683 {
12684 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012686 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012688 "[%d]: %x ", i, StaParams->supported_rates[i]);
12689 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070012690 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053012691 else if ((1 == update) && (NULL == StaParams))
12692 {
12693 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12694 "%s : update is true, but staParams is NULL. Error!", __func__);
12695 return -EPERM;
12696 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012697
12698 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
12699
12700 if (!update)
12701 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012702 /*Before adding sta make sure that device exited from BMPS*/
12703 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
12704 {
12705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12706 "%s: Adding tdls peer sta. Disable BMPS", __func__);
12707 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
12708 if (status != VOS_STATUS_SUCCESS) {
12709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
12710 }
12711 }
12712
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012713 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012714 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012715 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053012716 hddLog(VOS_TRACE_LEVEL_ERROR,
12717 FL("Failed to add TDLS peer STA. Enable Bmps"));
12718 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012719 return -EPERM;
12720 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012721 }
12722 else
12723 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012724 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012725 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012726 if (ret != eHAL_STATUS_SUCCESS) {
12727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
12728 return -EPERM;
12729 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012730 }
12731
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012732 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012733 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
12734
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012735 mutex_lock(&pHddCtx->tdls_lock);
12736 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
12737
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012738 if ((pTdlsPeer != NULL) &&
12739 (pTdlsPeer->link_status == eTDLS_LINK_TEARING))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012740 {
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012741 hddLog(VOS_TRACE_LEVEL_ERROR,
12742 FL("peer link status %u"), pTdlsPeer->link_status);
12743 mutex_unlock(&pHddCtx->tdls_lock);
12744 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012745 }
Masti, Narayanraddi255d8c52016-01-07 16:26:06 +053012746 mutex_unlock(&pHddCtx->tdls_lock);
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012747
Masti, Narayanraddi07262462016-01-19 12:40:06 +053012748 if (ret <= 0)
12749 {
12750 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12751 "%s: timeout waiting for tdls add station indication %ld",
12752 __func__, ret);
12753 goto error;
12754 }
12755
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012756 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
12757 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012759 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070012760 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012761 }
12762
12763 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070012764
12765error:
Atul Mittal115287b2014-07-08 13:26:33 +053012766 wlan_hdd_tdls_set_link_status(pAdapter,
12767 mac,
12768 eTDLS_LINK_IDLE,
12769 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070012770 return -EPERM;
12771
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012772}
12773#endif
12774
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012775VOS_STATUS wlan_hdd_send_sta_authorized_event(
12776 hdd_adapter_t *adapter,
12777 hdd_context_t *hdd_ctx,
12778 const v_MACADDR_t *mac_addr)
12779{
12780 struct sk_buff *vendor_event;
12781 uint32_t sta_flags = 0;
12782 VOS_STATUS status;
12783
12784 ENTER();
12785
12786 if (!hdd_ctx) {
12787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is null"));
12788 return -EINVAL;
12789 }
12790
12791 vendor_event =
12792 cfg80211_vendor_event_alloc(
12793 hdd_ctx->wiphy, &adapter->wdev, sizeof(sta_flags) +
12794 VOS_MAC_ADDR_SIZE + NLMSG_HDRLEN,
12795 QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES_INDEX,
12796 GFP_KERNEL);
12797 if (!vendor_event) {
12798 hddLog(VOS_TRACE_LEVEL_ERROR,
12799 FL("cfg80211_vendor_event_alloc failed"));
12800 return -EINVAL;
12801 }
12802
12803 sta_flags |= BIT(NL80211_STA_FLAG_AUTHORIZED);
12804
12805 status = nla_put_u32(vendor_event,
12806 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_FLAGS,
12807 sta_flags);
12808 if (status) {
12809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA flag put fails"));
12810 kfree_skb(vendor_event);
12811 return VOS_STATUS_E_FAILURE;
12812 }
12813 status = nla_put(vendor_event,
12814 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_STA_MAC,
12815 VOS_MAC_ADDR_SIZE, mac_addr->bytes);
12816 if (status) {
12817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("STA MAC put fails"));
12818 kfree_skb(vendor_event);
12819 return VOS_STATUS_E_FAILURE;
12820 }
12821
12822 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
12823
12824 EXIT();
12825 return 0;
12826}
12827
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053012828static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012829 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12831 const u8 *mac,
12832#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012833 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012834#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012835 struct station_parameters *params)
12836{
12837 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012838 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012839 hdd_context_t *pHddCtx;
12840 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012842 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012843#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012844 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012845 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012846 tANI_U8 isOffChannelSupported = 0;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053012847 tANI_U8 isQosWmmSta = FALSE;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070012848#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070012849
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012850 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012851
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053012852 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012853 if ((NULL == pAdapter))
12854 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053012856 "invalid adapter ");
12857 return -EINVAL;
12858 }
12859
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012860 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12861 TRACE_CODE_HDD_CHANGE_STATION,
12862 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053012863 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053012864
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012865 ret = wlan_hdd_validate_context(pHddCtx);
12866 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053012867 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012868 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053012869 }
12870
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012871 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12872
12873 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012874 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053012875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12876 "invalid HDD station context");
12877 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012878 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012879 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
12880
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012881 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
12882 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070012883 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012884 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012886 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070012887 WLANTL_STA_AUTHENTICATED);
12888
Gopichand Nakkala29149562013-05-10 21:43:41 +053012889 if (status != VOS_STATUS_SUCCESS)
12890 {
12891 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12892 "%s: Not able to change TL state to AUTHENTICATED", __func__);
12893 return -EINVAL;
12894 }
Hanumanth Reddy Pothula852449b2018-03-08 13:21:10 +053012895 status = wlan_hdd_send_sta_authorized_event(pAdapter, pHddCtx,
12896 &STAMacAddress);
12897 if (status != VOS_STATUS_SUCCESS)
12898 return -EINVAL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012899 }
12900 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070012901 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
12902 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053012903#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012904 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
12905 StaParams.capability = params->capability;
12906 StaParams.uapsd_queues = params->uapsd_queues;
12907 StaParams.max_sp = params->max_sp;
12908
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012909 /* Convert (first channel , number of channels) tuple to
12910 * the total list of channels. This goes with the assumption
12911 * that if the first channel is < 14, then the next channels
12912 * are an incremental of 1 else an incremental of 4 till the number
12913 * of channels.
12914 */
12915 if (0 != params->supported_channels_len) {
12916 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
12917 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
12918 {
12919 int wifi_chan_index;
12920 StaParams.supported_channels[j] = params->supported_channels[i];
12921 wifi_chan_index =
12922 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
12923 no_of_channels = params->supported_channels[i+1];
12924 for(k=1; k <= no_of_channels; k++)
12925 {
12926 StaParams.supported_channels[j+1] =
12927 StaParams.supported_channels[j] + wifi_chan_index;
12928 j+=1;
12929 }
12930 }
12931 StaParams.supported_channels_len = j;
12932 }
SaidiReddy Yenuga0f1a1592017-04-05 13:18:26 +053012933 if (params->supported_oper_classes_len >
12934 SIR_MAC_MAX_SUPP_OPER_CLASSES) {
12935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12936 "received oper classes:%d, resetting it to max supported %d",
12937 params->supported_oper_classes_len,
12938 SIR_MAC_MAX_SUPP_OPER_CLASSES);
12939 params->supported_oper_classes_len =
12940 SIR_MAC_MAX_SUPP_OPER_CLASSES;
12941 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012942 vos_mem_copy(StaParams.supported_oper_classes,
12943 params->supported_oper_classes,
12944 params->supported_oper_classes_len);
12945 StaParams.supported_oper_classes_len =
12946 params->supported_oper_classes_len;
12947
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012948 if (params->ext_capab_len > sizeof(StaParams.extn_capability)) {
12949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12950 "received extn capabilities:%d, resetting it to max supported",
12951 params->ext_capab_len);
12952 params->ext_capab_len = sizeof(StaParams.extn_capability);
12953 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012954 if (0 != params->ext_capab_len)
12955 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
SaidiReddy Yenuga96d8ca52017-06-06 13:01:29 +053012956 params->ext_capab_len);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012957
12958 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012959 {
12960 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012961 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012962 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012963
12964 StaParams.supported_rates_len = params->supported_rates_len;
12965
12966 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
12967 * The supported_rates array , for all the structures propogating till Add Sta
12968 * to the firmware has to be modified , if the supplicant (ieee80211) is
12969 * modified to send more rates.
12970 */
12971
12972 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
12973 */
12974 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
12975 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
12976
12977 if (0 != StaParams.supported_rates_len) {
12978 int i = 0;
12979 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
12980 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070012981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012982 "Supported Rates with Length %d", StaParams.supported_rates_len);
12983 for (i=0; i < StaParams.supported_rates_len; i++)
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 "[%d]: %0x", i, StaParams.supported_rates[i]);
12986 }
12987
12988 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070012989 {
12990 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012991 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070012992 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070012993
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012994 if (0 != params->ext_capab_len ) {
12995 /*Define A Macro : TODO Sunil*/
12996 if ((1<<4) & StaParams.extn_capability[3]) {
12997 isBufSta = 1;
12998 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053012999 /* TDLS Channel Switching Support */
13000 if ((1<<6) & StaParams.extn_capability[3]) {
13001 isOffChannelSupported = 1;
13002 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013003 }
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013004
13005 if (pHddCtx->cfg_ini->fEnableTDLSWmmMode &&
Nitesh Shah48df4c02016-08-12 16:27:33 +053013006 (params->ht_capa || params->vht_capa ||
13007 (params->sta_flags_set & BIT(NL80211_STA_FLAG_WME))))
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013008 /* TDLS Peer is WME/QoS capable */
13009 isQosWmmSta = TRUE;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013010
13011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13012 "%s: TDLS Peer is QOS capable isQosWmmSta= %d HTcapPresent= %d",
13013 __func__, isQosWmmSta, StaParams.htcap_present);
13014
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013015 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
13016 &StaParams, isBufSta,
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053013017 isOffChannelSupported,
13018 isQosWmmSta);
Naresh Jayaram3180aa42014-02-12 21:47:26 +053013019
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053013020 if (VOS_STATUS_SUCCESS != status) {
13021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13022 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
13023 return -EINVAL;
13024 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080013025 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
13026
13027 if (VOS_STATUS_SUCCESS != status) {
13028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13029 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
13030 return -EINVAL;
13031 }
13032 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070013033#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053013034 }
Jeff Johnsone7245742012-09-05 17:12:55 -070013035 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 return status;
13037}
13038
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13040static int wlan_hdd_change_station(struct wiphy *wiphy,
13041 struct net_device *dev,
13042 const u8 *mac,
13043 struct station_parameters *params)
13044#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013045static int wlan_hdd_change_station(struct wiphy *wiphy,
13046 struct net_device *dev,
13047 u8 *mac,
13048 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013049#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013050{
13051 int ret;
13052
13053 vos_ssr_protect(__func__);
13054 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
13055 vos_ssr_unprotect(__func__);
13056
13057 return ret;
13058}
13059
Jeff Johnson295189b2012-06-20 16:38:30 -070013060/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013061 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013062 * This function is used to initialize the key information
13063 */
13064#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013065static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013066 struct net_device *ndev,
13067 u8 key_index, bool pairwise,
13068 const u8 *mac_addr,
13069 struct key_params *params
13070 )
13071#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013072static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 struct net_device *ndev,
13074 u8 key_index, const u8 *mac_addr,
13075 struct key_params *params
13076 )
13077#endif
13078{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013080 tCsrRoamSetKey setKey;
13081 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013082 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013083 v_U32_t roamId= 0xFF;
13084 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013085 hdd_hostapd_state_t *pHostapdState;
13086 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013087 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013088 hdd_context_t *pHddCtx;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013089 uint8_t i;
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013090 v_MACADDR_t *peerMacAddr;
13091 u64 rsc_counter = 0;
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013092 uint8_t staid = HDD_MAX_STA_COUNT;
13093 bool pairwise_set_key = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070013094
13095 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013096
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013097 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13098 TRACE_CODE_HDD_CFG80211_ADD_KEY,
13099 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013100 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13101 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013102 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013103 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013104 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013105 }
13106
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013107 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13108 __func__, hdd_device_modetoString(pAdapter->device_mode),
13109 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013110
13111 if (CSR_MAX_NUM_KEY <= key_index)
13112 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013114 key_index);
13115
13116 return -EINVAL;
13117 }
13118
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013119 if (CSR_MAX_KEY_LEN < params->key_len)
13120 {
13121 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
13122 params->key_len);
13123
13124 return -EINVAL;
13125 }
13126
Jingxiang Gec438aea2017-10-26 16:44:00 +080013127 if (CSR_MAX_RSC_LEN < params->seq_len)
13128 {
13129 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: Invalid seq length %d", __func__,
13130 params->seq_len);
Ashish Kumar Dhanotiya9783b182017-12-08 14:50:46 +053013131
13132 return -EINVAL;
Jingxiang Gec438aea2017-10-26 16:44:00 +080013133 }
13134
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013135 hddLog(VOS_TRACE_LEVEL_INFO,
Jingxiang Gec438aea2017-10-26 16:44:00 +080013136 "%s: called with key index = %d & key length %d & seq length %d",
13137 __func__, key_index, params->key_len, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013138
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013139 peerMacAddr = (v_MACADDR_t *)mac_addr;
13140
Jeff Johnson295189b2012-06-20 16:38:30 -070013141 /*extract key idx, key len and key*/
13142 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13143 setKey.keyId = key_index;
13144 setKey.keyLength = params->key_len;
13145 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
Jingxiang Gec438aea2017-10-26 16:44:00 +080013146 vos_mem_copy(&setKey.keyRsc[0], params->seq, params->seq_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013147
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013148 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 {
13150 case WLAN_CIPHER_SUITE_WEP40:
13151 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13152 break;
13153
13154 case WLAN_CIPHER_SUITE_WEP104:
13155 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
13156 break;
13157
13158 case WLAN_CIPHER_SUITE_TKIP:
13159 {
13160 u8 *pKey = &setKey.Key[0];
13161 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
13162
13163 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
13164
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013165 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070013166
13167 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013168 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013169 |--------------|----------|----------|
13170 <---16bytes---><--8bytes--><--8bytes-->
13171
13172 */
13173 /*Sme expects the 32 bytes key to be in the below order
13174
13175 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013176 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070013177 |--------------|----------|----------|
13178 <---16bytes---><--8bytes--><--8bytes-->
13179 */
13180 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013181 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070013182
13183 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013184 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013185
13186 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013187 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070013188
13189
13190 break;
13191 }
13192
13193 case WLAN_CIPHER_SUITE_CCMP:
13194 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
13195 break;
13196
13197#ifdef FEATURE_WLAN_WAPI
13198 case WLAN_CIPHER_SUITE_SMS4:
13199 {
13200 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13201 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
13202 params->key, params->key_len);
13203 return 0;
13204 }
13205#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013206
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013207#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013208 case WLAN_CIPHER_SUITE_KRK:
13209 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
13210 break;
13211#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070013212
13213#ifdef WLAN_FEATURE_11W
13214 case WLAN_CIPHER_SUITE_AES_CMAC:
13215 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070013216 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070013217#endif
13218
Jeff Johnson295189b2012-06-20 16:38:30 -070013219 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070013220 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070013221 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013222 status = -EOPNOTSUPP;
13223 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 }
13225
13226 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
13227 __func__, setKey.encType);
13228
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013229 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070013230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13231 (!pairwise)
13232#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013233 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013234#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013235 )
13236 {
13237 /* set group key*/
13238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13239 "%s- %d: setting Broadcast key",
13240 __func__, __LINE__);
13241 setKey.keyDirection = eSIR_RX_ONLY;
13242 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13243 }
13244 else
13245 {
13246 /* set pairwise key*/
13247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13248 "%s- %d: setting pairwise key",
13249 __func__, __LINE__);
13250 setKey.keyDirection = eSIR_TX_RX;
13251 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013252 pairwise_set_key = true;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013253 }
13254 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
13255 {
13256 setKey.keyDirection = eSIR_TX_RX;
13257 /*Set the group key*/
13258 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13259 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070013260
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013261 if ( 0 != status )
13262 {
13263 hddLog(VOS_TRACE_LEVEL_ERROR,
13264 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013265 status = -EINVAL;
13266 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013267 }
13268 /*Save the keys here and call sme_RoamSetKey for setting
13269 the PTK after peer joins the IBSS network*/
13270 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
13271 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013272 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013273 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053013274 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
13275 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
13276 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013277 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013278 if( pHostapdState->bssState == BSS_START )
13279 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013280 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13281 vos_status = wlan_hdd_check_ula_done(pAdapter);
13282
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013283 if (peerMacAddr && (pairwise_set_key == true))
13284 staid = hdd_sta_id_find_from_mac_addr(pAdapter, peerMacAddr);
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013285
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013286 if ( vos_status != VOS_STATUS_SUCCESS )
13287 {
13288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13289 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13290 __LINE__, vos_status );
13291
13292 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13293
13294 status = -EINVAL;
13295 goto end;
13296 }
13297
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 status = WLANSAP_SetKeySta( pVosContext, &setKey);
13299
13300 if ( status != eHAL_STATUS_SUCCESS )
13301 {
13302 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13303 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13304 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013305 status = -EINVAL;
13306 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 }
13308 }
13309
13310 /* Saving WEP keys */
13311 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
13312 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
13313 {
13314 //Save the wep key in ap context. Issue setkey after the BSS is started.
13315 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13316 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
13317 }
13318 else
13319 {
13320 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013321 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013322 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
13323 }
13324 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013325 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
13326 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013327 {
13328 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13329 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13330
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013331#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13332 if (!pairwise)
13333#else
13334 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
13335#endif
13336 {
13337 /* set group key*/
13338 if (pHddStaCtx->roam_info.deferKeyComplete)
13339 {
13340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13341 "%s- %d: Perform Set key Complete",
13342 __func__, __LINE__);
13343 hdd_PerformRoamSetKeyComplete(pAdapter);
13344 }
13345 }
13346
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013347 if (pairwise_set_key == true)
13348 staid = pHddStaCtx->conn_info.staId[0];
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013349
Jeff Johnson295189b2012-06-20 16:38:30 -070013350 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
13351
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080013352 pWextState->roamProfile.Keys.defaultIndex = key_index;
13353
13354
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070013355 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013356 params->key, params->key_len);
13357
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013358
Jeff Johnson295189b2012-06-20 16:38:30 -070013359 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13360
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013361 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013362 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013363 __func__, setKey.peerMac[0], setKey.peerMac[1],
13364 setKey.peerMac[2], setKey.peerMac[3],
13365 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 setKey.keyDirection);
13367
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013368 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053013369
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013370 if ( vos_status != VOS_STATUS_SUCCESS )
13371 {
13372 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013373 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
13374 __LINE__, vos_status );
13375
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013376 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013377
Nirav Shah4b53d4b2015-05-08 05:35:00 -070013378 status = -EINVAL;
13379 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013380
13381 }
13382
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013383#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013384 /* The supplicant may attempt to set the PTK once pre-authentication
13385 is done. Save the key in the UMAC and include it in the ADD BSS
13386 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013387 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013388 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013389 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013390 hddLog(VOS_TRACE_LEVEL_INFO_MED,
13391 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013392 status = 0;
13393 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053013394 }
13395 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
13396 {
13397 hddLog(VOS_TRACE_LEVEL_ERROR,
13398 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013399 status = -EINVAL;
13400 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013401 }
13402#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070013403
13404 /* issue set key request to SME*/
13405 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
13406 pAdapter->sessionId, &setKey, &roamId );
13407
13408 if ( 0 != status )
13409 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013410 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
13412 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013413 status = -EINVAL;
13414 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 }
13416
13417
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013418 /* in case of IBSS as there was no information available about WEP keys during
13419 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070013420 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013421 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
13422 !( ( IW_AUTH_KEY_MGMT_802_1X
13423 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
13425 )
13426 &&
13427 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
13428 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
13429 )
13430 )
13431 {
13432 setKey.keyDirection = eSIR_RX_ONLY;
13433 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
13434
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013435 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013437 __func__, setKey.peerMac[0], setKey.peerMac[1],
13438 setKey.peerMac[2], setKey.peerMac[3],
13439 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070013440 setKey.keyDirection);
13441
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013442 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 pAdapter->sessionId, &setKey, &roamId );
13444
13445 if ( 0 != status )
13446 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013447 hddLog(VOS_TRACE_LEVEL_ERROR,
13448 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013449 __func__, status);
13450 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013451 status = -EINVAL;
13452 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 }
13454 }
13455 }
13456
Sravan Kumar Kairam9397a402017-11-10 16:23:10 +053013457 if (pairwise_set_key == true) {
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013458 for (i = 0; i < params->seq_len; i++) {
13459 rsc_counter |= (params->seq[i] << i*8);
13460 }
Sravan Kumar Kairam8bb90ca2017-11-01 19:00:23 +053013461 WLANTL_SetKeySeqCounter(pVosContext, rsc_counter, staid);
13462 }
13463
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013464end:
13465 /* Need to clear any trace of key value in the memory.
13466 * Thus zero out the memory even though it is local
13467 * variable.
13468 */
13469 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013470 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053013471 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013472}
13473
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13475static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13476 struct net_device *ndev,
13477 u8 key_index, bool pairwise,
13478 const u8 *mac_addr,
13479 struct key_params *params
13480 )
13481#else
13482static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
13483 struct net_device *ndev,
13484 u8 key_index, const u8 *mac_addr,
13485 struct key_params *params
13486 )
13487#endif
13488{
13489 int ret;
13490 vos_ssr_protect(__func__);
13491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13492 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
13493 mac_addr, params);
13494#else
13495 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
13496 params);
13497#endif
13498 vos_ssr_unprotect(__func__);
13499
13500 return ret;
13501}
13502
Jeff Johnson295189b2012-06-20 16:38:30 -070013503/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013504 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 * This function is used to get the key information
13506 */
13507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013508static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013509 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013510 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013511 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013512 const u8 *mac_addr, void *cookie,
13513 void (*callback)(void *cookie, struct key_params*)
13514 )
13515#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013516static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013517 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013518 struct net_device *ndev,
13519 u8 key_index, const u8 *mac_addr, void *cookie,
13520 void (*callback)(void *cookie, struct key_params*)
13521 )
13522#endif
13523{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013524 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013525 hdd_wext_state_t *pWextState = NULL;
13526 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013527 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013528 hdd_context_t *pHddCtx;
13529 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013530
13531 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013532
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013533 if (NULL == pAdapter)
13534 {
13535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13536 "%s: HDD adapter is Null", __func__);
13537 return -ENODEV;
13538 }
13539
13540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13541 ret = wlan_hdd_validate_context(pHddCtx);
13542 if (0 != ret)
13543 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053013544 return ret;
13545 }
13546
13547 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13548 pRoamProfile = &(pWextState->roamProfile);
13549
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013550 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
13551 __func__, hdd_device_modetoString(pAdapter->device_mode),
13552 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013553
Jeff Johnson295189b2012-06-20 16:38:30 -070013554 memset(&params, 0, sizeof(params));
13555
13556 if (CSR_MAX_NUM_KEY <= key_index)
13557 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013558 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013559 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013560 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013561
13562 switch(pRoamProfile->EncryptionType.encryptionType[0])
13563 {
13564 case eCSR_ENCRYPT_TYPE_NONE:
13565 params.cipher = IW_AUTH_CIPHER_NONE;
13566 break;
13567
13568 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
13569 case eCSR_ENCRYPT_TYPE_WEP40:
13570 params.cipher = WLAN_CIPHER_SUITE_WEP40;
13571 break;
13572
13573 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
13574 case eCSR_ENCRYPT_TYPE_WEP104:
13575 params.cipher = WLAN_CIPHER_SUITE_WEP104;
13576 break;
13577
13578 case eCSR_ENCRYPT_TYPE_TKIP:
13579 params.cipher = WLAN_CIPHER_SUITE_TKIP;
13580 break;
13581
13582 case eCSR_ENCRYPT_TYPE_AES:
13583 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
13584 break;
13585
13586 default:
13587 params.cipher = IW_AUTH_CIPHER_NONE;
13588 break;
13589 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013590
c_hpothuaaf19692014-05-17 17:01:48 +053013591 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13592 TRACE_CODE_HDD_CFG80211_GET_KEY,
13593 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013594
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
13596 params.seq_len = 0;
13597 params.seq = NULL;
13598 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
13599 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013600 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013601 return 0;
13602}
13603
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013604#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13605static int wlan_hdd_cfg80211_get_key(
13606 struct wiphy *wiphy,
13607 struct net_device *ndev,
13608 u8 key_index, bool pairwise,
13609 const u8 *mac_addr, void *cookie,
13610 void (*callback)(void *cookie, struct key_params*)
13611 )
13612#else
13613static int wlan_hdd_cfg80211_get_key(
13614 struct wiphy *wiphy,
13615 struct net_device *ndev,
13616 u8 key_index, const u8 *mac_addr, void *cookie,
13617 void (*callback)(void *cookie, struct key_params*)
13618 )
13619#endif
13620{
13621 int ret;
13622
13623 vos_ssr_protect(__func__);
13624#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13625 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
13626 mac_addr, cookie, callback);
13627#else
13628 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
13629 callback);
13630#endif
13631 vos_ssr_unprotect(__func__);
13632
13633 return ret;
13634}
13635
Jeff Johnson295189b2012-06-20 16:38:30 -070013636/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013637 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013638 * This function is used to delete the key information
13639 */
13640#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013641static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013642 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013643 u8 key_index,
13644 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070013645 const u8 *mac_addr
13646 )
13647#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013648static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 struct net_device *ndev,
13650 u8 key_index,
13651 const u8 *mac_addr
13652 )
13653#endif
13654{
13655 int status = 0;
13656
13657 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013658 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070013659 //it is observed that this is invalidating peer
13660 //key index whenever re-key is done. This is affecting data link.
13661 //It should be ok to ignore del_key.
13662#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013663 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
13664 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070013665 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13666 tCsrRoamSetKey setKey;
13667 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013668
Jeff Johnson295189b2012-06-20 16:38:30 -070013669 ENTER();
13670
13671 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
13672 __func__,pAdapter->device_mode);
13673
13674 if (CSR_MAX_NUM_KEY <= key_index)
13675 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013676 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 key_index);
13678
13679 return -EINVAL;
13680 }
13681
13682 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13683 setKey.keyId = key_index;
13684
13685 if (mac_addr)
13686 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
13687 else
13688 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
13689
13690 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
13691
13692 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070013693 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013694 )
13695 {
13696
13697 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
13699 if( pHostapdState->bssState == BSS_START)
13700 {
13701 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013702
Jeff Johnson295189b2012-06-20 16:38:30 -070013703 if ( status != eHAL_STATUS_SUCCESS )
13704 {
13705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13706 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
13707 __LINE__, status );
13708 }
13709 }
13710 }
13711 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013712 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070013713 )
13714 {
13715 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13716
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013717 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
13718
13719 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013721 __func__, setKey.peerMac[0], setKey.peerMac[1],
13722 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013724 if(pAdapter->sessionCtx.station.conn_info.connState ==
13725 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070013726 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013727 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013728 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013729
Jeff Johnson295189b2012-06-20 16:38:30 -070013730 if ( 0 != status )
13731 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013733 "%s: sme_RoamSetKey failure, returned %d",
13734 __func__, status);
13735 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
13736 return -EINVAL;
13737 }
13738 }
13739 }
13740#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070013741 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 return status;
13743}
13744
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13746static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13747 struct net_device *ndev,
13748 u8 key_index,
13749 bool pairwise,
13750 const u8 *mac_addr
13751 )
13752#else
13753static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
13754 struct net_device *ndev,
13755 u8 key_index,
13756 const u8 *mac_addr
13757 )
13758#endif
13759{
13760 int ret;
13761
13762 vos_ssr_protect(__func__);
13763#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13764 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
13765 mac_addr);
13766#else
13767 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
13768#endif
13769 vos_ssr_unprotect(__func__);
13770
13771 return ret;
13772}
13773
Jeff Johnson295189b2012-06-20 16:38:30 -070013774/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013775 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070013776 * This function is used to set the default tx key index
13777 */
13778#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013779static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 struct net_device *ndev,
13781 u8 key_index,
13782 bool unicast, bool multicast)
13783#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013784static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013785 struct net_device *ndev,
13786 u8 key_index)
13787#endif
13788{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013789 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013790 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053013791 hdd_wext_state_t *pWextState;
13792 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013793 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013794
13795 ENTER();
13796
Gopichand Nakkala29149562013-05-10 21:43:41 +053013797 if ((NULL == pAdapter))
13798 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013799 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053013800 "invalid adapter");
13801 return -EINVAL;
13802 }
13803
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013804 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13805 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
13806 pAdapter->sessionId, key_index));
13807
Gopichand Nakkala29149562013-05-10 21:43:41 +053013808 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13809 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13810
13811 if ((NULL == pWextState) || (NULL == pHddStaCtx))
13812 {
13813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
13814 "invalid Wext state or HDD context");
13815 return -EINVAL;
13816 }
13817
Arif Hussain6d2a3322013-11-17 19:50:10 -080013818 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013819 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013820
Jeff Johnson295189b2012-06-20 16:38:30 -070013821 if (CSR_MAX_NUM_KEY <= key_index)
13822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013823 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 key_index);
13825
13826 return -EINVAL;
13827 }
13828
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013829 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13830 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013831 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013832 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013833 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013834 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013835
Jeff Johnson295189b2012-06-20 16:38:30 -070013836 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070013837 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013838 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053013840 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080013841 pHddStaCtx->conn_info.ucEncryptionType) &&
Hu Wangb1f68cb2017-08-23 20:01:49 +080013842#ifdef FEATURE_WLAN_WAPI
13843 (eCSR_ENCRYPT_TYPE_WPI !=
13844 pHddStaCtx->conn_info.ucEncryptionType) &&
13845#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013846 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080013847 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070013848 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013849 {
13850 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070013851 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013852
Jeff Johnson295189b2012-06-20 16:38:30 -070013853 tCsrRoamSetKey setKey;
13854 v_U32_t roamId= 0xFF;
13855 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013856
13857 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013859
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 Keys->defaultIndex = (u8)key_index;
13861 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
13862 setKey.keyId = key_index;
13863 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013864
13865 vos_mem_copy(&setKey.Key[0],
13866 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013868
Gopichand Nakkala29149562013-05-10 21:43:41 +053013869 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013870
13871 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070013872 &pHddStaCtx->conn_info.bssId[0],
13873 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013874
Gopichand Nakkala29149562013-05-10 21:43:41 +053013875 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
13876 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
13877 eCSR_ENCRYPT_TYPE_WEP104)
13878 {
13879 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
13880 even though ap is configured for WEP-40 encryption. In this canse the key length
13881 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
13882 type(104) and switching encryption type to 40*/
13883 pWextState->roamProfile.EncryptionType.encryptionType[0] =
13884 eCSR_ENCRYPT_TYPE_WEP40;
13885 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
13886 eCSR_ENCRYPT_TYPE_WEP40;
13887 }
13888
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013889 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013891
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013893 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013894 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013895
Jeff Johnson295189b2012-06-20 16:38:30 -070013896 if ( 0 != status )
13897 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013898 hddLog(VOS_TRACE_LEVEL_ERROR,
13899 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013900 status);
13901 return -EINVAL;
13902 }
13903 }
13904 }
13905
13906 /* In SoftAp mode setting key direction for default mode */
13907 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
13908 {
13909 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
13910 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
13911 (eCSR_ENCRYPT_TYPE_AES !=
13912 pWextState->roamProfile.EncryptionType.encryptionType[0])
13913 )
13914 {
13915 /* Saving key direction for default key index to TX default */
13916 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
13917 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
13918 }
13919 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013920 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013921 return status;
13922}
13923
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053013924#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13925static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13926 struct net_device *ndev,
13927 u8 key_index,
13928 bool unicast, bool multicast)
13929#else
13930static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
13931 struct net_device *ndev,
13932 u8 key_index)
13933#endif
13934{
13935 int ret;
13936 vos_ssr_protect(__func__);
13937#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13938 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
13939 multicast);
13940#else
13941 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
13942#endif
13943 vos_ssr_unprotect(__func__);
13944
13945 return ret;
13946}
13947
Jeff Johnson295189b2012-06-20 16:38:30 -070013948/*
13949 * FUNCTION: wlan_hdd_cfg80211_inform_bss
13950 * This function is used to inform the BSS details to nl80211 interface.
13951 */
13952static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
13953 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
13954{
13955 struct net_device *dev = pAdapter->dev;
13956 struct wireless_dev *wdev = dev->ieee80211_ptr;
13957 struct wiphy *wiphy = wdev->wiphy;
13958 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
13959 int chan_no;
13960 int ie_length;
13961 const char *ie;
13962 unsigned int freq;
13963 struct ieee80211_channel *chan;
13964 int rssi = 0;
13965 struct cfg80211_bss *bss = NULL;
13966
Jeff Johnson295189b2012-06-20 16:38:30 -070013967 if( NULL == pBssDesc )
13968 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013969 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 return bss;
13971 }
13972
13973 chan_no = pBssDesc->channelId;
13974 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
13975 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
13976
13977 if( NULL == ie )
13978 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013979 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013980 return bss;
13981 }
13982
13983#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
13984 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
13985 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013986 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013987 }
13988 else
13989 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053013990 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070013991 }
13992#else
13993 freq = ieee80211_channel_to_frequency(chan_no);
13994#endif
13995
13996 chan = __ieee80211_get_channel(wiphy, freq);
13997
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053013998 if (!chan) {
13999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
14000 return NULL;
14001 }
14002
Abhishek Singhaee43942014-06-16 18:55:47 +053014003 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070014004
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014005 return cfg80211_inform_bss(wiphy, chan,
14006#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14007 CFG80211_BSS_FTYPE_UNKNOWN,
14008#endif
14009 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014010 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070014011 pBssDesc->capabilityInfo,
14012 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053014013 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070014014}
14015
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014016/*
14017 * wlan_hdd_cfg80211_update_bss_list :to inform nl80211
14018 * interface that BSS might have been lost.
14019 * @pAdapter: adaptor
14020 * @bssid: bssid which might have been lost
14021 *
14022 * Return: bss which is unlinked from kernel cache
14023 */
14024struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_list(
14025 hdd_adapter_t *pAdapter, tSirMacAddr bssid)
14026{
14027 struct net_device *dev = pAdapter->dev;
14028 struct wireless_dev *wdev = dev->ieee80211_ptr;
14029 struct wiphy *wiphy = wdev->wiphy;
14030 struct cfg80211_bss *bss = NULL;
14031
Abhishek Singh5a597e62016-12-05 15:16:30 +053014032 bss = hdd_get_bss_entry(wiphy,
14033 NULL, bssid,
14034 NULL, 0);
Abhishek Singh72c2f4e2016-07-22 11:25:43 +053014035 if (bss == NULL) {
14036 hddLog(LOGE, FL("BSS not present"));
14037 } else {
14038 hddLog(LOG1, FL("cfg80211_unlink_bss called for BSSID "
14039 MAC_ADDRESS_STR), MAC_ADDR_ARRAY(bssid));
14040 cfg80211_unlink_bss(wiphy, bss);
14041 }
14042 return bss;
14043}
Jeff Johnson295189b2012-06-20 16:38:30 -070014044
14045
14046/*
14047 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
14048 * This function is used to inform the BSS details to nl80211 interface.
14049 */
14050struct cfg80211_bss*
14051wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
14052 tSirBssDescription *bss_desc
14053 )
14054{
14055 /*
14056 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
14057 already exists in bss data base of cfg80211 for that particular BSS ID.
14058 Using cfg80211_inform_bss_frame to update the bss entry instead of
14059 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
14060 now there is no possibility to get the mgmt(probe response) frame from PE,
14061 converting bss_desc to ieee80211_mgmt(probe response) and passing to
14062 cfg80211_inform_bss_frame.
14063 */
14064 struct net_device *dev = pAdapter->dev;
14065 struct wireless_dev *wdev = dev->ieee80211_ptr;
14066 struct wiphy *wiphy = wdev->wiphy;
14067 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014068#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14069 qcom_ie_age *qie_age = NULL;
14070 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
14071#else
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014073#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014074 const char *ie =
14075 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
14076 unsigned int freq;
14077 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014078 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014079 struct cfg80211_bss *bss_status = NULL;
14080 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
14081 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070014082 hdd_context_t *pHddCtx;
14083 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070014084#ifdef WLAN_OPEN_SOURCE
14085 struct timespec ts;
14086#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014087
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014088
Wilson Yangf80a0542013-10-07 13:02:37 -070014089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14090 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070014091 if (0 != status)
14092 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014093 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014094 }
14095
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053014096 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070014097 if (!mgmt)
14098 {
14099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14100 "%s: memory allocation failed ", __func__);
14101 return NULL;
14102 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070014103
Jeff Johnson295189b2012-06-20 16:38:30 -070014104 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014105
14106#ifdef WLAN_OPEN_SOURCE
14107 /* Android does not want the timestamp from the frame.
14108 Instead it wants a monotonic increasing value */
14109 get_monotonic_boottime(&ts);
14110 mgmt->u.probe_resp.timestamp =
14111 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
14112#else
14113 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014114 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
14115 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070014116
14117#endif
14118
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
14120 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014121
14122#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
14123 /* GPS Requirement: need age ie per entry. Using vendor specific. */
14124 /* Assuming this is the last IE, copy at the end */
14125 ie_length -=sizeof(qcom_ie_age);
14126 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
14127 qie_age->element_id = QCOM_VENDOR_IE_ID;
14128 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
14129 qie_age->oui_1 = QCOM_OUI1;
14130 qie_age->oui_2 = QCOM_OUI2;
14131 qie_age->oui_3 = QCOM_OUI3;
14132 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
Selvaraj, Sridhar4b3a8362016-10-12 12:34:08 +053014133 /* Lowi expects the timestamp of bss in units of 1/10 ms. In driver all
14134 * bss related timestamp is in units of ms. Due to this when scan results
14135 * are sent to lowi the scan age is high.To address this, send age in units
14136 * of 1/10 ms.
14137 */
14138 qie_age->age = (vos_timer_get_system_time() -
14139 bss_desc->nReceivedTime)/10;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080014140#endif
14141
Jeff Johnson295189b2012-06-20 16:38:30 -070014142 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053014143 if (bss_desc->fProbeRsp)
14144 {
14145 mgmt->frame_control |=
14146 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
14147 }
14148 else
14149 {
14150 mgmt->frame_control |=
14151 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
14152 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014153
14154#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014155 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014156 (wiphy->bands[HDD_NL80211_BAND_2GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014157 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014158 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_2GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014160 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014161 (wiphy->bands[HDD_NL80211_BAND_5GHZ] != NULL))
Jeff Johnson295189b2012-06-20 16:38:30 -070014162
14163 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014164 freq = ieee80211_channel_to_frequency(chan_no, HDD_NL80211_BAND_5GHZ);
Jeff Johnson295189b2012-06-20 16:38:30 -070014165 }
14166 else
14167 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
14169 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070014170 kfree(mgmt);
14171 return NULL;
14172 }
14173#else
14174 freq = ieee80211_channel_to_frequency(chan_no);
14175#endif
14176 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014177 /*when the band is changed on the fly using the GUI, three things are done
14178 * 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)
14179 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
14180 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
14181 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
14182 * and discards the channels correponding to previous band and calls back with zero bss results.
14183 * 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
14184 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
14185 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
14186 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
14187 * So drop the bss and continue to next bss.
14188 */
14189 if(chan == NULL)
14190 {
Deepthi Gowri306657b2016-04-28 17:10:41 +053014191 hddLog(VOS_TRACE_LEVEL_ERROR,
14192 FL("chan pointer is NULL, chan_no: %d freq: %d"),
14193 chan_no, freq);
Chilam Ngc4244af2013-04-01 15:37:32 -070014194 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080014195 return NULL;
14196 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053014197 /*To keep the rssi icon of the connected AP in the scan window
14198 *and the rssi icon of the wireless networks in sync
14199 * */
14200 if (( eConnectionState_Associated ==
14201 pAdapter->sessionCtx.station.conn_info.connState ) &&
14202 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
14203 pAdapter->sessionCtx.station.conn_info.bssId,
14204 WNI_CFG_BSSID_LEN)) &&
14205 (pHddCtx->hdd_wlan_suspended == FALSE))
14206 {
14207 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
14208 rssi = (pAdapter->rssi * 100);
14209 }
14210 else
14211 {
14212 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
14213 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014214
Nirav Shah20ac06f2013-12-12 18:14:06 +053014215 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053014216 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
14217 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053014218
Jeff Johnson295189b2012-06-20 16:38:30 -070014219 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
14220 frame_len, rssi, GFP_KERNEL);
14221 kfree(mgmt);
14222 return bss_status;
14223}
14224
14225/*
14226 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
14227 * This function is used to update the BSS data base of CFG8011
14228 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014229struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014230 tCsrRoamInfo *pRoamInfo
14231 )
14232{
14233 tCsrRoamConnectedProfile roamProfile;
14234 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14235 struct cfg80211_bss *bss = NULL;
14236
14237 ENTER();
14238
14239 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
14240 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
14241
14242 if (NULL != roamProfile.pBssDesc)
14243 {
Girish Gowlif4b68022014-08-28 23:18:57 +053014244 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14245 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070014246
14247 if (NULL == bss)
14248 {
14249 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
14250 __func__);
14251 }
14252
14253 sme_RoamFreeConnectProfile(hHal, &roamProfile);
14254 }
14255 else
14256 {
14257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
14258 __func__);
14259 }
14260 return bss;
14261}
14262
14263/*
14264 * FUNCTION: wlan_hdd_cfg80211_update_bss
14265 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014266static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
14267 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070014268 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014269{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014270 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 tCsrScanResultInfo *pScanResult;
14272 eHalStatus status = 0;
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014273 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014274 tScanResultHandle pResult;
14275 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070014276 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014277 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014279
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014280 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14281 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
14282 NO_SESSION, pAdapter->sessionId));
14283
Wilson Yangf80a0542013-10-07 13:02:37 -070014284 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014285 ret = wlan_hdd_validate_context(pHddCtx);
14286 if (0 != ret)
Jeff Johnson295189b2012-06-20 16:38:30 -070014287 {
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014288 return ret;
Wilson Yangf80a0542013-10-07 13:02:37 -070014289 }
14290
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014291 if (pAdapter->request != NULL)
14292 {
14293 if ((pAdapter->request->n_ssids == 1)
14294 && (pAdapter->request->ssids != NULL)
14295 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
14296 is_p2p_scan = true;
14297 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014298 /*
14299 * start getting scan results and populate cgf80211 BSS database
14300 */
14301 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
14302
14303 /* no scan results */
14304 if (NULL == pResult)
14305 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053014306 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
14307 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053014308 wlan_hdd_get_frame_logs(pAdapter,
14309 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070014310 return status;
14311 }
14312
14313 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
14314
14315 while (pScanResult)
14316 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014317 /*
14318 * cfg80211_inform_bss() is not updating ie field of bss entry, if
14319 * entry already exists in bss data base of cfg80211 for that
14320 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
14321 * bss entry instead of cfg80211_inform_bss, But this call expects
14322 * mgmt packet as input. As of now there is no possibility to get
14323 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070014324 * ieee80211_mgmt(probe response) and passing to c
14325 * fg80211_inform_bss_frame.
14326 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014327 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
14328 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
14329 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014330 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14331 continue; //Skip the non p2p bss entries
14332 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014333 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
14334 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014335
Jeff Johnson295189b2012-06-20 16:38:30 -070014336
14337 if (NULL == bss_status)
14338 {
14339 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014340 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014341 }
14342 else
14343 {
Yue Maf49ba872013-08-19 12:04:25 -070014344 cfg80211_put_bss(
14345#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
14346 wiphy,
14347#endif
14348 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 }
14350
14351 pScanResult = sme_ScanResultGetNext(hHal, pResult);
14352 }
14353
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014354 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053014355 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014356 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014357}
14358
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014359void
14360hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
14361{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014362 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080014363 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014364} /****** end hddPrintMacAddr() ******/
14365
14366void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014367hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014368{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014369 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014370 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014371 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
14372 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
14373 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014374} /****** end hddPrintPmkId() ******/
14375
14376//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
14377//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
14378
14379//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
14380//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
14381
14382#define dump_bssid(bssid) \
14383 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014384 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
14385 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014386 }
14387
14388#define dump_pmkid(pMac, pmkid) \
14389 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070014390 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
14391 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014392 }
14393
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070014394#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014395/*
14396 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
14397 * This function is used to notify the supplicant of a new PMKSA candidate.
14398 */
14399int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014400 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014401 int index, bool preauth )
14402{
Jeff Johnsone7245742012-09-05 17:12:55 -070014403#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014404 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014405 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014406
14407 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070014408 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014409
14410 if( NULL == pRoamInfo )
14411 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014412 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014413 return -EINVAL;
14414 }
14415
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014416 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
14417 {
14418 dump_bssid(pRoamInfo->bssid);
14419 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014420 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070014421 }
Jeff Johnsone7245742012-09-05 17:12:55 -070014422#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014423 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014424}
14425#endif //FEATURE_WLAN_LFR
14426
Yue Maef608272013-04-08 23:09:17 -070014427#ifdef FEATURE_WLAN_LFR_METRICS
14428/*
14429 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
14430 * 802.11r/LFR metrics reporting function to report preauth initiation
14431 *
14432 */
14433#define MAX_LFR_METRICS_EVENT_LENGTH 100
14434VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
14435 tCsrRoamInfo *pRoamInfo)
14436{
14437 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14438 union iwreq_data wrqu;
14439
14440 ENTER();
14441
14442 if (NULL == pAdapter)
14443 {
14444 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14445 return VOS_STATUS_E_FAILURE;
14446 }
14447
14448 /* create the event */
14449 memset(&wrqu, 0, sizeof(wrqu));
14450 memset(metrics_notification, 0, sizeof(metrics_notification));
14451
14452 wrqu.data.pointer = metrics_notification;
14453 wrqu.data.length = scnprintf(metrics_notification,
14454 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
14455 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14456
14457 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14458
14459 EXIT();
14460
14461 return VOS_STATUS_SUCCESS;
14462}
14463
14464/*
14465 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
14466 * 802.11r/LFR metrics reporting function to report preauth completion
14467 * or failure
14468 */
14469VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
14470 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
14471{
14472 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14473 union iwreq_data wrqu;
14474
14475 ENTER();
14476
14477 if (NULL == pAdapter)
14478 {
14479 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14480 return VOS_STATUS_E_FAILURE;
14481 }
14482
14483 /* create the event */
14484 memset(&wrqu, 0, sizeof(wrqu));
14485 memset(metrics_notification, 0, sizeof(metrics_notification));
14486
14487 scnprintf(metrics_notification, sizeof(metrics_notification),
14488 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
14489 MAC_ADDR_ARRAY(pRoamInfo->bssid));
14490
14491 if (1 == preauth_status)
14492 strncat(metrics_notification, " TRUE", 5);
14493 else
14494 strncat(metrics_notification, " FALSE", 6);
14495
14496 wrqu.data.pointer = metrics_notification;
14497 wrqu.data.length = strlen(metrics_notification);
14498
14499 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14500
14501 EXIT();
14502
14503 return VOS_STATUS_SUCCESS;
14504}
14505
14506/*
14507 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
14508 * 802.11r/LFR metrics reporting function to report handover initiation
14509 *
14510 */
14511VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
14512 tCsrRoamInfo *pRoamInfo)
14513{
14514 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
14515 union iwreq_data wrqu;
14516
14517 ENTER();
14518
14519 if (NULL == pAdapter)
14520 {
14521 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
14522 return VOS_STATUS_E_FAILURE;
14523 }
14524
14525 /* create the event */
14526 memset(&wrqu, 0, sizeof(wrqu));
14527 memset(metrics_notification, 0, sizeof(metrics_notification));
14528
14529 wrqu.data.pointer = metrics_notification;
14530 wrqu.data.length = scnprintf(metrics_notification,
14531 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
14532 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
14533
14534 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
14535
14536 EXIT();
14537
14538 return VOS_STATUS_SUCCESS;
14539}
14540#endif
14541
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014542
14543/**
14544 * wlan_hdd_cfg80211_validate_scan_req - validate scan request
14545 * @scan_req: scan request to be checked
14546 *
14547 * Return: true or false
14548 */
14549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14550static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14551 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014552 *scan_req, hdd_context_t
14553 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014554{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014555 if (!scan_req || !scan_req->wiphy ||
14556 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014557 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14558 return false;
14559 }
14560 if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HDD, NULL)) {
14561 hddLog(VOS_TRACE_LEVEL_ERROR, "Load/Unload in progress");
14562 return false;
14563 }
14564 return true;
14565}
14566#else
14567static inline bool wlan_hdd_cfg80211_validate_scan_req(struct
14568 cfg80211_scan_request
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014569 *scan_req, hdd_context_t
14570 *hdd_ctx)
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014571{
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014572 if (!scan_req || !scan_req->wiphy ||
14573 scan_req->wiphy != hdd_ctx->wiphy) {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014574 hddLog(VOS_TRACE_LEVEL_ERROR, "Invalid scan request");
14575 return false;
14576 }
14577 return true;
14578}
14579#endif
14580
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014581#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
14582/**
14583 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14584 * @adapter: Pointer to the adapter
14585 * @req : Scan request
14586 * @aborted : true scan aborted false scan success
14587 *
14588 * This function notifies scan done to cfg80211
14589 *
14590 * Return: none
14591 */
14592static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14593 struct cfg80211_scan_request *req,
14594 bool aborted)
14595{
14596 struct cfg80211_scan_info info = {
14597 .aborted = aborted
14598 };
14599
14600 if (adapter->dev->flags & IFF_UP)
14601 cfg80211_scan_done(req, &info);
14602 else
14603 hddLog(LOGW,
14604 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14605}
14606#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
14607/**
14608 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14609 * @adapter: Pointer to the adapter
14610 * @req : Scan request
14611 * @aborted : true scan aborted false scan success
14612 *
14613 * This function notifies scan done to cfg80211
14614 *
14615 * Return: none
14616 */
14617static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14618 struct cfg80211_scan_request *req,
14619 bool aborted)
14620{
14621 if (adapter->dev->flags & IFF_UP)
14622 cfg80211_scan_done(req, aborted);
14623 else
14624 hddLog(LOGW,
14625 FL("IFF_UP flag reset for %s"), adapter->dev->name);
14626}
14627#else
14628/**
14629 * hdd_cfg80211_scan_done() - Scan completed callback to cfg80211
14630 * @adapter: Pointer to the adapter
14631 * @req : Scan request
14632 * @aborted : true scan aborted false scan success
14633 *
14634 * This function notifies scan done to cfg80211
14635 *
14636 * Return: none
14637 */
14638static void hdd_cfg80211_scan_done(hdd_adapter_t *adapter,
14639 struct cfg80211_scan_request *req,
14640 bool aborted)
14641{
14642 cfg80211_scan_done(req, aborted);
14643}
14644#endif
14645
Mukul Sharmab392b642017-08-17 17:45:29 +053014646#define NET_DEV_IS_IFF_UP(pAdapter) (pAdapter->dev->flags & IFF_UP)
Jeff Johnson295189b2012-06-20 16:38:30 -070014647/*
14648 * FUNCTION: hdd_cfg80211_scan_done_callback
14649 * scanning callback function, called after finishing scan
14650 *
14651 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014652static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070014653 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
14654{
14655 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014656 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070014657 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014658 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 struct cfg80211_scan_request *req = NULL;
14660 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014661 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014662 long waitRet = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014663 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014664
14665 ENTER();
14666
c_manjee1b4ab9a2016-10-26 11:36:55 +053014667 if (!pAdapter || pAdapter->magic != WLAN_HDD_ADAPTER_MAGIC ||
14668 !pAdapter->dev) {
14669 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Adapter is not valid"));
14670 return 0;
14671 }
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014672 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053014673 if (NULL == pHddCtx) {
14674 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014675 return 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014676 }
14677
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014678#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014679 if (!NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014680 {
14681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Interface is down"));
Mahesh A Saptasagar11296752016-01-07 17:53:02 +053014682 }
14683#endif
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014684 pScanInfo = &pHddCtx->scan_info;
14685
Jeff Johnson295189b2012-06-20 16:38:30 -070014686 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014687 "%s called with halHandle = %pK, pContext = %pK,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080014688 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014689 __func__, halHandle, pContext, (int) scanId, (int) status);
14690
Kiet Lamac06e2c2013-10-23 16:25:07 +053014691 pScanInfo->mScanPendingCounter = 0;
14692
Jeff Johnson295189b2012-06-20 16:38:30 -070014693 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014694 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070014695 &pScanInfo->scan_req_completion_event,
14696 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014697 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070014698 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014699 hddLog(VOS_TRACE_LEVEL_ERROR,
14700 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070014701 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014702 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014703 }
14704
Yue Maef608272013-04-08 23:09:17 -070014705 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070014706 {
14707 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070014708 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014709 }
14710
14711 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014712 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 {
14714 hddLog(VOS_TRACE_LEVEL_INFO,
14715 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080014716 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070014717 (int) scanId);
14718 }
14719
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014720#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014721 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014722#endif
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014723 {
14724 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
14725 pAdapter);
14726 if (0 > ret)
14727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagar9dd72842016-04-15 19:45:14 +053014728 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014729
Jeff Johnson295189b2012-06-20 16:38:30 -070014730 /* If any client wait scan result through WEXT
14731 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014732 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 {
14734 /* The other scan request waiting for current scan finish
14735 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014736 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014737 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014738 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070014739 }
14740 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014741 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070014742 {
14743 struct net_device *dev = pAdapter->dev;
14744 union iwreq_data wrqu;
14745 int we_event;
14746 char *msg;
14747
14748 memset(&wrqu, '\0', sizeof(wrqu));
14749 we_event = SIOCGIWSCAN;
14750 msg = NULL;
14751 wireless_send_event(dev, we_event, &wrqu, msg);
14752 }
14753 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070014754 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014755
14756 /* Get the Scan Req */
14757 req = pAdapter->request;
mukul sharmae7041822015-12-03 15:09:21 +053014758 pAdapter->request = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014759
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014760 /* Scan is no longer pending */
14761 pScanInfo->mScanPending = VOS_FALSE;
14762
Hanumanth Reddy Pothulad4c817e2017-07-14 20:30:59 +053014763 if (!wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Jeff Johnson295189b2012-06-20 16:38:30 -070014764 {
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014765#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
14766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("interface state %s"),
Mukul Sharmab392b642017-08-17 17:45:29 +053014767 NET_DEV_IS_IFF_UP(pAdapter) ? "up" : "down");
Manjeet Singhaaee9cd2016-09-13 19:23:30 +053014768#endif
14769
14770 if (pAdapter->dev) {
14771 hddLog(VOS_TRACE_LEVEL_ERROR, FL("device name %s"),
14772 pAdapter->dev->name);
14773 }
mukul sharmae7041822015-12-03 15:09:21 +053014774 complete(&pScanInfo->abortscan_event_var);
Jeff Johnsone7245742012-09-05 17:12:55 -070014775 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070014776 }
14777
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014778 /* last_scan_timestamp is used to decide if new scan
14779 * is needed or not on station interface. If last station
14780 * scan time and new station scan time is less then
14781 * last_scan_timestamp ; driver will return cached scan.
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014782 * Also only last_scan_timestamp is updated here last_scan_channellist
14783 * is updated on receiving scan request itself to make sure kernel
14784 * allocated scan request(scan_req) object is not dereferenced here,
14785 * because interface down, where kernel frees scan_req, may happen any
14786 * time while driver is processing scan_done_callback. So it's better
14787 * not to access scan_req in this routine.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014788 */
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053014789 if (pScanInfo->no_cck == FALSE) { // no_cck will be set during p2p find
14790 if (status == eCSR_SCAN_SUCCESS)
14791 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
14792 else {
14793 vos_mem_zero(pHddCtx->scan_info.last_scan_channelList,
14794 sizeof(pHddCtx->scan_info.last_scan_channelList));
14795 pHddCtx->scan_info.last_scan_numChannels = 0;
14796 pScanInfo->last_scan_timestamp = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014797 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053014798 }
14799
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070014800 /*
14801 * cfg80211_scan_done informing NL80211 about completion
14802 * of scanning
14803 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014804 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
14805 {
14806 aborted = true;
14807 }
mukul sharmae7041822015-12-03 15:09:21 +053014808
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014809#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014810 if (NET_DEV_IS_IFF_UP(pAdapter) &&
14811 wlan_hdd_cfg80211_validate_scan_req(req, pHddCtx))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014812#endif
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053014813 hdd_cfg80211_scan_done(pAdapter, req, aborted);
mukul sharmae7041822015-12-03 15:09:21 +053014814
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080014815 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070014816
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014817allow_suspend:
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053014818 if ((pHddCtx->cfg_ini->enableMacSpoofing == MAC_ADDR_SPOOFING_FW_HOST_ENABLE
14819 ) && (pHddCtx->spoofMacAddr.isEnabled
14820 || pHddCtx->spoofMacAddr.isReqDeferred)) {
Siddharth Bhal76972212014-10-15 16:22:51 +053014821 /* Generate new random mac addr for next scan */
14822 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
Padma, Santhosh Kumardb2d75b2015-11-17 12:18:10 +053014823
14824 schedule_delayed_work(&pHddCtx->spoof_mac_addr_work,
14825 msecs_to_jiffies(MAC_ADDR_SPOOFING_DEFER_INTERVAL));
Siddharth Bhal76972212014-10-15 16:22:51 +053014826 }
14827
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070014828 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014829 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070014830
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014831 /* Acquire wakelock to handle the case where APP's tries to suspend
14832 * immediatly after the driver gets connect request(i.e after scan)
14833 * from supplicant, this result in app's is suspending and not able
14834 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053014835 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070014836
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
Mukul Sharmab392b642017-08-17 17:45:29 +053014838 if (NET_DEV_IS_IFF_UP(pAdapter))
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014839#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014840#ifdef FEATURE_WLAN_TDLS
Mahesh A Saptasagar08af5a32016-06-30 12:29:49 +053014841 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070014842#endif
14843
Jeff Johnson295189b2012-06-20 16:38:30 -070014844 EXIT();
14845 return 0;
14846}
14847
14848/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053014849 * FUNCTION: hdd_isConnectionInProgress
14850 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014851 *
14852 */
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014853v_BOOL_t hdd_isConnectionInProgress(hdd_context_t *pHddCtx, v_U8_t *session_id,
14854 scan_reject_states *reason)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014855{
14856 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14857 hdd_station_ctx_t *pHddStaCtx = NULL;
14858 hdd_adapter_t *pAdapter = NULL;
14859 VOS_STATUS status = 0;
14860 v_U8_t staId = 0;
14861 v_U8_t *staMac = NULL;
14862
14863 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
14864
14865 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
14866 {
14867 pAdapter = pAdapterNode->pAdapter;
14868
14869 if( pAdapter )
14870 {
14871 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014872 "%s: Adapter with device mode %s (%d) exists",
14873 __func__, hdd_device_modetoString(pAdapter->device_mode),
14874 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014875 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053014876 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14877 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
14878 (eConnectionState_Connecting ==
14879 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14880 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014881 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014882 "%s: %pK(%d) Connection is in progress", __func__,
Rashmi Ramannab1429032014-04-26 14:59:09 +053014883 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014884 if (session_id && reason)
14885 {
14886 *session_id = pAdapter->sessionId;
14887 *reason = eHDD_CONNECTION_IN_PROGRESS;
14888 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014889 return VOS_TRUE;
14890 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014891 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053014892 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014893 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014894 hddLog(LOG1,
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070014895 "%s: %pK(%d) Reassociation is in progress", __func__,
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014896 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014897 if (session_id && reason)
14898 {
14899 *session_id = pAdapter->sessionId;
14900 *reason = eHDD_REASSOC_IN_PROGRESS;
14901 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053014902 return VOS_TRUE;
14903 }
14904 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014905 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
14906 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014907 {
14908 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14909 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014910 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014911 {
14912 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014913 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014914 "%s: client " MAC_ADDRESS_STR
14915 " is in the middle of WPS/EAPOL exchange.", __func__,
14916 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014917 if (session_id && reason)
14918 {
14919 *session_id = pAdapter->sessionId;
14920 *reason = eHDD_EAPOL_IN_PROGRESS;
14921 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014922 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014923 }
14924 }
14925 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
14926 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
14927 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014928 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14929 ptSapContext pSapCtx = NULL;
14930 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14931 if(pSapCtx == NULL){
14932 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14933 FL("psapCtx is NULL"));
14934 return VOS_FALSE;
14935 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014936 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
14937 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014938 if ((pSapCtx->aStaInfo[staId].isUsed) &&
14939 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014940 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014941 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014942
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053014943 hddLog(LOG1,
Arif Hussain24bafea2013-11-15 15:10:03 -080014944 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
14945 "middle of WPS/EAPOL exchange.", __func__,
14946 MAC_ADDR_ARRAY(staMac));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053014947 if (session_id && reason)
14948 {
14949 *session_id = pAdapter->sessionId;
14950 *reason = eHDD_SAP_EAPOL_IN_PROGRESS;
14951 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014952 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014953 }
14954 }
14955 }
14956 }
14957 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14958 pAdapterNode = pNext;
14959 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053014960 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014961}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014962
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053014963/**
14964 * csr_scan_request_assign_bssid() - Set the BSSID received from Supplicant
14965 * to the Scan request
14966 * @scanRequest: Pointer to the csr scan request
14967 * @request: Pointer to the scan request from supplicant
14968 *
14969 * Return: None
14970 */
14971#ifdef CFG80211_SCAN_BSSID
14972static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14973 struct cfg80211_scan_request *request)
14974{
14975 vos_mem_copy(scanRequest->bssid, request->bssid, VOS_MAC_ADDR_SIZE);
14976}
14977#else
14978static inline void csr_scan_request_assign_bssid(tCsrScanRequest *scanRequest,
14979 struct cfg80211_scan_request *request)
14980{
14981}
14982#endif
14983
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080014984/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014985 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070014986 * this scan respond to scan trigger and update cfg80211 scan database
14987 * later, scan dump command can be used to recieve scan results
14988 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014989int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080014990#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
14991 struct net_device *dev,
14992#endif
14993 struct cfg80211_scan_request *request)
14994{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053014995 hdd_adapter_t *pAdapter = NULL;
14996 hdd_context_t *pHddCtx = NULL;
14997 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014998 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014999 tCsrScanRequest scanRequest;
15000 tANI_U8 *channelList = NULL, i;
15001 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015002 int status;
15003 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015004 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015005 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053015006 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015007 bool is_p2p_scan = false;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015008 v_U8_t curr_session_id;
15009 scan_reject_states curr_reason;
Jeff Johnson295189b2012-06-20 16:38:30 -070015010
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015011#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
15012 struct net_device *dev = NULL;
15013 if (NULL == request)
15014 {
15015 hddLog(VOS_TRACE_LEVEL_ERROR,
15016 "%s: scan req param null", __func__);
15017 return -EINVAL;
15018 }
15019 dev = request->wdev->netdev;
15020#endif
15021
15022 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15023 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
15024 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15025
Jeff Johnson295189b2012-06-20 16:38:30 -070015026 ENTER();
15027
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015028 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
15029 __func__, hdd_device_modetoString(pAdapter->device_mode),
15030 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015031
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015032 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015033 if (0 != status)
15034 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015035 return status;
15036 }
15037
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015038 if (NULL == pwextBuf)
15039 {
15040 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
15041 __func__);
15042 return -EIO;
15043 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015044 cfg_param = pHddCtx->cfg_ini;
15045 pScanInfo = &pHddCtx->scan_info;
15046
Jeff Johnson295189b2012-06-20 16:38:30 -070015047#ifdef WLAN_BTAMP_FEATURE
15048 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015049 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070015050 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015051 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015052 "%s: No scanning when AMP is on", __func__);
15053 return -EOPNOTSUPP;
15054 }
15055#endif
15056 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015057 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070015058 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015059 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015060 "%s: Not scanning on device_mode = %s (%d)",
15061 __func__, hdd_device_modetoString(pAdapter->device_mode),
15062 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015063 return -EOPNOTSUPP;
15064 }
15065
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053015066 if (pAdapter->device_mode == WLAN_HDD_MONITOR) {
15067 hddLog(LOGE, FL("Scan is not supported for monitor adapter"));
15068 return -EOPNOTSUPP;
15069 }
15070
Jeff Johnson295189b2012-06-20 16:38:30 -070015071 if (TRUE == pScanInfo->mScanPending)
15072 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015073 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
15074 {
15075 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
15076 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015077 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015078 }
15079
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053015080 // Don't allow scan if PNO scan is going on.
15081 if (pHddCtx->isPnoEnable)
15082 {
15083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15084 FL("pno scan in progress"));
15085 return -EBUSY;
15086 }
15087
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015088 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070015089 //Channel and action frame is pending
15090 //Otherwise Cancel Remain On Channel and allow Scan
15091 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015092 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070015093 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053015094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070015095 return -EBUSY;
15096 }
15097
Jeff Johnson295189b2012-06-20 16:38:30 -070015098 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
15099 {
15100 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080015101 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015102 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015104 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
15105 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015106 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015107 "%s: MAX TM Level Scan not allowed", __func__);
15108 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015109 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070015110 }
15111 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
15112
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015113 /* Check if scan is allowed at this point of time.
15114 */
Hanumanth Reddy Pothulaec960842016-09-14 19:04:26 +053015115 if (TRUE == pHddCtx->btCoexModeSet)
15116 {
15117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15118 FL("BTCoex Mode operation in progress"));
15119 return -EBUSY;
15120 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015121 if (hdd_isConnectionInProgress(pHddCtx, &curr_session_id, &curr_reason))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015122 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015123
15124 if (!(pHddCtx->scan_reject_cnt % HDD_SCAN_REJECT_RATE_LIMIT))
15125 hddLog(LOGE, FL("Scan not allowed Session %d reason %d"),
15126 curr_session_id, curr_reason);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015127 if (pHddCtx->last_scan_reject_session_id != curr_session_id ||
15128 pHddCtx->last_scan_reject_reason != curr_reason ||
15129 !pHddCtx->last_scan_reject_timestamp)
15130 {
15131 pHddCtx->last_scan_reject_session_id = curr_session_id;
15132 pHddCtx->last_scan_reject_reason = curr_reason;
Abhishek Singh3e500772017-07-17 10:13:43 +053015133 pHddCtx->last_scan_reject_timestamp =
15134 jiffies_to_msecs(jiffies) + SCAN_REJECT_THRESHOLD_TIME;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015135 pHddCtx->scan_reject_cnt = 0;
Agrawal Ashishc932a8d2016-08-17 19:21:02 +053015136 }
Abhishek Singhe4b12562017-06-20 16:53:39 +053015137 else
15138 {
15139 pHddCtx->scan_reject_cnt++;
15140
Abhishek Singhe4b12562017-06-20 16:53:39 +053015141 if ((pHddCtx->scan_reject_cnt >=
15142 SCAN_REJECT_THRESHOLD) &&
Abhishek Singh3e500772017-07-17 10:13:43 +053015143 vos_system_time_after(jiffies_to_msecs(jiffies),
15144 pHddCtx->last_scan_reject_timestamp))
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015145 {
Vignesh Viswanathane0a3f922017-08-10 19:15:44 +053015146 hddLog(LOGE, FL("Session %d reason %d reject cnt %d threshold time has elapsed? %d"),
15147 curr_session_id, curr_reason, pHddCtx->scan_reject_cnt,
15148 vos_system_time_after(jiffies_to_msecs(jiffies),
15149 pHddCtx->last_scan_reject_timestamp));
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015150 pHddCtx->last_scan_reject_timestamp = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015151 pHddCtx->scan_reject_cnt = 0;
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015152 if (pHddCtx->cfg_ini->enableFatalEvent)
15153 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
15154 WLAN_LOG_INDICATOR_HOST_DRIVER,
15155 WLAN_LOG_REASON_SCAN_NOT_ALLOWED,
15156 FALSE, FALSE);
15157 else
15158 {
15159 hddLog(LOGE, FL("Triggering SSR"));
Anurag Chouhanf0d0ba12018-02-09 15:13:43 +053015160 vos_wlanRestart(VOS_SCAN_REQ_EXPIRED);
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015161 }
15162 }
15163 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080015164 return -EBUSY;
15165 }
Sreelakshmi Konamki20ebed92016-10-27 12:13:30 +053015166 pHddCtx->last_scan_reject_timestamp = 0;
15167 pHddCtx->last_scan_reject_session_id = 0xFF;
15168 pHddCtx->last_scan_reject_reason = 0;
Abhishek Singhe4b12562017-06-20 16:53:39 +053015169 pHddCtx->scan_reject_cnt = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015170
Jeff Johnson295189b2012-06-20 16:38:30 -070015171 vos_mem_zero( &scanRequest, sizeof(scanRequest));
15172
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015173 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
15174 * Becasue of this, driver is assuming that this is not wildcard scan and so
15175 * is not aging out the scan results.
15176 */
Hanumanth Reddy Pothula998efeb2017-10-31 15:43:19 +053015177 if ((request->ssids) && (request->n_ssids == 1) &&
15178 ('\0' == request->ssids->ssid[0])) {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015179 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015180 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015181
15182 if ((request->ssids) && (0 < request->n_ssids))
15183 {
15184 tCsrSSIDInfo *SsidInfo;
15185 int j;
15186 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
15187 /* Allocate num_ssid tCsrSSIDInfo structure */
15188 SsidInfo = scanRequest.SSIDs.SSIDList =
15189 ( tCsrSSIDInfo *)vos_mem_malloc(
15190 request->n_ssids*sizeof(tCsrSSIDInfo));
15191
15192 if(NULL == scanRequest.SSIDs.SSIDList)
15193 {
15194 hddLog(VOS_TRACE_LEVEL_ERROR,
15195 "%s: memory alloc failed SSIDInfo buffer", __func__);
15196 return -ENOMEM;
15197 }
15198
15199 /* copy all the ssid's and their length */
15200 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
15201 {
15202 /* get the ssid length */
15203 SsidInfo->SSID.length = request->ssids[j].ssid_len;
15204 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
15205 SsidInfo->SSID.length);
15206 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
15207 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
15208 j, SsidInfo->SSID.ssId);
15209 }
15210 /* set the scan type to active */
15211 scanRequest.scanType = eSIR_ACTIVE_SCAN;
15212 }
15213 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015214 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053015215 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15216 TRACE_CODE_HDD_CFG80211_SCAN,
15217 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070015218 /* set the scan type to active */
15219 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070015220 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015221 else
15222 {
15223 /*Set the scan type to default type, in this case it is ACTIVE*/
15224 scanRequest.scanType = pScanInfo->scan_mode;
15225 }
15226 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
15227 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070015228
Selvaraj, Sridhard2b078a2016-06-18 10:44:37 +053015229 csr_scan_request_assign_bssid(&scanRequest, request);
15230
Jeff Johnson295189b2012-06-20 16:38:30 -070015231 /* set BSSType to default type */
15232 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
15233
15234 /*TODO: scan the requested channels only*/
15235
15236 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015237 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070015238 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015239 hddLog(VOS_TRACE_LEVEL_WARN,
15240 "No of Scan Channels exceeded limit: %d", request->n_channels);
15241 request->n_channels = MAX_CHANNEL;
15242 }
15243
15244 hddLog(VOS_TRACE_LEVEL_INFO,
15245 "No of Scan Channels: %d", request->n_channels);
15246
15247
15248 if( request->n_channels )
15249 {
15250 char chList [(request->n_channels*5)+1];
15251 int len;
15252 channelList = vos_mem_malloc( request->n_channels );
15253 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053015254 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015255 hddLog(VOS_TRACE_LEVEL_ERROR,
15256 "%s: memory alloc failed channelList", __func__);
15257 status = -ENOMEM;
15258 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053015259 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015260
15261 for( i = 0, len = 0; i < request->n_channels ; i++ )
15262 {
15263 channelList[i] = request->channels[i]->hw_value;
15264 len += snprintf(chList+len, 5, "%d ", channelList[i]);
15265 }
15266
Nirav Shah20ac06f2013-12-12 18:14:06 +053015267 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015268 "Channel-List: %s ", chList);
15269 }
c_hpothu53512302014-04-15 18:49:53 +053015270
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015271 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
15272 scanRequest.ChannelInfo.ChannelList = channelList;
15273
15274 /* set requestType to full scan */
15275 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
15276
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015277 /* if there is back to back scan happening in driver with in
15278 * nDeferScanTimeInterval interval driver should defer new scan request
15279 * and should provide last cached scan results instead of new channel list.
15280 * This rule is not applicable if scan is p2p scan.
15281 * This condition will work only in case when last request no of channels
15282 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053015283 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053015284 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015285 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015286
Sushant Kaushik86592172015-04-27 16:35:03 +053015287 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
15288 /* if wps ie is NULL , then only defer scan */
15289 if ( pWpsIe == NULL &&
15290 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053015291 {
15292 if ( pScanInfo->last_scan_timestamp !=0 &&
15293 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
15294 {
15295 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
15296 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
15297 vos_mem_compare(pScanInfo->last_scan_channelList,
15298 channelList, pScanInfo->last_scan_numChannels))
15299 {
15300 hddLog(VOS_TRACE_LEVEL_WARN,
15301 " New and old station scan time differ is less then %u",
15302 pHddCtx->cfg_ini->nDeferScanTimeInterval);
15303
15304 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015305 pAdapter);
15306
Agarwal Ashish57e84372014-12-05 18:26:53 +053015307 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015308 "Return old cached scan as all channels and no of channels are same");
15309
Agarwal Ashish57e84372014-12-05 18:26:53 +053015310 if (0 > ret)
15311 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015312
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053015313 hdd_cfg80211_scan_done(pAdapter, request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053015314
15315 status = eHAL_STATUS_SUCCESS;
15316 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053015317 }
15318 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053015319 }
15320
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015321 /* Flush the scan results(only p2p beacons) for STA scan and P2P
15322 * search (Flush on both full scan and social scan but not on single
15323 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
15324 */
15325
15326 /* Supplicant does single channel scan after 8-way handshake
15327 * and in that case driver shoudnt flush scan results. If
15328 * driver flushes the scan results here and unfortunately if
15329 * the AP doesnt respond to our probe req then association
15330 * fails which is not desired
15331 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015332 if ((request->n_ssids == 1)
15333 && (request->ssids != NULL)
15334 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
15335 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015336
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053015337 if( is_p2p_scan ||
15338 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015339 {
15340 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
15341 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
15342 pAdapter->sessionId );
15343 }
15344
15345 if( request->ie_len )
15346 {
15347 /* save this for future association (join requires this) */
15348 /*TODO: Array needs to be converted to dynamic allocation,
15349 * as multiple ie.s can be sent in cfg80211_scan_request structure
15350 * CR 597966
15351 */
15352 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
15353 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
15354 pScanInfo->scanAddIE.length = request->ie_len;
15355
15356 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15357 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
15358 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015359 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053015360 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070015361 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015362 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
15363 memcpy( pwextBuf->roamProfile.addIEScan,
15364 request->ie, request->ie_len);
15365 }
15366 else
15367 {
15368 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
15369 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070015370 }
15371
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015372 }
15373 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
15374 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
15375
15376 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
15377 request->ie_len);
15378 if (pP2pIe != NULL)
15379 {
15380#ifdef WLAN_FEATURE_P2P_DEBUG
15381 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
15382 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
15383 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053015384 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015385 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
15386 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15387 "Go nego completed to Connection is started");
15388 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15389 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053015390 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015391 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
15392 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070015393 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015394 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
15395 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
15396 "Disconnected state to Connection is started");
15397 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
15398 "for 4way Handshake");
15399 }
15400#endif
15401
15402 /* no_cck will be set during p2p find to disable 11b rates */
15403 if(TRUE == request->no_cck)
15404 {
15405 hddLog(VOS_TRACE_LEVEL_INFO,
15406 "%s: This is a P2P Search", __func__);
15407 scanRequest.p2pSearch = 1;
15408
15409 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053015410 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015411 /* set requestType to P2P Discovery */
15412 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
15413 }
15414
15415 /*
15416 Skip Dfs Channel in case of P2P Search
15417 if it is set in ini file
15418 */
15419 if(cfg_param->skipDfsChnlInP2pSearch)
15420 {
15421 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015422 }
15423 else
15424 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053015425 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053015426 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015427
Agarwal Ashish4f616132013-12-30 23:32:50 +053015428 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015429 }
15430 }
15431
15432 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
15433
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015434#ifdef FEATURE_WLAN_TDLS
15435 /* if tdls disagree scan right now, return immediately.
15436 tdls will schedule the scan when scan is allowed. (return SUCCESS)
15437 or will reject the scan if any TDLS is in progress. (return -EBUSY)
15438 */
15439 status = wlan_hdd_tdls_scan_callback (pAdapter,
15440 wiphy,
15441#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15442 dev,
15443#endif
15444 request);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015445 if (status <= 0)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015446 {
Abhishek Singhe2b63952016-01-05 18:27:29 +053015447 if (!status)
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015448 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
15449 "scan rejected %d", __func__, status);
15450 else
15451 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
15452 __func__, status);
Abhishek Singhe2b63952016-01-05 18:27:29 +053015453 hdd_wlan_block_scan_by_tdls();
Gupta, Kapil2ebf3e02016-03-17 19:45:19 +053015454 goto free_mem;
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015455 }
15456#endif
15457
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070015458 /* acquire the wakelock to avoid the apps suspend during the scan. To
15459 * address the following issues.
15460 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
15461 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
15462 * for long time, this result in apps running at full power for long time.
15463 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
15464 * be stuck in full power because of resume BMPS
15465 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015466 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070015467
Nirav Shah20ac06f2013-12-12 18:14:06 +053015468 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
15469 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015470 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
15471 scanRequest.requestType, scanRequest.scanType,
15472 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053015473 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
15474
Hanumantha Reddy Pothulaca1d1cc2015-10-26 15:37:35 +053015475 if (pHddCtx->spoofMacAddr.isEnabled &&
15476 pHddCtx->cfg_ini->enableMacSpoofing == 1)
Siddharth Bhal76972212014-10-15 16:22:51 +053015477 {
15478 hddLog(VOS_TRACE_LEVEL_INFO,
15479 "%s: MAC Spoofing enabled for current scan", __func__);
15480 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
15481 * to fill TxBds for probe request during current scan
15482 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015483 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053015484 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015485
15486 if(status != VOS_STATUS_SUCCESS)
15487 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015488 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015489 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053015490#ifdef FEATURE_WLAN_TDLS
15491 wlan_hdd_tdls_scan_done_callback(pAdapter);
15492#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053015493 goto free_mem;
15494 }
Siddharth Bhal76972212014-10-15 16:22:51 +053015495 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053015496 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070015497 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015498 pAdapter->sessionId, &scanRequest, &scanId,
15499 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070015500
Jeff Johnson295189b2012-06-20 16:38:30 -070015501 if (eHAL_STATUS_SUCCESS != status)
15502 {
15503 hddLog(VOS_TRACE_LEVEL_ERROR,
15504 "%s: sme_ScanRequest returned error %d", __func__, status);
15505 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015506 if(eHAL_STATUS_RESOURCES == status)
15507 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053015508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
15509 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070015510 status = -EBUSY;
15511 } else {
15512 status = -EIO;
15513 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053015514 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053015515
15516#ifdef FEATURE_WLAN_TDLS
15517 wlan_hdd_tdls_scan_done_callback(pAdapter);
15518#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015519 goto free_mem;
15520 }
15521
15522 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053015523 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070015524 pAdapter->request = request;
15525 pScanInfo->scanId = scanId;
Hanumanth Reddy Pothulaf31f65c2018-01-30 19:51:27 +053015526 pScanInfo->no_cck = request->no_cck;
15527 pHddCtx->scan_info.last_scan_numChannels = request->n_channels;
15528 for (i = 0; i < pHddCtx->scan_info.last_scan_numChannels; i++) {
15529 pHddCtx->scan_info.last_scan_channelList[i] =
15530 request->channels[i]->hw_value;
15531 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015532
15533 complete(&pScanInfo->scan_req_completion_event);
15534
15535free_mem:
15536 if( scanRequest.SSIDs.SSIDList )
15537 {
15538 vos_mem_free(scanRequest.SSIDs.SSIDList);
15539 }
15540
15541 if( channelList )
15542 vos_mem_free( channelList );
15543
15544 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015545 return status;
15546}
15547
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053015548int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
15549#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15550 struct net_device *dev,
15551#endif
15552 struct cfg80211_scan_request *request)
15553{
15554 int ret;
15555
15556 vos_ssr_protect(__func__);
15557 ret = __wlan_hdd_cfg80211_scan(wiphy,
15558#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
15559 dev,
15560#endif
15561 request);
15562 vos_ssr_unprotect(__func__);
15563
15564 return ret;
15565}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015566
15567void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
15568{
15569 v_U8_t iniDot11Mode =
15570 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
15571 eHddDot11Mode hddDot11Mode = iniDot11Mode;
15572
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015573 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
15574 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015575 switch ( iniDot11Mode )
15576 {
15577 case eHDD_DOT11_MODE_AUTO:
15578 case eHDD_DOT11_MODE_11ac:
15579 case eHDD_DOT11_MODE_11ac_ONLY:
15580#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053015581 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
15582 sme_IsFeatureSupportedByFW(DOT11AC) )
15583 hddDot11Mode = eHDD_DOT11_MODE_11ac;
15584 else
15585 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015586#else
15587 hddDot11Mode = eHDD_DOT11_MODE_11n;
15588#endif
15589 break;
15590 case eHDD_DOT11_MODE_11n:
15591 case eHDD_DOT11_MODE_11n_ONLY:
15592 hddDot11Mode = eHDD_DOT11_MODE_11n;
15593 break;
15594 default:
15595 hddDot11Mode = iniDot11Mode;
15596 break;
15597 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015598#ifdef WLAN_FEATURE_AP_HT40_24G
15599 if (operationChannel > SIR_11B_CHANNEL_END)
15600#endif
15601 {
15602 /* This call decides required channel bonding mode */
15603 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015604 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
Abhishek Singh02b823e2017-10-30 17:53:20 +053015605 operationChannel, eHT_MAX_CHANNEL_WIDTH);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053015606 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015607}
15608
Jeff Johnson295189b2012-06-20 16:38:30 -070015609/*
15610 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015611 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070015612 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015613int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053015614 const u8 *ssid, size_t ssid_len, const u8 *bssid,
15615 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070015616{
15617 int status = 0;
15618 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080015619 hdd_context_t *pHddCtx;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015620 hdd_station_ctx_t *hdd_sta_ctx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015621 v_U32_t roamId;
15622 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070015623 eCsrAuthType RSNAuthType;
15624
15625 ENTER();
15626
15627 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015628 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053015629 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080015630
15631 status = wlan_hdd_validate_context(pHddCtx);
15632 if (status)
15633 {
Yue Mae36e3552014-03-05 17:06:20 -080015634 return status;
15635 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015636
Jeff Johnson295189b2012-06-20 16:38:30 -070015637 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
15638 {
15639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
15640 return -EINVAL;
15641 }
15642
Nitesh Shah9b066282017-06-06 18:05:52 +053015643 wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
15644
Jeff Johnson295189b2012-06-20 16:38:30 -070015645 pRoamProfile = &pWextState->roamProfile;
15646
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015647 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070015648 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015649 hdd_station_ctx_t *pHddStaCtx;
15650 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Abhishek Singh6782c9e2017-06-06 13:37:45 +053015651 pHddStaCtx->get_mgmt_log_sent = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015652
Siddharth Bhalda0d1622015-04-24 15:47:49 +053015653 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
15654
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015655 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070015656 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
15657 {
15658 /*QoS not enabled in cfg file*/
15659 pRoamProfile->uapsd_mask = 0;
15660 }
15661 else
15662 {
15663 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015664 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070015665 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
15666 }
15667
15668 pRoamProfile->SSIDs.numOfSSIDs = 1;
15669 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
15670 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015671 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070015672 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
15673 ssid, ssid_len);
15674
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015675 vos_mem_zero(pRoamProfile->BSSIDs.bssid, WNI_CFG_BSSID_LEN);
15676 vos_mem_zero(pRoamProfile->bssid_hint, WNI_CFG_BSSID_LEN);
15677
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 if (bssid)
15679 {
15680 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015681 vos_mem_copy(pRoamProfile->BSSIDs.bssid, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015682 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015683 /* Save BSSID in seperate variable as well, as RoamProfile
15684 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070015685 case of join failure we should send valid BSSID to supplicant
15686 */
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015687 vos_mem_copy(pWextState->req_bssId, bssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070015688 WNI_CFG_BSSID_LEN);
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015689
Jeff Johnson295189b2012-06-20 16:38:30 -070015690 }
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015691 else if (bssid_hint)
Dhanashri Atre51981c62013-06-13 11:47:57 -070015692 {
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015693 /* Store bssid_hint to use in the scan filter. */
15694 vos_mem_copy(pRoamProfile->bssid_hint, bssid_hint,
15695 WNI_CFG_BSSID_LEN);
15696 /*
15697 * Save BSSID in seperate variable as well, as RoamProfile
15698 * BSSID is getting zeroed out in the association process. And in
15699 * case of join failure we should send valid BSSID to supplicant
15700 */
15701 vos_mem_copy(pWextState->req_bssId, bssid_hint,
15702 WNI_CFG_BSSID_LEN);
15703 hddLog(LOG1, FL(" bssid_hint: "MAC_ADDRESS_STR),
15704 MAC_ADDR_ARRAY(pRoamProfile->bssid_hint));
Dhanashri Atre51981c62013-06-13 11:47:57 -070015705 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015706
Abhishek Singhb3e376c2017-01-04 15:27:13 +053015707
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015708 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
15709 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070015710 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
15711 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015712 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015713 /*set gen ie*/
15714 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
15715 /*set auth*/
15716 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
15717 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015718#ifdef FEATURE_WLAN_WAPI
15719 if (pAdapter->wapi_info.nWapiMode)
15720 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015721 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015722 switch (pAdapter->wapi_info.wapiAuthMode)
15723 {
15724 case WAPI_AUTH_MODE_PSK:
15725 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015726 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015727 pAdapter->wapi_info.wapiAuthMode);
15728 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
15729 break;
15730 }
15731 case WAPI_AUTH_MODE_CERT:
15732 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015733 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015734 pAdapter->wapi_info.wapiAuthMode);
15735 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
15736 break;
15737 }
15738 } // End of switch
15739 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
15740 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
15741 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070015742 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015743 pRoamProfile->AuthType.numEntries = 1;
15744 pRoamProfile->EncryptionType.numEntries = 1;
15745 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15746 pRoamProfile->mcEncryptionType.numEntries = 1;
15747 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
15748 }
15749 }
15750#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015751#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015752 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015753 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
15754 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
15755 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015756 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
15757 sizeof (tSirGtkOffloadParams));
15758 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015759 }
15760#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015761 pRoamProfile->csrPersona = pAdapter->device_mode;
15762
Jeff Johnson32d95a32012-09-10 13:15:23 -070015763 if( operatingChannel )
15764 {
15765 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
15766 pRoamProfile->ChannelInfo.numOfChannels = 1;
15767 }
Chet Lanctot186b5732013-03-18 10:26:30 -070015768 else
15769 {
15770 pRoamProfile->ChannelInfo.ChannelList = NULL;
15771 pRoamProfile->ChannelInfo.numOfChannels = 0;
15772 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070015773 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
15774 {
15775 hdd_select_cbmode(pAdapter,operatingChannel);
15776 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053015777
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015778 /*
15779 * Change conn_state to connecting before sme_RoamConnect(),
15780 * because sme_RoamConnect() has a direct path to call
15781 * hdd_smeRoamCallback(), which will change the conn_state
15782 * If direct path, conn_state will be accordingly changed
15783 * to NotConnected or Associated by either
15784 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
15785 * in sme_RoamCallback()
15786 * if sme_RomConnect is to be queued,
15787 * Connecting state will remain until it is completed.
15788 * If connection state is not changed,
15789 * connection state will remain in eConnectionState_NotConnected state.
15790 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
15791 * if conn state is eConnectionState_NotConnected.
15792 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
15793 * informed of connect result indication which is an issue.
15794 */
15795
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015796 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15797 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053015798 {
15799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015800 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015801 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
15802 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053015803 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015804 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070015805 pAdapter->sessionId, pRoamProfile, &roamId);
15806
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053015807 if ((eHAL_STATUS_SUCCESS != status) &&
15808 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
15809 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015810
15811 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053015812 hddLog(VOS_TRACE_LEVEL_ERROR,
15813 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
15814 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015815 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015816 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080015817 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053015818 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080015819
15820 pRoamProfile->ChannelInfo.ChannelList = NULL;
15821 pRoamProfile->ChannelInfo.numOfChannels = 0;
15822
Jeff Johnson295189b2012-06-20 16:38:30 -070015823 }
15824 else
15825 {
15826 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
15827 return -EINVAL;
15828 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080015829 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015830 return status;
15831}
15832
15833/*
15834 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
15835 * This function is used to set the authentication type (OPEN/SHARED).
15836 *
15837 */
15838static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
15839 enum nl80211_auth_type auth_type)
15840{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015841 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015842 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15843
15844 ENTER();
15845
15846 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015847 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070015848 {
Jeff Johnson295189b2012-06-20 16:38:30 -070015849 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015850 hddLog(VOS_TRACE_LEVEL_INFO,
15851 "%s: set authentication type to AUTOSWITCH", __func__);
15852 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
15853 break;
15854
15855 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015856#ifdef WLAN_FEATURE_VOWIFI_11R
15857 case NL80211_AUTHTYPE_FT:
15858#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015859 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070015860 "%s: set authentication type to OPEN", __func__);
15861 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
15862 break;
15863
15864 case NL80211_AUTHTYPE_SHARED_KEY:
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 SHARED", __func__);
15867 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
15868 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015869#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015870 case NL80211_AUTHTYPE_NETWORK_EAP:
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 CCKM WPA", __func__);
15873 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
15874 break;
15875#endif
15876
15877
15878 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015879 hddLog(VOS_TRACE_LEVEL_ERROR,
15880 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015881 auth_type);
15882 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
15883 return -EINVAL;
15884 }
15885
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015886 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070015887 pHddStaCtx->conn_info.authType;
15888 return 0;
15889}
15890
15891/*
15892 * FUNCTION: wlan_hdd_set_akm_suite
15893 * This function is used to set the key mgmt type(PSK/8021x).
15894 *
15895 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015896static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070015897 u32 key_mgmt
15898 )
15899{
15900 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15901 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053015902 /* Should be in ieee802_11_defs.h */
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015903#ifndef WLAN_AKM_SUITE_8021X_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015904#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015905#endif
15906#ifndef WLAN_AKM_SUITE_PSK_SHA256
Abhishek Singhae408032014-09-25 17:22:04 +053015907#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Vidyullatha Kanchanapally08197682017-04-18 16:30:11 +053015908#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015909 /*set key mgmt type*/
15910 switch(key_mgmt)
15911 {
15912 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053015913 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015914#ifdef WLAN_FEATURE_VOWIFI_11R
15915 case WLAN_AKM_SUITE_FT_PSK:
15916#endif
15917 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070015918 __func__);
15919 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
15920 break;
15921
15922 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053015923 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015924#ifdef WLAN_FEATURE_VOWIFI_11R
15925 case WLAN_AKM_SUITE_FT_8021X:
15926#endif
15927 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070015928 __func__);
15929 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15930 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080015931#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070015932#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
15933#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
15934 case WLAN_AKM_SUITE_CCKM:
15935 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
15936 __func__);
15937 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
15938 break;
15939#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070015940#ifndef WLAN_AKM_SUITE_OSEN
15941#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
15942 case WLAN_AKM_SUITE_OSEN:
15943 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
15944 __func__);
15945 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
15946 break;
15947#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015948
15949 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070015951 __func__, key_mgmt);
15952 return -EINVAL;
15953
15954 }
15955 return 0;
15956}
15957
15958/*
15959 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015960 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070015961 * (NONE/WEP40/WEP104/TKIP/CCMP).
15962 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015963static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
15964 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070015965 bool ucast
15966 )
15967{
15968 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015969 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070015970 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15971
15972 ENTER();
15973
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015974 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015975 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053015976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070015977 __func__, cipher);
15978 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15979 }
15980 else
15981 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015982
Jeff Johnson295189b2012-06-20 16:38:30 -070015983 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015984 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070015985 {
15986 case IW_AUTH_CIPHER_NONE:
15987 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
15988 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015989
Jeff Johnson295189b2012-06-20 16:38:30 -070015990 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015991 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070015992 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015993
Jeff Johnson295189b2012-06-20 16:38:30 -070015994 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053015995 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070015996 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015997
Jeff Johnson295189b2012-06-20 16:38:30 -070015998 case WLAN_CIPHER_SUITE_TKIP:
15999 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
16000 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016001
Jeff Johnson295189b2012-06-20 16:38:30 -070016002 case WLAN_CIPHER_SUITE_CCMP:
16003 encryptionType = eCSR_ENCRYPT_TYPE_AES;
16004 break;
16005#ifdef FEATURE_WLAN_WAPI
16006 case WLAN_CIPHER_SUITE_SMS4:
16007 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
16008 break;
16009#endif
16010
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080016011#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070016012 case WLAN_CIPHER_SUITE_KRK:
16013 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
16014 break;
16015#endif
16016 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016017 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 __func__, cipher);
16019 return -EOPNOTSUPP;
16020 }
16021 }
16022
16023 if (ucast)
16024 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016025 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016026 __func__, encryptionType);
16027 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
16028 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016029 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016030 encryptionType;
16031 }
16032 else
16033 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016034 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070016035 __func__, encryptionType);
16036 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
16037 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
16038 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
16039 }
16040
16041 return 0;
16042}
16043
16044
16045/*
16046 * FUNCTION: wlan_hdd_cfg80211_set_ie
16047 * This function is used to parse WPA/RSN IE's.
16048 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016049int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016050#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16051 const u8 *ie,
16052#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016053 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016054#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016055 size_t ie_len
16056 )
16057{
16058 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16060 const u8 *genie = ie;
16061#else
Jeff Johnson295189b2012-06-20 16:38:30 -070016062 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016063#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016064 v_U16_t remLen = ie_len;
16065#ifdef FEATURE_WLAN_WAPI
16066 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
16067 u16 *tmp;
16068 v_U16_t akmsuiteCount;
16069 int *akmlist;
16070#endif
16071 ENTER();
16072
16073 /* clear previous assocAddIE */
16074 pWextState->assocAddIE.length = 0;
16075 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016076 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016077
16078 while (remLen >= 2)
16079 {
16080 v_U16_t eLen = 0;
16081 v_U8_t elementId;
16082 elementId = *genie++;
16083 eLen = *genie++;
16084 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016085
Nachiket Kukade4aba5f02017-06-09 15:43:48 +053016086 /* Sanity check on eLen */
16087 if (eLen > remLen) {
16088 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid IE length[%d] for IE[0x%X]",
16089 __func__, eLen, elementId);
16090 VOS_ASSERT(0);
16091 return -EINVAL;
16092 }
16093
Arif Hussain6d2a3322013-11-17 19:50:10 -080016094 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070016095 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016096
16097 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070016098 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016099 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016100 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 -070016101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016102 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016103 "%s: Invalid WPA IE", __func__);
16104 return -EINVAL;
16105 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016106 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070016107 {
16108 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016109 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016110 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016111
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016112 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016113 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016114 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
16115 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016116 VOS_ASSERT(0);
16117 return -ENOMEM;
16118 }
16119 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16120 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16121 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016122
Jeff Johnson295189b2012-06-20 16:38:30 -070016123 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
16124 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16125 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16126 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016127 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
16128 {
Nachiket Kukade3d72b7e2017-06-09 16:58:24 +053016129 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16130 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d]",
16131 __func__, eLen);
16132 VOS_ASSERT(0);
16133 return -EINVAL;
16134 }
16135
Jeff Johnson295189b2012-06-20 16:38:30 -070016136 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
16137 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16138 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
16139 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
16140 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
16141 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016142 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053016143 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070016144 {
16145 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016146 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016147 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016148
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016149 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016150 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016151 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16152 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016153 VOS_ASSERT(0);
16154 return -ENOMEM;
16155 }
16156 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
16157 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16158 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016159
Jeff Johnson295189b2012-06-20 16:38:30 -070016160 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16161 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16162 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016163#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016164 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
16165 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070016166 /*Consider WFD IE, only for P2P Client */
16167 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
16168 {
16169 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016170 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070016171 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016172
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016173 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070016174 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016175 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16176 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070016177 VOS_ASSERT(0);
16178 return -ENOMEM;
16179 }
16180 // WFD IE is saved to Additional IE ; it should be accumulated to handle
16181 // WPS IE + P2P IE + WFD IE
16182 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16183 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016184
Jeff Johnson295189b2012-06-20 16:38:30 -070016185 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16186 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16187 }
16188#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016189 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016190 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016191 HS20_OUI_TYPE_SIZE)) )
16192 {
16193 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016194 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016195 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016196
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016197 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016198 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016199 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16200 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016201 VOS_ASSERT(0);
16202 return -ENOMEM;
16203 }
16204 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16205 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016206
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070016207 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16208 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16209 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016210 /* Appending OSEN Information Element in Assiciation Request */
16211 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
16212 OSEN_OUI_TYPE_SIZE)) )
16213 {
16214 v_U16_t curAddIELen = pWextState->assocAddIE.length;
16215 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
16216 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016217
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016218 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070016219 {
16220 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16221 "Need bigger buffer space");
16222 VOS_ASSERT(0);
16223 return -ENOMEM;
16224 }
16225 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16226 pWextState->assocAddIE.length += eLen + 2;
16227
16228 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
16229 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16230 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16231 }
16232
Abhishek Singh4322e622015-06-10 15:42:54 +053016233 /* Update only for WPA IE */
16234 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
16235 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016236
16237 /* populating as ADDIE in beacon frames */
16238 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016239 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016240 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
16241 {
16242 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16243 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
16244 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16245 {
16246 hddLog(LOGE,
16247 "Coldn't pass "
16248 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
16249 }
16250 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
16251 else
16252 hddLog(LOGE,
16253 "Could not pass on "
16254 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
16255
16256 /* IBSS mode doesn't contain params->proberesp_ies still
16257 beaconIE's need to be populated in probe response frames */
16258 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
16259 {
16260 u16 rem_probe_resp_ie_len = eLen + 2;
16261 u8 probe_rsp_ie_len[3] = {0};
16262 u8 counter = 0;
16263
16264 /* Check Probe Resp Length if it is greater then 255 then
16265 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
16266 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
16267 not able Store More then 255 bytes into One Variable */
16268
16269 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
16270 {
16271 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
16272 {
16273 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
16274 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
16275 }
16276 else
16277 {
16278 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
16279 rem_probe_resp_ie_len = 0;
16280 }
16281 }
16282
16283 rem_probe_resp_ie_len = 0;
16284
16285 if (probe_rsp_ie_len[0] > 0)
16286 {
16287 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16288 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
16289 (tANI_U8*)(genie - 2),
16290 probe_rsp_ie_len[0], NULL,
16291 eANI_BOOLEAN_FALSE)
16292 == eHAL_STATUS_FAILURE)
16293 {
16294 hddLog(LOGE,
16295 "Could not pass"
16296 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
16297 }
16298 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
16299 }
16300
16301 if (probe_rsp_ie_len[1] > 0)
16302 {
16303 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16304 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
16305 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16306 probe_rsp_ie_len[1], NULL,
16307 eANI_BOOLEAN_FALSE)
16308 == eHAL_STATUS_FAILURE)
16309 {
16310 hddLog(LOGE,
16311 "Could not pass"
16312 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
16313 }
16314 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
16315 }
16316
16317 if (probe_rsp_ie_len[2] > 0)
16318 {
16319 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
16320 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
16321 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
16322 probe_rsp_ie_len[2], NULL,
16323 eANI_BOOLEAN_FALSE)
16324 == eHAL_STATUS_FAILURE)
16325 {
16326 hddLog(LOGE,
16327 "Could not pass"
16328 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
16329 }
16330 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
16331 }
16332
16333 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
16334 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
16335 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
16336 {
16337 hddLog(LOGE,
16338 "Could not pass"
16339 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
16340 }
16341 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070016342 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070016343 break;
16344 case DOT11F_EID_RSN:
Nachiket Kukade307d4892018-01-23 23:36:25 +053016345 if (eLen > (MAX_WPA_RSN_IE_LEN - 2)) {
16346 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Invalid WPA RSN IE length[%d], exceeds %d bytes",
16347 __func__, eLen, MAX_WPA_RSN_IE_LEN - 2);
16348 VOS_ASSERT(0);
16349 return -EINVAL;
16350 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016351 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
16352 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
16353 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
16354 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
16355 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
16356 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053016357
Abhishek Singhb16f3562016-01-20 11:08:32 +053016358 /* Appending extended capabilities with Interworking or
16359 * bsstransition bit set in Assoc Req.
Abhishek Singh15d95602015-03-24 15:52:57 +053016360 *
16361 * In assoc req this EXT Cap will only be taken into account if
Abhishek Singhb16f3562016-01-20 11:08:32 +053016362 * interworkingService or bsstransition bit is set to 1.
16363 * Driver is only interested in interworkingService and
16364 * bsstransition capability from supplicant.
16365 * If in future any other EXT Cap info is
Abhishek Singh15d95602015-03-24 15:52:57 +053016366 * required from supplicat, it needs to be handled while
16367 * sending Assoc Req in LIM.
16368 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016369 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016370 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016371 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016372 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016373 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016374
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053016375 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016376 {
Jeff Johnson902c9832012-12-10 14:28:09 -080016377 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
16378 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016379 VOS_ASSERT(0);
16380 return -ENOMEM;
16381 }
16382 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
16383 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016384
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016385 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
16386 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
16387 break;
16388 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016389#ifdef FEATURE_WLAN_WAPI
16390 case WLAN_EID_WAPI:
16391 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016392 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070016393 pAdapter->wapi_info.nWapiMode);
16394 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016395 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070016396 akmsuiteCount = WPA_GET_LE16(tmp);
16397 tmp = tmp + 1;
16398 akmlist = (int *)(tmp);
16399 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
16400 {
16401 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
16402 }
16403 else
16404 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016405 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070016406 VOS_ASSERT(0);
16407 return -EINVAL;
16408 }
16409
16410 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
16411 {
16412 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070016413 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070016414 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016415 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016416 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016417 {
Jeff Johnson295189b2012-06-20 16:38:30 -070016418 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
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_CERT;
16421 }
16422 break;
16423#endif
16424 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016425 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016426 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070016427 /* when Unknown IE is received we should break and continue
16428 * to the next IE in the buffer instead we were returning
16429 * so changing this to break */
16430 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070016431 }
16432 genie += eLen;
16433 remLen -= eLen;
16434 }
16435 EXIT();
16436 return 0;
16437}
16438
16439/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016440 * FUNCTION: hdd_isWPAIEPresent
16441 * Parse the received IE to find the WPA IE
16442 *
16443 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016444static bool hdd_isWPAIEPresent(
16445#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
16446 const u8 *ie,
16447#else
16448 u8 *ie,
16449#endif
16450 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053016451{
16452 v_U8_t eLen = 0;
16453 v_U16_t remLen = ie_len;
16454 v_U8_t elementId = 0;
16455
16456 while (remLen >= 2)
16457 {
16458 elementId = *ie++;
16459 eLen = *ie++;
16460 remLen -= 2;
16461 if (eLen > remLen)
16462 {
16463 hddLog(VOS_TRACE_LEVEL_ERROR,
16464 "%s: IE length is wrong %d", __func__, eLen);
16465 return FALSE;
16466 }
16467 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
16468 {
16469 /* OUI - 0x00 0X50 0XF2
16470 WPA Information Element - 0x01
16471 WPA version - 0x01*/
16472 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
16473 return TRUE;
16474 }
16475 ie += eLen;
16476 remLen -= eLen;
16477 }
16478 return FALSE;
16479}
16480
16481/*
Jeff Johnson295189b2012-06-20 16:38:30 -070016482 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016483 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070016484 * parameters during connect operation.
16485 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016486int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070016487 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016488 )
Jeff Johnson295189b2012-06-20 16:38:30 -070016489{
16490 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016491 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070016492 ENTER();
16493
16494 /*set wpa version*/
16495 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
16496
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016497 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016498 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053016499 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070016500 {
16501 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
16502 }
16503 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
16504 {
16505 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
16506 }
16507 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016508
16509 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070016510 pWextState->wpaVersion);
16511
16512 /*set authentication type*/
16513 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
16514
16515 if (0 > status)
16516 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016517 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016518 "%s: failed to set authentication type ", __func__);
16519 return status;
16520 }
16521
16522 /*set key mgmt type*/
16523 if (req->crypto.n_akm_suites)
16524 {
16525 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
16526 if (0 > status)
16527 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016528 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070016529 __func__);
16530 return status;
16531 }
16532 }
16533
16534 /*set pairwise cipher type*/
16535 if (req->crypto.n_ciphers_pairwise)
16536 {
16537 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
16538 req->crypto.ciphers_pairwise[0], true);
16539 if (0 > status)
16540 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016541 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016542 "%s: failed to set unicast cipher type", __func__);
16543 return status;
16544 }
16545 }
16546 else
16547 {
16548 /*Reset previous cipher suite to none*/
16549 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
16550 if (0 > status)
16551 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016552 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016553 "%s: failed to set unicast cipher type", __func__);
16554 return status;
16555 }
16556 }
16557
16558 /*set group cipher type*/
16559 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
16560 false);
16561
16562 if (0 > status)
16563 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016564 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070016565 __func__);
16566 return status;
16567 }
16568
Chet Lanctot186b5732013-03-18 10:26:30 -070016569#ifdef WLAN_FEATURE_11W
16570 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
16571#endif
16572
Jeff Johnson295189b2012-06-20 16:38:30 -070016573 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
16574 if (req->ie_len)
16575 {
16576 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
16577 if ( 0 > status)
16578 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016579 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070016580 __func__);
16581 return status;
16582 }
16583 }
16584
16585 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016586 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016587 {
16588 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
16589 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
16590 )
16591 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016592 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070016593 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
16594 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070016596 __func__);
16597 return -EOPNOTSUPP;
16598 }
16599 else
16600 {
16601 u8 key_len = req->key_len;
16602 u8 key_idx = req->key_idx;
16603
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016604 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070016605 && (CSR_MAX_NUM_KEY > key_idx)
16606 )
16607 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016608 hddLog(VOS_TRACE_LEVEL_INFO,
16609 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070016610 __func__, key_idx, key_len);
16611 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016612 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070016613 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016614 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070016615 (u8)key_len;
16616 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
16617 }
16618 }
16619 }
16620 }
16621
16622 return status;
16623}
16624
16625/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016626 * FUNCTION: wlan_hdd_try_disconnect
16627 * This function is used to disconnect from previous
16628 * connection
16629 */
Agrawal Ashishc407f192017-01-23 17:18:35 +053016630int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016631{
16632 long ret = 0;
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016633 int status, result = 0;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016634 hdd_station_ctx_t *pHddStaCtx;
16635 eMib_dot11DesiredBssType connectedBssType;
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016636 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016637
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016638 ret = wlan_hdd_validate_context(pHddCtx);
16639 if (0 != ret)
16640 {
16641 return ret;
16642 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016643 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16644
16645 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
16646
16647 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
16648 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
Abhishek Singh630ff592016-01-07 18:15:53 +053016649 (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) ||
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016650 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
16651 {
Abhishek Singh9f4df782017-03-15 17:29:10 +053016652 /* Indicate disconnect to SME so that in-progress connection or preauth
16653 * can be aborted
16654 */
16655 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
16656 pAdapter->sessionId);
Abhishek Singh19a7dd92015-12-30 16:31:51 +053016657 spin_lock_bh(&pAdapter->lock_for_active_session);
16658 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
16659 {
16660 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
16661 }
16662 spin_unlock_bh(&pAdapter->lock_for_active_session);
Abhishek Singhf7962582015-10-23 10:54:06 +053016663 hdd_connSetConnectionState(pHddStaCtx,
16664 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016665 /* Issue disconnect to CSR */
16666 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016667 status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016668 pAdapter->sessionId,
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016669 eCSR_DISCONNECT_REASON_UNSPECIFIED);
16670 if(eHAL_STATUS_CMD_NOT_QUEUED == status) {
16671 hddLog(LOG1,
16672 FL("Already disconnected or connect was in sme/roam pending list and removed by disconnect"));
16673 } else if ( 0 != status ) {
16674 hddLog(LOGE,
16675 FL("csrRoamDisconnect failure, returned %d"),
16676 (int)status );
16677 result = -EINVAL;
16678 goto disconnected;
16679 }
16680 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016681 &pAdapter->disconnect_comp_var,
16682 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016683 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status)) {
16684 hddLog(LOGE,
16685 "%s: Failed to disconnect, timed out", __func__);
16686 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016687 }
16688 }
16689 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
16690 {
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016691 ret = wait_for_completion_timeout(
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016692 &pAdapter->disconnect_comp_var,
16693 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016694 if (!ret)
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016695 {
16696 hddLog(LOGE, FL("Failed to receive disconnect event"));
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016697 result = -ETIMEDOUT;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016698 }
16699 }
Abhishek Singhf1b048a2016-01-13 13:57:27 +053016700disconnected:
16701 hddLog(LOG1,
16702 FL("Set HDD connState to eConnectionState_NotConnected"));
16703 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
16704 return result;
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016705}
16706
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016707/**
16708 * wlan_hdd_reassoc_bssid_hint() - Start reassociation if bssid is present
16709 * @adapter: Pointer to the HDD adapter
16710 * @req: Pointer to the structure cfg_connect_params receieved from user space
16711 *
16712 * This function will start reassociation if bssid hint, channel hint and
16713 * previous bssid parameters are present in the connect request
16714 *
16715 * Return: success if reassociation is happening
16716 * Error code if reassociation is not permitted or not happening
16717 */
16718#ifdef CFG80211_CONNECT_PREV_BSSID
16719static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16720 struct cfg80211_connect_params *req)
16721{
16722 int status = -EPERM;
16723 if (req->bssid_hint && req->channel_hint && req->prev_bssid) {
16724 hddLog(VOS_TRACE_LEVEL_INFO,
16725 FL("REASSOC Attempt on channel %d to "MAC_ADDRESS_STR),
16726 req->channel_hint->hw_value,
16727 MAC_ADDR_ARRAY(req->bssid_hint));
16728 status = hdd_reassoc(adapter, req->bssid_hint,
16729 req->channel_hint->hw_value,
16730 CONNECT_CMD_USERSPACE);
16731 }
16732 return status;
16733}
16734#else
16735static int wlan_hdd_reassoc_bssid_hint(hdd_adapter_t *adapter,
16736 struct cfg80211_connect_params *req)
16737{
16738 return -EPERM;
16739}
16740#endif
16741
Abhishek Singhe3beee22017-07-31 15:35:40 +053016742/**
16743 * wlan_hdd_check_ht20_ht40_ind() - check if Supplicant has indicated to
16744 * connect in HT20 mode
16745 * @hdd_ctx: hdd context
16746 * @adapter: Pointer to the HDD adapter
16747 * @req: Pointer to the structure cfg_connect_params receieved from user space
16748 *
16749 * This function will check if supplicant has indicated to to connect in HT20
16750 * mode. this is currently applicable only for 2.4Ghz mode only.
16751 * if feature is enabled and supplicant indicate HT20 set
16752 * force_24ghz_in_ht20 to true to force 2.4Ghz in HT20 else set it to false.
16753 *
16754 * Return: void
16755 */
16756#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)
16757static void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16758 hdd_adapter_t *adapter,
16759 struct cfg80211_connect_params *req)
16760{
16761 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16762 tCsrRoamProfile *roam_profile;
16763
16764 roam_profile = &wext_state->roamProfile;
16765 roam_profile->force_24ghz_in_ht20 = false;
16766 if (hdd_ctx->cfg_ini->override_ht20_40_24g &&
16767 !(req->ht_capa.cap_info &
16768 IEEE80211_HT_CAP_SUP_WIDTH_20_40))
16769 roam_profile->force_24ghz_in_ht20 = true;
16770
16771 hddLog(LOG1, FL("req->ht_capa.cap_info %x override_ht20_40_24g %d"),
16772 req->ht_capa.cap_info, hdd_ctx->cfg_ini->override_ht20_40_24g);
16773}
16774#else
16775static inline void wlan_hdd_check_ht20_ht40_ind(hdd_context_t *hdd_ctx,
16776 hdd_adapter_t *adapter,
16777 struct cfg80211_connect_params *req)
16778{
16779 hdd_wext_state_t *wext_state = WLAN_HDD_GET_WEXT_STATE_PTR(adapter);
16780 tCsrRoamProfile *roam_profile;
16781
16782 roam_profile = &wext_state->roamProfile;
16783 roam_profile->force_24ghz_in_ht20 = false;
16784}
16785#endif
16786
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016787/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053016788 * FUNCTION: __wlan_hdd_cfg80211_connect
16789 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070016790 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016791static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016792 struct net_device *ndev,
16793 struct cfg80211_connect_params *req
16794 )
16795{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016796 int status;
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016797 u16 channel;
Edhar, Mahesh Kumar496c7f72016-03-18 12:47:44 +053016798#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) || \
16799 defined(CFG80211_BSSID_HINT_BACKPORT)
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016800 const u8 *bssid_hint = req->bssid_hint;
16801#else
16802 const u8 *bssid_hint = NULL;
16803#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016804 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070016805 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053016806 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070016807
16808 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016809
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016810 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16811 TRACE_CODE_HDD_CFG80211_CONNECT,
16812 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016813 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016814 "%s: device_mode = %s (%d)", __func__,
16815 hdd_device_modetoString(pAdapter->device_mode),
16816 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016817
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016818 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016819 if (!pHddCtx)
16820 {
16821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16822 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053016823 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080016824 }
16825
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016826 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016827 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016829 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016830 }
16831
Rajeev Kumar Sirasanagandla8f11d542017-11-14 17:56:55 +053016832 if (wlan_hdd_check_and_stop_mon(pAdapter, true))
16833 return -EINVAL;
16834
Selvaraj, Sridhar95e226f2016-06-18 12:27:25 +053016835 status = wlan_hdd_reassoc_bssid_hint(pAdapter, req);
16836 if (0 == status)
16837 return status;
16838
Agarwal Ashish51325b52014-06-16 16:50:49 +053016839
Jeff Johnson295189b2012-06-20 16:38:30 -070016840#ifdef WLAN_BTAMP_FEATURE
16841 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016842 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070016843 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016844 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016845 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080016846 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070016847 }
16848#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016849
16850 //If Device Mode is Station Concurrent Sessions Exit BMps
16851 //P2P Mode will be taken care in Open/close adapter
16852 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053016853 (vos_concurrent_open_sessions_running())) {
16854 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
16855 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016856 }
16857
16858 /*Try disconnecting if already in connected state*/
16859 status = wlan_hdd_try_disconnect(pAdapter);
16860 if ( 0 > status)
16861 {
16862 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
16863 " connection"));
16864 return -EALREADY;
16865 }
Agrawal Ashish559530c2015-12-01 18:04:20 +053016866 /* Check for max concurrent connections after doing disconnect if any*/
16867 if (vos_max_concurrent_connections_reached()) {
16868 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16869 return -ECONNREFUSED;
16870 }
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053016871
Jeff Johnson295189b2012-06-20 16:38:30 -070016872 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016873 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070016874
16875 if ( 0 > status)
16876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070016878 __func__);
16879 return status;
16880 }
Sravan Kumar Kairam589c5722016-01-27 20:28:53 +053016881
16882 if (pHddCtx->spoofMacAddr.isEnabled)
16883 {
16884 hddLog(VOS_TRACE_LEVEL_INFO,
16885 "%s: MAC Spoofing enabled ", __func__);
16886 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
16887 * to fill TxBds for probe request during SSID scan which may happen
16888 * as part of connect command
16889 */
16890 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
16891 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
16892 if (status != VOS_STATUS_SUCCESS)
16893 return -ECONNREFUSED;
16894 }
16895
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016896 if (req->channel)
16897 channel = req->channel->hw_value;
Mohit Khanna765234a2012-09-11 15:08:35 -070016898 else
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016899 channel = 0;
Kapil Gupta312028a2016-10-25 14:15:20 +053016900
16901 /* Abort if any scan is going on */
16902 status = wlan_hdd_scan_abort(pAdapter);
16903 if (0 != status)
16904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("scan abort failed"));
16905
Abhishek Singhe3beee22017-07-31 15:35:40 +053016906 wlan_hdd_check_ht20_ht40_ind(pHddCtx, pAdapter, req);
16907
Sreelakshmi Konamkie6521742016-03-18 12:44:27 +053016908 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
16909 req->ssid_len, req->bssid,
16910 bssid_hint, channel);
Jeff Johnson295189b2012-06-20 16:38:30 -070016911
Sushant Kaushikd7083982015-03-18 14:33:24 +053016912 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070016913 {
16914 //ReEnable BMPS if disabled
16915 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
16916 (NULL != pHddCtx))
16917 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053016918 if (pHddCtx->hdd_wlan_suspended)
16919 {
16920 hdd_set_pwrparams(pHddCtx);
16921 }
Jeff Johnson295189b2012-06-20 16:38:30 -070016922 //ReEnable Bmps and Imps back
16923 hdd_enable_bmps_imps(pHddCtx);
16924 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053016925 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070016926 return status;
16927 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016928 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016929 EXIT();
16930 return status;
16931}
16932
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016933static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
16934 struct net_device *ndev,
16935 struct cfg80211_connect_params *req)
16936{
16937 int ret;
16938 vos_ssr_protect(__func__);
16939 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
16940 vos_ssr_unprotect(__func__);
16941
16942 return ret;
16943}
Jeff Johnson295189b2012-06-20 16:38:30 -070016944
16945/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016946 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070016947 * This function is used to issue a disconnect request to SME
16948 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053016949static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070016950 struct net_device *dev,
16951 u16 reason
16952 )
16953{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016954 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016955 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016956 tCsrRoamProfile *pRoamProfile;
16957 hdd_station_ctx_t *pHddStaCtx;
16958 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053016959#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080016960 tANI_U8 staIdx;
16961#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016962
Jeff Johnson295189b2012-06-20 16:38:30 -070016963 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016964
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016965 if (!pAdapter) {
16966 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16967 return -EINVAL;
16968 }
16969
16970 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16971 if (!pHddStaCtx) {
16972 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
16973 return -EINVAL;
16974 }
16975
16976 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16977 status = wlan_hdd_validate_context(pHddCtx);
16978 if (0 != status)
16979 {
16980 return status;
16981 }
16982
16983 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
16984
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016985 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16986 TRACE_CODE_HDD_CFG80211_DISCONNECT,
16987 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016988 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
16989 __func__, hdd_device_modetoString(pAdapter->device_mode),
16990 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070016991
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
16993 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070016994
Jeff Johnson295189b2012-06-20 16:38:30 -070016995 if (NULL != pRoamProfile)
16996 {
16997 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053016998 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
16999 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070017000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017001 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070017002 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017003 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070017004 switch(reason)
17005 {
17006 case WLAN_REASON_MIC_FAILURE:
17007 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
17008 break;
17009
17010 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
17011 case WLAN_REASON_DISASSOC_AP_BUSY:
17012 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
17013 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
17014 break;
17015
17016 case WLAN_REASON_PREV_AUTH_NOT_VALID:
17017 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053017018 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070017019 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
17020 break;
17021
Jeff Johnson295189b2012-06-20 16:38:30 -070017022 default:
17023 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
17024 break;
17025 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017026 pScanInfo = &pHddCtx->scan_info;
17027 if (pScanInfo->mScanPending)
17028 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017029 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017030 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053017031 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053017032 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053017033 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053017034 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017035#ifdef FEATURE_WLAN_TDLS
17036 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017037 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017038 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017039 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
17040 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017041 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017042 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017043 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017045 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080017046 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017047 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017048 status = sme_DeleteTdlsPeerSta(
17049 WLAN_HDD_GET_HAL_CTX(pAdapter),
17050 pAdapter->sessionId,
17051 mac);
17052 if (status != eHAL_STATUS_SUCCESS) {
17053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17054 return -EPERM;
17055 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080017056 }
17057 }
17058#endif
Padma, Santhosh Kumar5f7d10e2016-12-05 18:55:06 +053017059
17060 hddLog(LOG1, FL("Disconnecting with reasoncode:%u connState %d"),
17061 reasonCode,
17062 pHddStaCtx->conn_info.connState);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017063 status = wlan_hdd_disconnect(pAdapter, reasonCode);
17064 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070017065 {
17066 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017067 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017068 __func__, (int)status );
17069 return -EINVAL;
17070 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017071 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053017072 else
17073 {
17074 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
17075 "called while in %d state", __func__,
17076 pHddStaCtx->conn_info.connState);
17077 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017078 }
17079 else
17080 {
17081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
17082 }
17083
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017084 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017085 return status;
17086}
17087
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053017088static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
17089 struct net_device *dev,
17090 u16 reason
17091 )
17092{
17093 int ret;
17094 vos_ssr_protect(__func__);
17095 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
17096 vos_ssr_unprotect(__func__);
17097
17098 return ret;
17099}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053017100
Jeff Johnson295189b2012-06-20 16:38:30 -070017101/*
17102 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017103 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070017104 * settings in IBSS mode.
17105 */
17106static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017107 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070017108 struct cfg80211_ibss_params *params
17109 )
17110{
17111 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017112 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070017113 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
17114 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017115
Jeff Johnson295189b2012-06-20 16:38:30 -070017116 ENTER();
17117
17118 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070017119 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070017120
17121 if (params->ie_len && ( NULL != params->ie) )
17122 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017123 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17124 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017125 {
17126 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
17127 encryptionType = eCSR_ENCRYPT_TYPE_AES;
17128 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017129 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070017130 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017131 tDot11fIEWPA dot11WPAIE;
17132 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017133 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017134
Wilson Yang00256342013-10-10 23:13:38 -070017135 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017136 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
17137 params->ie_len, DOT11F_EID_WPA);
17138 if ( NULL != ie )
17139 {
17140 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
17141 // Unpack the WPA IE
17142 //Skip past the EID byte and length byte - and four byte WiFi OUI
17143 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
17144 &ie[2+4],
17145 ie[1] - 4,
17146 &dot11WPAIE);
17147 /*Extract the multicast cipher, the encType for unicast
17148 cipher for wpa-none is none*/
17149 encryptionType =
17150 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
17151 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017152 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070017153
Jeff Johnson295189b2012-06-20 16:38:30 -070017154 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
17155
17156 if (0 > status)
17157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017158 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070017159 __func__);
17160 return status;
17161 }
17162 }
17163
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017164 pWextState->roamProfile.AuthType.authType[0] =
17165 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070017166 eCSR_AUTH_TYPE_OPEN_SYSTEM;
Jeff Johnson295189b2012-06-20 16:38:30 -070017167 if (params->privacy)
17168 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017169 /* Security enabled IBSS, At this time there is no information available
17170 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070017171 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017172 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070017173 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017174 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070017175 *enable privacy bit in beacons */
17176
17177 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
17178 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070017179 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
17180 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070017181 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
17182 pWextState->roamProfile.EncryptionType.numEntries = 1;
17183 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070017184 return status;
17185}
17186
17187/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017188 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017189 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017190 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017191static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017192 struct net_device *dev,
17193 struct cfg80211_ibss_params *params
17194 )
17195{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017196 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070017197 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17198 tCsrRoamProfile *pRoamProfile;
17199 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017200 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17201 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017202 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070017203
17204 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017205
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017206 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17207 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
17208 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017209 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017210 "%s: device_mode = %s (%d)", __func__,
17211 hdd_device_modetoString(pAdapter->device_mode),
17212 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017213
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017214 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017215 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017216 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017217 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017218 }
17219
17220 if (NULL == pWextState)
17221 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017222 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017223 __func__);
17224 return -EIO;
17225 }
17226
Agarwal Ashish51325b52014-06-16 16:50:49 +053017227 if (vos_max_concurrent_connections_reached()) {
17228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17229 return -ECONNREFUSED;
17230 }
17231
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053017232 /*Try disconnecting if already in connected state*/
17233 status = wlan_hdd_try_disconnect(pAdapter);
17234 if ( 0 > status)
17235 {
17236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
17237 " IBSS connection"));
17238 return -EALREADY;
17239 }
17240
Jeff Johnson295189b2012-06-20 16:38:30 -070017241 pRoamProfile = &pWextState->roamProfile;
17242
17243 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
17244 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017245 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017246 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017247 return -EINVAL;
17248 }
17249
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017250 /* BSSID is provided by upper layers hence no need to AUTO generate */
17251 if (NULL != params->bssid) {
17252 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17253 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
17254 hddLog (VOS_TRACE_LEVEL_ERROR,
17255 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17256 return -EIO;
17257 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017258 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017259 }
krunal sonie9002db2013-11-25 14:24:17 -080017260 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
17261 {
17262 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
17263 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
17264 {
17265 hddLog (VOS_TRACE_LEVEL_ERROR,
17266 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
17267 return -EIO;
17268 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017269
17270 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080017271 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017272 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080017273 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070017274
Jeff Johnson295189b2012-06-20 16:38:30 -070017275 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070017276 if (NULL !=
17277#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17278 params->chandef.chan)
17279#else
17280 params->channel)
17281#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017282 {
17283 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017284 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
17285 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
17286 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17287 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070017288
17289 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017290 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070017291 ieee80211_frequency_to_channel(
17292#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
17293 params->chandef.chan->center_freq);
17294#else
17295 params->channel->center_freq);
17296#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017297
17298 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
17299 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070017300 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017301 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
17302 __func__);
17303 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070017304 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017305
17306 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070017307 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017308 if (channelNum == validChan[indx])
17309 {
17310 break;
17311 }
17312 }
17313 if (indx >= numChans)
17314 {
17315 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070017316 __func__, channelNum);
17317 return -EINVAL;
17318 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017319 /* Set the Operational Channel */
17320 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
17321 channelNum);
17322 pRoamProfile->ChannelInfo.numOfChannels = 1;
17323 pHddStaCtx->conn_info.operationChannel = channelNum;
17324 pRoamProfile->ChannelInfo.ChannelList =
17325 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070017326 }
17327
17328 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017329 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070017330 if (status < 0)
17331 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017332 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070017333 __func__);
17334 return status;
17335 }
17336
17337 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017338 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Abhishek Singh4d924682015-11-17 15:23:06 +053017339 params->ssid_len, (const u8 *)&bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070017340 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070017341
17342 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070017343 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070017344
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017345 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017346 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017347}
17348
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017349static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
17350 struct net_device *dev,
17351 struct cfg80211_ibss_params *params
17352 )
17353{
17354 int ret = 0;
17355
17356 vos_ssr_protect(__func__);
17357 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
17358 vos_ssr_unprotect(__func__);
17359
17360 return ret;
17361}
17362
Jeff Johnson295189b2012-06-20 16:38:30 -070017363/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017364 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017365 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070017366 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017367static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017368 struct net_device *dev
17369 )
17370{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017372 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
17373 tCsrRoamProfile *pRoamProfile;
17374 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017375 int status;
Abhishek Singh69de3302016-11-11 16:44:32 +053017376 eHalStatus hal_status;
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017377#ifdef WLAN_FEATURE_RMC
17378 tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN] = {0};
17379#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017380
17381 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017382
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017383 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17384 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
17385 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017386 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017387 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017388 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017389 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017390 }
17391
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017392 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
17393 hdd_device_modetoString(pAdapter->device_mode),
17394 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070017395 if (NULL == pWextState)
17396 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080017397 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070017398 __func__);
17399 return -EIO;
17400 }
17401
17402 pRoamProfile = &pWextState->roamProfile;
17403
17404 /* Issue disconnect only if interface type is set to IBSS */
17405 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
17406 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017407 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070017408 __func__);
17409 return -EINVAL;
17410 }
17411
Abhishek Singh7cd040e2016-01-07 10:51:04 +053017412#ifdef WLAN_FEATURE_RMC
17413 /* Clearing add IE of beacon */
17414 if (ccmCfgSetStr(pHddCtx->hHal,
17415 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0],
17416 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN,
17417 NULL, eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17418 {
17419 hddLog (VOS_TRACE_LEVEL_ERROR,
17420 "%s: unable to clear PROBE_RSP_BCN_ADDNIE_DATA", __func__);
17421 return -EINVAL;
17422 }
17423 if (ccmCfgSetInt(pHddCtx->hHal,
17424 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0, NULL,
17425 eANI_BOOLEAN_FALSE) != eHAL_STATUS_SUCCESS)
17426 {
17427 hddLog (VOS_TRACE_LEVEL_ERROR,
17428 "%s: unable to clear WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG",
17429 __func__);
17430 return -EINVAL;
17431 }
17432
17433 // Reset WNI_CFG_PROBE_RSP Flags
17434 wlan_hdd_reset_prob_rspies(pAdapter);
17435
17436 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
17437 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 0,NULL,
17438 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
17439 {
17440 hddLog (VOS_TRACE_LEVEL_ERROR,
17441 "%s: unable to clear WNI_CFG_PROBE_RSP_ADDNIE_FLAG",
17442 __func__);
17443 return -EINVAL;
17444 }
17445#endif
17446
Jeff Johnson295189b2012-06-20 16:38:30 -070017447 /* Issue Disconnect request */
17448 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Abhishek Singh69de3302016-11-11 16:44:32 +053017449 hal_status = sme_RoamDisconnect(WLAN_HDD_GET_HAL_CTX(pAdapter),
17450 pAdapter->sessionId,
17451 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
17452 if (!HAL_STATUS_SUCCESS(hal_status)) {
17453 hddLog(LOGE,
17454 FL("sme_RoamDisconnect failed hal_status(%d)"),
17455 hal_status);
17456 return -EAGAIN;
17457 }
17458 status = wait_for_completion_timeout(
17459 &pAdapter->disconnect_comp_var,
17460 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
17461 if (!status) {
17462 hddLog(LOGE,
17463 FL("wait on disconnect_comp_var failed"));
17464 return -ETIMEDOUT;
17465 }
Jeff Johnson295189b2012-06-20 16:38:30 -070017466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017467 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017468 return 0;
17469}
17470
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017471static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
17472 struct net_device *dev
17473 )
17474{
17475 int ret = 0;
17476
17477 vos_ssr_protect(__func__);
17478 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
17479 vos_ssr_unprotect(__func__);
17480
17481 return ret;
17482}
17483
Jeff Johnson295189b2012-06-20 16:38:30 -070017484/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017485 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070017486 * This function is used to set the phy parameters
17487 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
17488 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017489static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070017490 u32 changed)
17491{
17492 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17493 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017494 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017495
17496 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017497
17498 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017499 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
17500 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017502 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017503 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017504 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017505 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017506 }
17507
Jeff Johnson295189b2012-06-20 16:38:30 -070017508 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
17509 {
17510 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
17511 WNI_CFG_RTS_THRESHOLD_STAMAX :
17512 wiphy->rts_threshold;
17513
17514 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017515 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070017516 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017517 hddLog(VOS_TRACE_LEVEL_ERROR,
17518 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017519 __func__, rts_threshold);
17520 return -EINVAL;
17521 }
17522
17523 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
17524 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017525 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017526 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017527 hddLog(VOS_TRACE_LEVEL_ERROR,
17528 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017529 __func__, rts_threshold);
17530 return -EIO;
17531 }
17532
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017533 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017534 rts_threshold);
17535 }
17536
17537 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
17538 {
17539 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
17540 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
17541 wiphy->frag_threshold;
17542
17543 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017544 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070017545 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017546 hddLog(VOS_TRACE_LEVEL_ERROR,
17547 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070017548 frag_threshold);
17549 return -EINVAL;
17550 }
17551
17552 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
17553 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017554 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017555 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017556 hddLog(VOS_TRACE_LEVEL_ERROR,
17557 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017558 __func__, frag_threshold);
17559 return -EIO;
17560 }
17561
17562 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
17563 frag_threshold);
17564 }
17565
17566 if ((changed & WIPHY_PARAM_RETRY_SHORT)
17567 || (changed & WIPHY_PARAM_RETRY_LONG))
17568 {
17569 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
17570 wiphy->retry_short :
17571 wiphy->retry_long;
17572
17573 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
17574 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
17575 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017576 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017577 __func__, retry_value);
17578 return -EINVAL;
17579 }
17580
17581 if (changed & WIPHY_PARAM_RETRY_SHORT)
17582 {
17583 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
17584 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017585 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017586 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017587 hddLog(VOS_TRACE_LEVEL_ERROR,
17588 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017589 __func__, retry_value);
17590 return -EIO;
17591 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017592 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017593 __func__, retry_value);
17594 }
17595 else if (changed & WIPHY_PARAM_RETRY_SHORT)
17596 {
17597 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
17598 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017599 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017601 hddLog(VOS_TRACE_LEVEL_ERROR,
17602 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017603 __func__, retry_value);
17604 return -EIO;
17605 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017606 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070017607 __func__, retry_value);
17608 }
17609 }
17610
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017611 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017612 return 0;
17613}
17614
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017615static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
17616 u32 changed)
17617{
17618 int ret;
17619
17620 vos_ssr_protect(__func__);
17621 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
17622 vos_ssr_unprotect(__func__);
17623
17624 return ret;
17625}
17626
Jeff Johnson295189b2012-06-20 16:38:30 -070017627/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017628 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017629 * This function is used to set the txpower
17630 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017631static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017632#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17633 struct wireless_dev *wdev,
17634#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017635#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017636 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017637#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017638 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070017639#endif
17640 int dbm)
17641{
17642 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017643 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070017644 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
17645 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017646 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017647
17648 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017649
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017650 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17651 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
17652 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017653 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017654 if (0 != status)
17655 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017656 return status;
17657 }
17658
17659 hHal = pHddCtx->hHal;
17660
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017661 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
17662 dbm, ccmCfgSetCallback,
17663 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070017664 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017665 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070017666 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
17667 return -EIO;
17668 }
17669
17670 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
17671 dbm);
17672
17673 switch(type)
17674 {
17675 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
17676 /* Fall through */
17677 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
17678 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
17679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
17681 __func__);
17682 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070017683 }
17684 break;
17685 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017686 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070017687 __func__);
17688 return -EOPNOTSUPP;
17689 break;
17690 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017691 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
17692 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070017693 return -EIO;
17694 }
17695
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017696 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017697 return 0;
17698}
17699
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053017700static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
17701#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17702 struct wireless_dev *wdev,
17703#endif
17704#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17705 enum tx_power_setting type,
17706#else
17707 enum nl80211_tx_power_setting type,
17708#endif
17709 int dbm)
17710{
17711 int ret;
17712 vos_ssr_protect(__func__);
17713 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
17714#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17715 wdev,
17716#endif
17717#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
17718 type,
17719#else
17720 type,
17721#endif
17722 dbm);
17723 vos_ssr_unprotect(__func__);
17724
17725 return ret;
17726}
17727
Jeff Johnson295189b2012-06-20 16:38:30 -070017728/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017729 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070017730 * This function is used to read the txpower
17731 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017732static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070017733#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17734 struct wireless_dev *wdev,
17735#endif
17736 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070017737{
17738
17739 hdd_adapter_t *pAdapter;
17740 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017741 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017742
Jeff Johnsone7245742012-09-05 17:12:55 -070017743 ENTER();
17744
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017745 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017746 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017747 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017748 *dbm = 0;
17749 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017750 }
17751
Jeff Johnson295189b2012-06-20 16:38:30 -070017752 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
17753 if (NULL == pAdapter)
17754 {
17755 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
17756 return -ENOENT;
17757 }
17758
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017759 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17760 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
17761 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070017762 wlan_hdd_get_classAstats(pAdapter);
17763 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
17764
Jeff Johnsone7245742012-09-05 17:12:55 -070017765 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070017766 return 0;
17767}
17768
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017769static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
17770#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17771 struct wireless_dev *wdev,
17772#endif
17773 int *dbm)
17774{
17775 int ret;
17776
17777 vos_ssr_protect(__func__);
17778 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
17779#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
17780 wdev,
17781#endif
17782 dbm);
17783 vos_ssr_unprotect(__func__);
17784
17785 return ret;
17786}
17787
Dustin Brown8c1d4092017-07-28 18:08:01 +053017788/*
17789 * wlan_hdd_fill_summary_stats() - populate station_info summary stats
17790 * @stats: summary stats to use as a source
17791 * @info: kernel station_info struct to use as a destination
17792 *
17793 * Return: None
17794 */
17795static void wlan_hdd_fill_summary_stats(tCsrSummaryStatsInfo *stats,
17796 struct station_info *info)
17797{
17798 int i;
17799
17800 info->rx_packets = stats->rx_frm_cnt;
17801 info->tx_packets = 0;
17802 info->tx_retries = 0;
17803 info->tx_failed = 0;
17804
17805 for (i = 0; i < 4; ++i) {
17806 info->tx_packets += stats->tx_frm_cnt[i];
17807 info->tx_retries += stats->multiple_retry_cnt[i];
17808 info->tx_failed += stats->fail_cnt[i];
17809 }
17810
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017811#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17812 !defined(WITH_BACKPORTS)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017813 info->filled |= STATION_INFO_TX_PACKETS |
17814 STATION_INFO_TX_RETRIES |
17815 STATION_INFO_TX_FAILED |
17816 STATION_INFO_RX_PACKETS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017817#else
17818 info->filled |= BIT(NL80211_STA_INFO_TX_PACKETS) |
17819 BIT(NL80211_STA_INFO_TX_RETRIES) |
17820 BIT(NL80211_STA_INFO_TX_FAILED) |
17821 BIT(NL80211_STA_INFO_RX_PACKETS);
17822#endif
Dustin Brown8c1d4092017-07-28 18:08:01 +053017823}
17824
17825/**
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017826 * wlan_hdd_sap_get_sta_rssi() - get RSSI of the SAP client
17827 * @adapter: sap adapter pointer
17828 * @staid: station id of the client
17829 * @rssi: rssi value to fill
17830 *
17831 * Return: None
17832 */
Hanumanth Reddy Pothula57323632017-12-06 17:55:09 +053017833void
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017834wlan_hdd_sap_get_sta_rssi(hdd_adapter_t *adapter, uint8_t staid, s8 *rssi)
17835{
17836 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
17837
17838 WLANTL_GetSAPStaRSSi(pVosContext, staid, rssi);
17839}
17840
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017841#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
17842 !defined(WITH_BACKPORTS)
17843static inline void wlan_hdd_fill_station_info_signal(struct station_info
17844 *sinfo)
17845{
17846 sinfo->filled |= STATION_INFO_SIGNAL;
17847}
17848#else
17849static inline void wlan_hdd_fill_station_info_signal(struct station_info
17850 *sinfo)
17851{
17852 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
17853}
17854#endif
17855
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017856/**
Dustin Brown8c1d4092017-07-28 18:08:01 +053017857 * wlan_hdd_get_sap_stats() - get aggregate SAP stats
17858 * @adapter: sap adapter to get stats for
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017859 * @mac: mac address of the station
Dustin Brown8c1d4092017-07-28 18:08:01 +053017860 * @info: kernel station_info struct to populate
17861 *
17862 * Fetch the vdev-level aggregate stats for the given SAP adapter. This is to
17863 * support "station dump" and "station get" for SAP vdevs, even though they
17864 * aren't technically stations.
17865 *
17866 * Return: errno
17867 */
17868static int
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017869wlan_hdd_get_sap_stats(hdd_adapter_t *adapter,
17870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17871 const u8* mac,
17872#else
17873 u8* mac,
17874#endif
17875 struct station_info *info)
Dustin Brown8c1d4092017-07-28 18:08:01 +053017876{
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017877 v_MACADDR_t *peerMacAddr;
17878 uint8_t staid;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017879 VOS_STATUS status;
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017880 bool bc_mac_addr;
Dustin Brown8c1d4092017-07-28 18:08:01 +053017881
17882 status = wlan_hdd_get_station_stats(adapter);
17883 if (!VOS_IS_STATUS_SUCCESS(status)) {
17884 hddLog(VOS_TRACE_LEVEL_ERROR,
17885 "Failed to get SAP stats; status:%d", status);
17886 return 0;
17887 }
17888
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017889 peerMacAddr = (v_MACADDR_t *)mac;
17890 bc_mac_addr = vos_is_macaddr_broadcast(peerMacAddr);
17891 staid = hdd_sta_id_find_from_mac_addr(adapter, peerMacAddr);
17892 hddLog(VOS_TRACE_LEVEL_INFO, "Get SAP stats for sta id:%d", staid);
17893
17894 if (staid < WLAN_MAX_STA_COUNT && !bc_mac_addr) {
17895 wlan_hdd_sap_get_sta_rssi(adapter, staid, &info->signal);
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017896 wlan_hdd_fill_station_info_signal(info);
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017897 }
17898
Dustin Brown8c1d4092017-07-28 18:08:01 +053017899 wlan_hdd_fill_summary_stats(&adapter->hdd_stats.summary_stat, info);
17900
17901 return 0;
17902}
17903
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017904static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053017905#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17906 const u8* mac,
17907#else
17908 u8* mac,
17909#endif
17910 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070017911{
17912 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
17913 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17914 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053017915 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017916
17917 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
17918 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070017919
17920 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
17921 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
17922 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
17923 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
17924 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
17925 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
17926 tANI_U16 maxRate = 0;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017927 int8_t snr = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070017928 tANI_U16 myRate;
17929 tANI_U16 currentRate = 0;
17930 tANI_U8 maxSpeedMCS = 0;
17931 tANI_U8 maxMCSIdx = 0;
17932 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053017933 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070017934 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017935 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070017936
Leo Chang6f8870f2013-03-26 18:11:36 -070017937#ifdef WLAN_FEATURE_11AC
17938 tANI_U32 vht_mcs_map;
17939 eDataRate11ACMaxMcs vhtMaxMcs;
17940#endif /* WLAN_FEATURE_11AC */
17941
Jeff Johnsone7245742012-09-05 17:12:55 -070017942 ENTER();
17943
Dustin Brown8c1d4092017-07-28 18:08:01 +053017944 status = wlan_hdd_validate_context(pHddCtx);
17945 if (0 != status)
17946 {
17947 return status;
17948 }
17949
17950 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Sravan Kumar Kairame0e78442017-09-18 18:00:53 +053017951 return wlan_hdd_get_sap_stats(pAdapter, mac, sinfo);
Dustin Brown8c1d4092017-07-28 18:08:01 +053017952
Jeff Johnson295189b2012-06-20 16:38:30 -070017953 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17954 (0 == ssidlen))
17955 {
17956 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
17957 " Invalid ssidlen, %d", __func__, ssidlen);
17958 /*To keep GUI happy*/
17959 return 0;
17960 }
17961
Mukul Sharma811205f2014-07-09 21:07:30 +053017962 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17963 {
17964 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17965 "%s: Roaming in progress, so unable to proceed this request", __func__);
Sachin Ahuja81ab1812016-08-19 21:35:58 +053017966 /* return a cached value */
17967 sinfo->signal = pAdapter->rssi;
Mukul Sharma811205f2014-07-09 21:07:30 +053017968 return 0;
17969 }
17970
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053017971 wlan_hdd_get_station_stats(pAdapter);
17972 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070017973
Kiet Lam3b17fc82013-09-27 05:24:08 +053017974 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017975 wlan_hdd_get_snr(pAdapter, &snr);
17976 pHddStaCtx->conn_info.signal = sinfo->signal;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017977 pHddStaCtx->cache_conn_info.signal = sinfo->signal;
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053017978 pHddStaCtx->conn_info.noise = pHddStaCtx->conn_info.signal - snr;
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053017979 pHddStaCtx->cache_conn_info.noise = pHddStaCtx->conn_info.noise;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053017980 wlan_hdd_fill_station_info_signal(sinfo);
Kiet Lam3b17fc82013-09-27 05:24:08 +053017981
c_hpothu09f19542014-05-30 21:53:31 +053017982 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053017983 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
17984 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053017985 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053017986 {
17987 rate_flags = pAdapter->maxRateFlags;
17988 }
c_hpothu44ff4e02014-05-08 00:13:57 +053017989
Jeff Johnson295189b2012-06-20 16:38:30 -070017990 //convert to the UI units of 100kbps
17991 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
17992
17993#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070017994 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 -070017995 sinfo->signal,
17996 pCfg->reportMaxLinkSpeed,
17997 myRate,
17998 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070017999 (int) pCfg->linkSpeedRssiMid,
18000 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070018001 (int) rate_flags,
18002 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070018003#endif //LINKSPEED_DEBUG_ENABLED
18004
18005 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
18006 {
18007 // we do not want to necessarily report the current speed
18008 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
18009 {
18010 // report the max possible speed
18011 rssidx = 0;
18012 }
18013 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
18014 {
18015 // report the max possible speed with RSSI scaling
18016 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
18017 {
18018 // report the max possible speed
18019 rssidx = 0;
18020 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018021 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070018022 {
18023 // report middle speed
18024 rssidx = 1;
18025 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018026 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
18027 {
18028 // report middle speed
18029 rssidx = 2;
18030 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018031 else
18032 {
18033 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070018034 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070018035 }
18036 }
18037 else
18038 {
18039 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
18040 hddLog(VOS_TRACE_LEVEL_ERROR,
18041 "%s: Invalid value for reportMaxLinkSpeed: %u",
18042 __func__, pCfg->reportMaxLinkSpeed);
18043 rssidx = 0;
18044 }
18045
18046 maxRate = 0;
18047
18048 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018049 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
18050 OperationalRates, &ORLeng))
18051 {
18052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18053 /*To keep GUI happy*/
18054 return 0;
18055 }
18056
Jeff Johnson295189b2012-06-20 16:38:30 -070018057 for (i = 0; i < ORLeng; i++)
18058 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018059 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018060 {
18061 /* Validate Rate Set */
18062 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
18063 {
18064 currentRate = supported_data_rate[j].supported_rate[rssidx];
18065 break;
18066 }
18067 }
18068 /* Update MAX rate */
18069 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18070 }
18071
18072 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018073 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
18074 ExtendedRates, &ERLeng))
18075 {
18076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18077 /*To keep GUI happy*/
18078 return 0;
18079 }
18080
Jeff Johnson295189b2012-06-20 16:38:30 -070018081 for (i = 0; i < ERLeng; i++)
18082 {
Jeff Johnsone7245742012-09-05 17:12:55 -070018083 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070018084 {
18085 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
18086 {
18087 currentRate = supported_data_rate[j].supported_rate[rssidx];
18088 break;
18089 }
18090 }
18091 /* Update MAX rate */
18092 maxRate = (currentRate > maxRate)?currentRate:maxRate;
18093 }
c_hpothu79aab322014-07-14 21:11:01 +053018094
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018095 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053018096 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053018097 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053018098 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070018099 {
c_hpothu79aab322014-07-14 21:11:01 +053018100 if (rate_flags & eHAL_TX_RATE_VHT80)
18101 mode = 2;
18102 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
18103 mode = 1;
18104 else
18105 mode = 0;
18106
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053018107 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
18108 MCSRates, &MCSLeng))
18109 {
18110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
18111 /*To keep GUI happy*/
18112 return 0;
18113 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018114 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070018115#ifdef WLAN_FEATURE_11AC
18116 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018117 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070018118 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018119 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018120 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070018121 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070018122 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018123 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018124 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018125 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070018126 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018127 maxMCSIdx = 7;
18128 }
18129 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
18130 {
18131 maxMCSIdx = 8;
18132 }
18133 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
18134 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018135 //VHT20 is supporting 0~8
18136 if (rate_flags & eHAL_TX_RATE_VHT20)
18137 maxMCSIdx = 8;
18138 else
18139 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070018140 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018141
c_hpothu79aab322014-07-14 21:11:01 +053018142 if (0 != rssidx)/*check for scaled */
18143 {
18144 //get middle rate MCS index if rssi=1/2
18145 for (i=0; i <= maxMCSIdx; i++)
18146 {
18147 if (sinfo->signal <= rssiMcsTbl[mode][i])
18148 {
18149 maxMCSIdx = i;
18150 break;
18151 }
18152 }
18153 }
18154
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018155 if (rate_flags & eHAL_TX_RATE_VHT80)
18156 {
18157 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
18158 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
18159 }
18160 else if (rate_flags & eHAL_TX_RATE_VHT40)
18161 {
18162 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
18163 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
18164 }
18165 else if (rate_flags & eHAL_TX_RATE_VHT20)
18166 {
18167 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
18168 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
18169 }
18170
Leo Chang6f8870f2013-03-26 18:11:36 -070018171 maxSpeedMCS = 1;
18172 if (currentRate > maxRate)
18173 {
18174 maxRate = currentRate;
18175 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018176
Leo Chang6f8870f2013-03-26 18:11:36 -070018177 }
18178 else
18179#endif /* WLAN_FEATURE_11AC */
18180 {
18181 if (rate_flags & eHAL_TX_RATE_HT40)
18182 {
18183 rateFlag |= 1;
18184 }
18185 if (rate_flags & eHAL_TX_RATE_SGI)
18186 {
18187 rateFlag |= 2;
18188 }
18189
Girish Gowli01abcee2014-07-31 20:18:55 +053018190 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053018191 if (rssidx == 1 || rssidx == 2)
18192 {
18193 //get middle rate MCS index if rssi=1/2
18194 for (i=0; i <= 7; i++)
18195 {
18196 if (sinfo->signal <= rssiMcsTbl[mode][i])
18197 {
18198 temp = i+1;
18199 break;
18200 }
18201 }
18202 }
c_hpothu79aab322014-07-14 21:11:01 +053018203
18204 for (i = 0; i < MCSLeng; i++)
18205 {
Leo Chang6f8870f2013-03-26 18:11:36 -070018206 for (j = 0; j < temp; j++)
18207 {
18208 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
18209 {
18210 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018211 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018212 break;
18213 }
18214 }
18215 if ((j < temp) && (currentRate > maxRate))
18216 {
18217 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070018218 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018219 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053018220 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070018221 }
18222 }
18223
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018224 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
18225 {
18226 maxRate = myRate;
18227 maxSpeedMCS = 1;
18228 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18229 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018230 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053018231 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070018232 {
18233 maxRate = myRate;
18234 if (rate_flags & eHAL_TX_RATE_LEGACY)
18235 {
18236 maxSpeedMCS = 0;
18237 }
18238 else
18239 {
18240 maxSpeedMCS = 1;
18241 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
18242 }
18243 }
18244
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018245 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070018246 {
18247 sinfo->txrate.legacy = maxRate;
18248#ifdef LINKSPEED_DEBUG_ENABLED
18249 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
18250#endif //LINKSPEED_DEBUG_ENABLED
18251 }
18252 else
18253 {
18254 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070018255#ifdef WLAN_FEATURE_11AC
18256 sinfo->txrate.nss = 1;
18257 if (rate_flags & eHAL_TX_RATE_VHT80)
18258 {
18259 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018260#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18261 defined(WITH_BACKPORTS)
18262 sinfo->txrate.bw = RATE_INFO_BW_80;
18263#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018264 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018265#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018266 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018267 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070018268 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018269 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018270#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18271 defined(WITH_BACKPORTS)
18272 sinfo->txrate.bw = RATE_INFO_BW_40;
18273#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018274 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018275#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018276 }
18277 else if (rate_flags & eHAL_TX_RATE_VHT20)
18278 {
18279 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18280 }
18281#endif /* WLAN_FEATURE_11AC */
18282 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
18283 {
18284 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18285 if (rate_flags & eHAL_TX_RATE_HT40)
18286 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018287#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18288 defined(WITH_BACKPORTS)
18289 sinfo->txrate.bw = RATE_INFO_BW_40;
18290#else
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018291 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018292#endif
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018293 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018294 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018295 if (rate_flags & eHAL_TX_RATE_SGI)
18296 {
18297 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18298 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053018299
Jeff Johnson295189b2012-06-20 16:38:30 -070018300#ifdef LINKSPEED_DEBUG_ENABLED
18301 pr_info("Reporting MCS rate %d flags %x\n",
18302 sinfo->txrate.mcs,
18303 sinfo->txrate.flags );
18304#endif //LINKSPEED_DEBUG_ENABLED
18305 }
18306 }
18307 else
18308 {
18309 // report current rate instead of max rate
18310
18311 if (rate_flags & eHAL_TX_RATE_LEGACY)
18312 {
18313 //provide to the UI in units of 100kbps
18314 sinfo->txrate.legacy = myRate;
18315#ifdef LINKSPEED_DEBUG_ENABLED
18316 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
18317#endif //LINKSPEED_DEBUG_ENABLED
18318 }
18319 else
18320 {
18321 //must be MCS
18322 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070018323#ifdef WLAN_FEATURE_11AC
18324 sinfo->txrate.nss = 1;
18325 if (rate_flags & eHAL_TX_RATE_VHT80)
18326 {
18327 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
18328 }
18329 else
18330#endif /* WLAN_FEATURE_11AC */
18331 {
18332 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
18333 }
Jeff Johnson295189b2012-06-20 16:38:30 -070018334 if (rate_flags & eHAL_TX_RATE_SGI)
18335 {
18336 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
18337 }
18338 if (rate_flags & eHAL_TX_RATE_HT40)
18339 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018340#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18341 defined(WITH_BACKPORTS)
18342 sinfo->txrate.bw = RATE_INFO_BW_40;
18343#else
Jeff Johnson295189b2012-06-20 16:38:30 -070018344 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018345#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018346 }
Leo Chang6f8870f2013-03-26 18:11:36 -070018347#ifdef WLAN_FEATURE_11AC
18348 else if (rate_flags & eHAL_TX_RATE_VHT80)
18349 {
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018350#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) || \
18351 defined(WITH_BACKPORTS)
18352 sinfo->txrate.bw = RATE_INFO_BW_80;
18353#else
Leo Chang6f8870f2013-03-26 18:11:36 -070018354 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018355#endif
Leo Chang6f8870f2013-03-26 18:11:36 -070018356 }
18357#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070018358#ifdef LINKSPEED_DEBUG_ENABLED
18359 pr_info("Reporting actual MCS rate %d flags %x\n",
18360 sinfo->txrate.mcs,
18361 sinfo->txrate.flags );
18362#endif //LINKSPEED_DEBUG_ENABLED
18363 }
18364 }
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018365
18366#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18367 !defined(WITH_BACKPORTS)
Jeff Johnson295189b2012-06-20 16:38:30 -070018368 sinfo->filled |= STATION_INFO_TX_BITRATE;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018369#else
18370 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
18371#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018372
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018373 sinfo->tx_packets =
18374 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
18375 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
18376 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
18377 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
18378
18379 sinfo->tx_retries =
18380 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
18381 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
18382 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
18383 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
18384
18385 sinfo->tx_failed =
18386 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
18387 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
18388 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
18389 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
18390
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018391#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)) && \
18392 !defined(WITH_BACKPORTS)
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018393 sinfo->filled |=
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018394 STATION_INFO_RX_PACKETS |
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018395 STATION_INFO_TX_PACKETS |
18396 STATION_INFO_TX_RETRIES |
18397 STATION_INFO_TX_FAILED;
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018398#else
18399 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
18400 BIT(NL80211_STA_INFO_TX_PACKETS) |
18401 BIT(NL80211_STA_INFO_TX_RETRIES) |
18402 BIT(NL80211_STA_INFO_TX_FAILED);
18403#endif
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018404
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018405 sinfo->rx_packets = pAdapter->hdd_stats.summary_stat.rx_frm_cnt;
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018406
Anurag Chouhanbdb1fd62017-07-19 16:32:33 +053018407 vos_mem_copy(&pHddStaCtx->conn_info.txrate,
18408 &sinfo->txrate, sizeof(sinfo->txrate));
Ashish Kumar Dhanotiyabb8d2302018-02-22 00:37:26 +053018409 vos_mem_copy(&pHddStaCtx->cache_conn_info.txrate,
18410 &sinfo->txrate, sizeof(sinfo->txrate));
18411
Edhar, Mahesh Kumar3cc9f232015-12-29 14:41:01 +053018412 if (rate_flags & eHAL_TX_RATE_LEGACY)
18413 hddLog(LOG1, FL("Reporting RSSI:%d legacy rate %d pkt cnt tx %d rx %d"),
18414 sinfo->signal, sinfo->txrate.legacy, sinfo->tx_packets,
18415 sinfo->rx_packets);
18416 else
18417 hddLog(LOG1,
18418 FL("Reporting RSSI:%d MCS rate %d flags 0x%x pkt cnt tx %d rx %d"),
18419 sinfo->signal, sinfo->txrate.mcs, sinfo->txrate.flags,
18420 sinfo->tx_packets, sinfo->rx_packets);
18421
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018422 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18423 TRACE_CODE_HDD_CFG80211_GET_STA,
18424 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070018425 EXIT();
18426 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070018427}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018428#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18429static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18430 const u8* mac, struct station_info *sinfo)
18431#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018432static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
18433 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018434#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018435{
18436 int ret;
18437
18438 vos_ssr_protect(__func__);
18439 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
18440 vos_ssr_unprotect(__func__);
18441
18442 return ret;
18443}
18444
18445static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070018446 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070018447{
18448 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018449 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070018450 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018451 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018452
Jeff Johnsone7245742012-09-05 17:12:55 -070018453 ENTER();
18454
Jeff Johnson295189b2012-06-20 16:38:30 -070018455 if (NULL == pAdapter)
18456 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080018457 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018458 return -ENODEV;
18459 }
18460
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018461 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18462 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
18463 pAdapter->sessionId, timeout));
18464
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018465 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018466 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018467 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018468 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018469 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018470 }
18471
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018472 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
18473 (TRUE == pHddCtx->hdd_wlan_suspended) &&
18474 (pHddCtx->cfg_ini->fhostArpOffload) &&
18475 (eConnectionState_Associated ==
18476 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
18477 {
Amar Singhald53568e2013-09-26 11:03:45 -070018478
18479 hddLog(VOS_TRACE_LEVEL_INFO,
18480 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053018481 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018482 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18483 {
18484 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080018485 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053018486 __func__, vos_status);
18487 }
18488 }
18489
Jeff Johnson295189b2012-06-20 16:38:30 -070018490 /**The get power cmd from the supplicant gets updated by the nl only
18491 *on successful execution of the function call
18492 *we are oppositely mapped w.r.t mode in the driver
18493 **/
18494 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
18495
18496 if (VOS_STATUS_E_FAILURE == vos_status)
18497 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18499 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018500 return -EINVAL;
18501 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018502 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070018503 return 0;
18504}
18505
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018506static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
18507 struct net_device *dev, bool mode, int timeout)
18508{
18509 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018510
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018511 vos_ssr_protect(__func__);
18512 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
18513 vos_ssr_unprotect(__func__);
18514
18515 return ret;
18516}
Sushant Kaushik084f6592015-09-10 13:11:56 +053018517
Jeff Johnson295189b2012-06-20 16:38:30 -070018518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018519static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
18520 struct net_device *netdev,
18521 u8 key_index)
18522{
18523 ENTER();
18524 return 0;
18525}
18526
Jeff Johnson295189b2012-06-20 16:38:30 -070018527static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018528 struct net_device *netdev,
18529 u8 key_index)
18530{
18531 int ret;
18532 vos_ssr_protect(__func__);
18533 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
18534 vos_ssr_unprotect(__func__);
18535 return ret;
18536}
18537#endif //LINUX_VERSION_CODE
18538
18539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18540static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18541 struct net_device *dev,
18542 struct ieee80211_txq_params *params)
18543{
18544 ENTER();
18545 return 0;
18546}
18547#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18548static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
18549 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018550{
Jeff Johnsone7245742012-09-05 17:12:55 -070018551 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070018552 return 0;
18553}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018554#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070018555
18556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
18557static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018558 struct net_device *dev,
18559 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070018560{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018561 int ret;
18562
18563 vos_ssr_protect(__func__);
18564 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
18565 vos_ssr_unprotect(__func__);
18566 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018567}
18568#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18569static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
18570 struct ieee80211_txq_params *params)
18571{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018572 int ret;
18573
18574 vos_ssr_protect(__func__);
18575 ret = __wlan_hdd_set_txq_params(wiphy, params);
18576 vos_ssr_unprotect(__func__);
18577 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070018578}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018579#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018580
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018581static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018582 struct net_device *dev,
18583 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070018584{
18585 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018586 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018587 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018588 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018589 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018590 v_CONTEXT_t pVosContext = NULL;
18591 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018592
Jeff Johnsone7245742012-09-05 17:12:55 -070018593 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018594
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018595 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070018596 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018597 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070018598 return -EINVAL;
18599 }
18600
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018601 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18602 TRACE_CODE_HDD_CFG80211_DEL_STA,
18603 pAdapter->sessionId, pAdapter->device_mode));
18604
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018605 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18606 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018607 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018608 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018609 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018610 }
18611
Jeff Johnson295189b2012-06-20 16:38:30 -070018612 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018613 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070018614 )
18615 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018616 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
18617 pSapCtx = VOS_GET_SAP_CB(pVosContext);
18618 if(pSapCtx == NULL){
18619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18620 FL("psapCtx is NULL"));
18621 return -ENOENT;
18622 }
Agrawal Ashish306b75f2017-01-11 19:16:25 +053018623 if (pHddCtx->cfg_ini->enable_sap_auth_offload)
18624 {
18625 VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_INFO,
18626 "Change reason code to eSIR_MAC_DISASSOC_LEAVING_BSS_REASON in sap auth offload");
18627 pDelStaParams->reason_code = eSIR_MAC_DISASSOC_LEAVING_BSS_REASON;
18628 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018629 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070018630 {
18631 v_U16_t i;
18632 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
18633 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018634 if ((pSapCtx->aStaInfo[i].isUsed) &&
18635 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070018636 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018637 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018638 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018639 ETHER_ADDR_LEN);
18640
Jeff Johnson295189b2012-06-20 16:38:30 -070018641 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018642 "%s: Delete STA with MAC::"
18643 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018644 __func__,
18645 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
18646 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070018647 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018648 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070018649 }
18650 }
18651 }
18652 else
18653 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018654
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018655 vos_status = hdd_softap_GetStaId(pAdapter,
18656 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018657 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18658 {
18659 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018660 "%s: Skip this DEL STA as this is not used::"
18661 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018662 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018663 return -ENOENT;
18664 }
18665
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018666 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018667 {
18668 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080018669 "%s: Skip this DEL STA as deauth is in progress::"
18670 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018671 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018672 return -ENOENT;
18673 }
18674
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018675 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018676
Jeff Johnson295189b2012-06-20 16:38:30 -070018677 hddLog(VOS_TRACE_LEVEL_INFO,
18678 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018679 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070018680 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018681 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018682
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018683 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018684 if (!VOS_IS_STATUS_SUCCESS(vos_status))
18685 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053018686 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018687 hddLog(VOS_TRACE_LEVEL_INFO,
18688 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080018689 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018690 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018691 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080018692 return -ENOENT;
18693 }
18694
Jeff Johnson295189b2012-06-20 16:38:30 -070018695 }
18696 }
18697
18698 EXIT();
18699
18700 return 0;
18701}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018702
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018703#ifdef USE_CFG80211_DEL_STA_V2
Kapil Gupta137ef892016-12-13 19:38:00 +053018704int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018705 struct net_device *dev,
18706 struct station_del_parameters *param)
18707#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
Kapil Gupta137ef892016-12-13 19:38:00 +053018709int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018710 struct net_device *dev, const u8 *mac)
18711#else
Kapil Gupta137ef892016-12-13 19:38:00 +053018712int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018713 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018714#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018715#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018716{
18717 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018718 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070018719
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018720 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018721
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053018722#ifdef USE_CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018723 if (NULL == param) {
18724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018725 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018726 return -EINVAL;
18727 }
18728
18729 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
18730 param->subtype, &delStaParams);
18731
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018732#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053018733 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018734 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053018735#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053018736 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
18737
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018738 vos_ssr_unprotect(__func__);
18739
18740 return ret;
18741}
18742
18743static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018744 struct net_device *dev,
18745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18746 const u8 *mac,
18747#else
18748 u8 *mac,
18749#endif
18750 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018751{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018752 hdd_adapter_t *pAdapter;
18753 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018754 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018755#ifdef FEATURE_WLAN_TDLS
18756 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018757
Hoonki Lee11f7dda2013-02-14 16:55:44 -080018758 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018759
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018760 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18761 if (NULL == pAdapter)
18762 {
18763 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18764 "%s: Adapter is NULL",__func__);
18765 return -EINVAL;
18766 }
18767 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18768 status = wlan_hdd_validate_context(pHddCtx);
18769 if (0 != status)
18770 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018771 return status;
18772 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018773
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018774 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18775 TRACE_CODE_HDD_CFG80211_ADD_STA,
18776 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018777 mask = params->sta_flags_mask;
18778
18779 set = params->sta_flags_set;
18780
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053018781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018782 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
18783 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018784
18785 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
18786 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080018787 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018788 }
18789 }
18790#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018791 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080018792 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070018793}
18794
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018795#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18796static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18797 struct net_device *dev, const u8 *mac,
18798 struct station_parameters *params)
18799#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018800static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
18801 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053018802#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018803{
18804 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018805
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018806 vos_ssr_protect(__func__);
18807 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
18808 vos_ssr_unprotect(__func__);
18809
18810 return ret;
18811}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018812#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070018813
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018814static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070018815 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018816{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018817 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18818 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018819 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018820 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018821 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018822 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070018823
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018824 ENTER();
18825
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018826 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018827 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018828 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018829 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018830 return -EINVAL;
18831 }
18832
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018833 if (!pmksa) {
18834 hddLog(LOGE, FL("pmksa is NULL"));
18835 return -EINVAL;
18836 }
18837
18838 if (!pmksa->bssid || !pmksa->pmkid) {
Jeff Johnsonc135a9a2017-09-19 08:37:24 -070018839 hddLog(LOGE, FL("pmksa->bssid(%pK) or pmksa->pmkid(%pK) is NULL"),
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018840 pmksa->bssid, pmksa->pmkid);
18841 return -EINVAL;
18842 }
18843
18844 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
18845 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18846
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018847 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18848 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018849 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018850 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018851 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018852 }
18853
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018854 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018855 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18856
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018857 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
18858 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018859
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018860 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018861 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018862 &pmk_id, 1, FALSE);
18863
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018864 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18865 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
18866 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018867
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018868 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018869 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018870}
18871
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018872static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
18873 struct cfg80211_pmksa *pmksa)
18874{
18875 int ret;
18876
18877 vos_ssr_protect(__func__);
18878 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
18879 vos_ssr_unprotect(__func__);
18880
18881 return ret;
18882}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018883
Wilson Yang6507c4e2013-10-01 20:11:19 -070018884
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018885static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070018886 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018887{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018888 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18889 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018890 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018891 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018892
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018893 ENTER();
18894
Wilson Yang6507c4e2013-10-01 20:11:19 -070018895 /* Validate pAdapter */
18896 if (NULL == pAdapter)
18897 {
18898 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
18899 return -EINVAL;
18900 }
18901
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018902 if (!pmksa) {
18903 hddLog(LOGE, FL("pmksa is NULL"));
18904 return -EINVAL;
18905 }
18906
18907 if (!pmksa->bssid) {
18908 hddLog(LOGE, FL("pmksa->bssid is NULL"));
18909 return -EINVAL;
18910 }
18911
Kiet Lam98c46a12014-10-31 15:34:57 -070018912 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
18913 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
18914
Wilson Yang6507c4e2013-10-01 20:11:19 -070018915 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18916 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018917 if (0 != status)
18918 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018919 return status;
18920 }
18921
18922 /*Retrieve halHandle*/
18923 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18924
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018925 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18926 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
18927 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018928 /* Delete the PMKID CSR cache */
18929 if (eHAL_STATUS_SUCCESS !=
18930 sme_RoamDelPMKIDfromCache(halHandle,
18931 pAdapter->sessionId, pmksa->bssid, FALSE)) {
18932 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
18933 MAC_ADDR_ARRAY(pmksa->bssid));
18934 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018935 }
18936
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018937 EXIT();
18938 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018939}
18940
Wilson Yang6507c4e2013-10-01 20:11:19 -070018941
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018942static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
18943 struct cfg80211_pmksa *pmksa)
18944{
18945 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018946
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018947 vos_ssr_protect(__func__);
18948 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
18949 vos_ssr_unprotect(__func__);
18950
18951 return ret;
18952
18953}
18954
18955static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018956{
Wilson Yang6507c4e2013-10-01 20:11:19 -070018957 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18958 tHalHandle halHandle;
18959 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080018960 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018961
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018962 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070018963
18964 /* Validate pAdapter */
18965 if (NULL == pAdapter)
18966 {
18967 hddLog(VOS_TRACE_LEVEL_ERROR,
18968 "%s: Invalid Adapter" ,__func__);
18969 return -EINVAL;
18970 }
18971
18972 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18973 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070018974 if (0 != status)
18975 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070018976 return status;
18977 }
18978
18979 /*Retrieve halHandle*/
18980 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18981
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053018982 /* Flush the PMKID cache in CSR */
18983 if (eHAL_STATUS_SUCCESS !=
18984 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
18985 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
18986 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070018987 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018988 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080018989 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018990}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053018991
18992static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
18993{
18994 int ret;
18995
18996 vos_ssr_protect(__func__);
18997 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
18998 vos_ssr_unprotect(__func__);
18999
19000 return ret;
19001}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019002#endif
19003
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019004#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019005static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19006 struct net_device *dev,
19007 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019008{
19009 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19010 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019011 hdd_context_t *pHddCtx;
19012 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019014 ENTER();
19015
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019016 if (NULL == pAdapter)
19017 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019019 return -ENODEV;
19020 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019021 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19022 ret = wlan_hdd_validate_context(pHddCtx);
19023 if (0 != ret)
19024 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053019025 return ret;
19026 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019027 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019028 if (NULL == pHddStaCtx)
19029 {
19030 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
19031 return -EINVAL;
19032 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019033
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19035 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
19036 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019037 // Added for debug on reception of Re-assoc Req.
19038 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
19039 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080019040 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019041 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080019042 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019043 }
19044
19045#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080019046 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019047 ftie->ie_len);
19048#endif
19049
19050 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053019051 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
19052 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019053 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019054
19055 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019056 return 0;
19057}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053019058
19059static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
19060 struct net_device *dev,
19061 struct cfg80211_update_ft_ies_params *ftie)
19062{
19063 int ret;
19064
19065 vos_ssr_protect(__func__);
19066 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
19067 vos_ssr_unprotect(__func__);
19068
19069 return ret;
19070}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019071#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019072
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019073#ifdef FEATURE_WLAN_SCAN_PNO
19074
19075void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
19076 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
19077{
19078 int ret;
19079 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
19080 hdd_context_t *pHddCtx;
19081
Nirav Shah80830bf2013-12-31 16:35:12 +053019082 ENTER();
19083
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019084 if (NULL == pAdapter)
19085 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053019086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019087 "%s: HDD adapter is Null", __func__);
19088 return ;
19089 }
19090
19091 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19092 if (NULL == pHddCtx)
19093 {
19094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19095 "%s: HDD context is Null!!!", __func__);
19096 return ;
19097 }
19098
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019099 spin_lock(&pHddCtx->schedScan_lock);
19100 if (TRUE == pHddCtx->isWiphySuspended)
19101 {
19102 pHddCtx->isSchedScanUpdatePending = TRUE;
19103 spin_unlock(&pHddCtx->schedScan_lock);
19104 hddLog(VOS_TRACE_LEVEL_INFO,
19105 "%s: Update cfg80211 scan database after it resume", __func__);
19106 return ;
19107 }
19108 spin_unlock(&pHddCtx->schedScan_lock);
19109
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019110 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
19111
19112 if (0 > ret)
19113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053019114 else
19115 {
19116 /* Acquire wakelock to handle the case where APP's tries to suspend
19117 * immediatly after the driver gets connect request(i.e after pno)
19118 * from supplicant, this result in app's is suspending and not able
19119 * to process the connect request to AP */
19120 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
19121 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019122 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19124 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019125}
19126
19127/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019128 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019129 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019130 */
19131static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
19132{
19133 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
19134 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019135 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019136 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19137 int status = 0;
Agrawal Ashishcff31692016-12-16 17:17:50 +053019138
19139 if (WLAN_HDD_INFRA_STATION != pAdapter->device_mode)
19140 {
19141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19142 "%s: PNO is allowed only in STA interface", __func__);
19143 return eHAL_STATUS_FAILURE;
19144 }
19145
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019146 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
19147
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019148 /* The current firmware design does not allow PNO during any
Agrawal Ashishcff31692016-12-16 17:17:50 +053019149 * active sessions. PNO is allowed only in case when sap session
19150 * is present and sapo auth offload feature enabled in firmare.
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019151 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019152 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
19153 {
19154 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019155 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019156
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019157 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
19158 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
19159 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
19160 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
Agrawal Ashishcff31692016-12-16 17:17:50 +053019161 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode &&
19162 !pHddCtx->cfg_ini->enable_sap_auth_offload)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053019163 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019164 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019165 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019166 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019167 }
19168 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
19169 pAdapterNode = pNext;
19170 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019171 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019172}
19173
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019174void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
19175{
19176 hdd_adapter_t *pAdapter = callbackContext;
19177 hdd_context_t *pHddCtx;
19178
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019179 ENTER();
19180
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019181 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
19182 {
19183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19184 FL("Invalid adapter or adapter has invalid magic"));
19185 return;
19186 }
19187
19188 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
19189 if (0 != wlan_hdd_validate_context(pHddCtx))
19190 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019191 return;
19192 }
19193
c_hpothub53c45d2014-08-18 16:53:14 +053019194 if (VOS_STATUS_SUCCESS != status)
19195 {
19196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019197 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053019198 pHddCtx->isPnoEnable = FALSE;
19199 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019200
19201 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
19202 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019203 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019204}
19205
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019206#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0)) || \
19207 defined (CFG80211_MULTI_SCAN_PLAN_BACKPORT)
19208/**
19209 * hdd_config_sched_scan_plan() - configures the sched scan plans
19210 * from the framework.
19211 * @pno_req: pointer to PNO scan request
19212 * @request: pointer to scan request from framework
19213 *
19214 * Return: None
19215 */
19216static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
19217 struct cfg80211_sched_scan_request *request,
19218 hdd_context_t *hdd_ctx)
19219{
19220 v_U32_t i = 0;
19221
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019222 pno_req->scanTimers.ucScanTimersCount = request->n_scan_plans;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019223 for (i = 0; i < request->n_scan_plans; i++)
19224 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019225 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
19226 request->scan_plans[i].iterations;
19227 pno_req->scanTimers.aTimerValues[i].uTimerValue =
19228 request->scan_plans[i].interval;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019229 }
19230}
19231#else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019232static void hdd_config_sched_scan_plan(tpSirPNOScanReq pno_req,
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019233 struct cfg80211_sched_scan_request *request,
19234 hdd_context_t *hdd_ctx)
19235{
19236 v_U32_t i, temp_int;
19237 /* Driver gets only one time interval which is hardcoded in
19238 * supplicant for 10000ms. Taking power consumption into account 6
19239 * timers will be used, Timervalue is increased exponentially
19240 * i.e 10,20,40, 80,160,320 secs. And number of scan cycle for each
19241 * timer is configurable through INI param gPNOScanTimerRepeatValue.
19242 * If it is set to 0 only one timer will be used and PNO scan cycle
19243 * will be repeated after each interval specified by supplicant
19244 * till PNO is disabled.
19245 */
19246 if (0 == hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue)
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019247 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019248 HDD_PNO_SCAN_TIMERS_SET_ONE;
19249 else
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019250 pno_req->scanTimers.ucScanTimersCount =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019251 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
19252
19253 temp_int = (request->interval)/1000;
19254 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19255 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
19256 temp_int, hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue);
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019257 for ( i = 0; i < pno_req->scanTimers.ucScanTimersCount; i++)
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019258 {
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019259 pno_req->scanTimers.aTimerValues[i].uTimerRepeat =
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019260 hdd_ctx->cfg_ini->configPNOScanTimerRepeatValue;
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019261 pno_req->scanTimers.aTimerValues[i].uTimerValue = temp_int;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019262 temp_int *= 2;
19263 }
19264 //Repeat last timer until pno disabled.
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019265 pno_req->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019266}
19267#endif
19268
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019269/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019270 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
19271 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019272 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019273static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019274 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19275{
19276 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019277 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019278 hdd_context_t *pHddCtx;
19279 tHalHandle hHal;
Anurag Chouhan343af7e2016-12-16 13:11:19 +053019280 v_U32_t i, indx, num_ch, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053019281 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
19282 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019283 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
19284 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019285 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019286 hdd_config_t *pConfig = NULL;
19287 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019288
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019289 ENTER();
19290
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019291 if (NULL == pAdapter)
19292 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019294 "%s: HDD adapter is Null", __func__);
19295 return -ENODEV;
19296 }
19297
19298 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019299 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019300
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019301 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019302 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019303 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019304 }
19305
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019306 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019307 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19308 if (NULL == hHal)
19309 {
19310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19311 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019312 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019313 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019314 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19315 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
19316 pAdapter->sessionId, pAdapter->device_mode));
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019317 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053019318 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053019319 {
19320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19321 "%s: aborting the existing scan is unsuccessfull", __func__);
19322 return -EBUSY;
19323 }
19324
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019325 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019326 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053019327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053019328 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053019329 return -EBUSY;
19330 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019331
c_hpothu37f21312014-04-09 21:49:54 +053019332 if (TRUE == pHddCtx->isPnoEnable)
19333 {
19334 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
19335 FL("already PNO is enabled"));
19336 return -EBUSY;
19337 }
c_hpothu225aa7c2014-10-22 17:45:13 +053019338
19339 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
19340 {
19341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19342 "%s: abort ROC failed ", __func__);
19343 return -EBUSY;
19344 }
19345
c_hpothu37f21312014-04-09 21:49:54 +053019346 pHddCtx->isPnoEnable = TRUE;
19347
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019348 pnoRequest.enable = 1; /*Enable PNO */
19349 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019350
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019351 if (( !pnoRequest.ucNetworksCount ) ||
19352 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019353 {
19354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019355 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019356 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019357 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019358 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019359 goto error;
19360 }
19361
19362 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
19363 {
19364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019365 "%s: Incorrect number of channels %d",
19366 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019367 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019368 goto error;
19369 }
19370
19371 /* Framework provides one set of channels(all)
19372 * common for all saved profile */
19373 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
19374 channels_allowed, &num_channels_allowed))
19375 {
19376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19377 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019378 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019379 goto error;
19380 }
19381 /* Checking each channel against allowed channel list */
19382 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053019383 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019384 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019385 char chList [(request->n_channels*5)+1];
19386 int len;
19387 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019388 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019389 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019390 {
Nirav Shah80830bf2013-12-31 16:35:12 +053019391 if (request->channels[i]->hw_value == channels_allowed[indx])
19392 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019393 if ((!pConfig->enableDFSPnoChnlScan) &&
19394 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
19395 {
19396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19397 "%s : Dropping DFS channel : %d",
19398 __func__,channels_allowed[indx]);
19399 num_ignore_dfs_ch++;
19400 break;
19401 }
19402
Nirav Shah80830bf2013-12-31 16:35:12 +053019403 valid_ch[num_ch++] = request->channels[i]->hw_value;
19404 len += snprintf(chList+len, 5, "%d ",
19405 request->channels[i]->hw_value);
19406 break ;
19407 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019408 }
19409 }
Nirav Shah80830bf2013-12-31 16:35:12 +053019410 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019411
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053019412 /*If all channels are DFS and dropped, then ignore the PNO request*/
19413 if (num_ignore_dfs_ch == request->n_channels)
19414 {
19415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19416 "%s : All requested channels are DFS channels", __func__);
19417 ret = -EINVAL;
19418 goto error;
19419 }
19420 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019421
19422 pnoRequest.aNetworks =
19423 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19424 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019425 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019426 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19427 FL("failed to allocate memory aNetworks %u"),
19428 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19429 goto error;
19430 }
19431 vos_mem_zero(pnoRequest.aNetworks,
19432 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
19433
19434 /* Filling per profile params */
19435 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
19436 {
19437 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019438 request->match_sets[i].ssid.ssid_len;
19439
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019440 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
19441 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019442 {
19443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019444 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019445 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019446 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019447 goto error;
19448 }
19449
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019450 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019451 request->match_sets[i].ssid.ssid,
19452 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053019453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19454 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019455 i, pnoRequest.aNetworks[i].ssId.ssId);
19456 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
19457 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
19458 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019459
19460 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019461 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
19462 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019463
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019464 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019465 }
19466
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019467 for (i = 0; i < request->n_ssids; i++)
19468 {
19469 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019470 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019471 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019472 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019473 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019474 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019475 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019476 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019477 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019478 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053019479 break;
19480 }
19481 j++;
19482 }
19483 }
19484 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19485 "Number of hidden networks being Configured = %d",
19486 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019487 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080019488 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019489
19490 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19491 if (pnoRequest.p24GProbeTemplate == NULL)
19492 {
19493 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19494 FL("failed to allocate memory p24GProbeTemplate %u"),
19495 SIR_PNO_MAX_PB_REQ_SIZE);
19496 goto error;
19497 }
19498
19499 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
19500 if (pnoRequest.p5GProbeTemplate == NULL)
19501 {
19502 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
19503 FL("failed to allocate memory p5GProbeTemplate %u"),
19504 SIR_PNO_MAX_PB_REQ_SIZE);
19505 goto error;
19506 }
19507
19508 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19509 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
19510
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053019511 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
19512 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019513 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019514 pnoRequest.us24GProbeTemplateLen = request->ie_len;
19515 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
19516 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019517
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019518 pnoRequest.us5GProbeTemplateLen = request->ie_len;
19519 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
19520 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053019521 }
19522
Anurag Chouhanf3e52b72016-12-21 11:33:37 +053019523 hdd_config_sched_scan_plan(&pnoRequest, request, pHddCtx);
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053019524
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019525 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019526
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019527 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019528 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19529 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019530 pAdapter->pno_req_status = 0;
19531
Nirav Shah80830bf2013-12-31 16:35:12 +053019532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19533 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019534 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
19535 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053019536
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019537 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019538 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019539 hdd_cfg80211_sched_scan_done_callback, pAdapter);
19540 if (eHAL_STATUS_SUCCESS != status)
19541 {
19542 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053019543 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019544 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019545 goto error;
19546 }
19547
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019548 ret = wait_for_completion_timeout(
19549 &pAdapter->pno_comp_var,
19550 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19551 if (0 >= ret)
19552 {
19553 // Did not receive the response for PNO enable in time.
19554 // Assuming the PNO enable was success.
19555 // Returning error from here, because we timeout, results
19556 // in side effect of Wifi (Wifi Setting) not to work.
19557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19558 FL("Timed out waiting for PNO to be Enabled"));
19559 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019560 }
19561
19562 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053019563 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019564
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019565error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
19567 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053019568 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019569 if (pnoRequest.aNetworks)
19570 vos_mem_free(pnoRequest.aNetworks);
19571 if (pnoRequest.p24GProbeTemplate)
19572 vos_mem_free(pnoRequest.p24GProbeTemplate);
19573 if (pnoRequest.p5GProbeTemplate)
19574 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053019575
19576 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019577 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019578}
19579
19580/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019581 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
19582 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019583 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019584static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
19585 struct net_device *dev, struct cfg80211_sched_scan_request *request)
19586{
19587 int ret;
19588
19589 vos_ssr_protect(__func__);
19590 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
19591 vos_ssr_unprotect(__func__);
19592
19593 return ret;
19594}
19595
19596/*
19597 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
19598 * Function to disable PNO
19599 */
19600static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019601 struct net_device *dev)
19602{
19603 eHalStatus status = eHAL_STATUS_FAILURE;
19604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19605 hdd_context_t *pHddCtx;
19606 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019607 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019608 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019609
19610 ENTER();
19611
19612 if (NULL == pAdapter)
19613 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019615 "%s: HDD adapter is Null", __func__);
19616 return -ENODEV;
19617 }
19618
19619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019620
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019621 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019622 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019623 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019624 "%s: HDD context is Null", __func__);
19625 return -ENODEV;
19626 }
19627
19628 /* The return 0 is intentional when isLogpInProgress and
19629 * isLoadUnloadInProgress. We did observe a crash due to a return of
19630 * failure in sched_scan_stop , especially for a case where the unload
19631 * of the happens at the same time. The function __cfg80211_stop_sched_scan
19632 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
19633 * success. If it returns a failure , then its next invocation due to the
19634 * clean up of the second interface will have the dev pointer corresponding
19635 * to the first one leading to a crash.
19636 */
19637 if (pHddCtx->isLogpInProgress)
19638 {
19639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19640 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053019641 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019642 return ret;
19643 }
19644
Mihir Shete18156292014-03-11 15:38:30 +053019645 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019646 {
19647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19648 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19649 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019650 }
19651
19652 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
19653 if (NULL == hHal)
19654 {
19655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19656 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019657 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019658 }
19659
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019660 pnoRequest.enable = 0; /* Disable PNO */
19661 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019662
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053019663 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19664 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
19665 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019666
19667 INIT_COMPLETION(pAdapter->pno_comp_var);
19668 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
19669 pnoRequest.callbackContext = pAdapter;
19670 pAdapter->pno_req_status = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053019671 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019672 pAdapter->sessionId,
19673 NULL, pAdapter);
19674 if (eHAL_STATUS_SUCCESS != status)
19675 {
19676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19677 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019678 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019679 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019680 }
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019681 ret = wait_for_completion_timeout(
19682 &pAdapter->pno_comp_var,
19683 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
19684 if (0 >= ret)
19685 {
19686 // Did not receive the response for PNO disable in time.
19687 // Assuming the PNO disable was success.
19688 // Returning error from here, because we timeout, results
19689 // in side effect of Wifi (Wifi Setting) not to work.
Anurag Chouhan96b41cb2016-09-28 18:54:47 +053019690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hanumantha Reddy Pothula0e408dc2015-11-23 12:04:53 +053019691 FL("Timed out waiting for PNO to be disabled"));
19692 ret = 0;
19693 }
19694
19695 ret = pAdapter->pno_req_status;
19696 pHddCtx->isPnoEnable = (ret == 0) ? FALSE : TRUE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019697
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019698error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053019700 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019701
19702 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053019703 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019704}
19705
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053019706/*
19707 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
19708 * NL interface to disable PNO
19709 */
19710static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
19711 struct net_device *dev)
19712{
19713 int ret;
19714
19715 vos_ssr_protect(__func__);
19716 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
19717 vos_ssr_unprotect(__func__);
19718
19719 return ret;
19720}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019721#endif /*FEATURE_WLAN_SCAN_PNO*/
19722
19723
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019724#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019725#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019726static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19727 struct net_device *dev,
19728 u8 *peer, u8 action_code,
19729 u8 dialog_token,
19730 u16 status_code, u32 peer_capability,
19731 const u8 *buf, size_t len)
19732#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053019733#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
19734 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019735static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19736 struct net_device *dev,
19737 const u8 *peer, u8 action_code,
19738 u8 dialog_token, u16 status_code,
19739 u32 peer_capability, bool initiator,
19740 const u8 *buf, size_t len)
19741#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
19742static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19743 struct net_device *dev,
19744 const u8 *peer, u8 action_code,
19745 u8 dialog_token, u16 status_code,
19746 u32 peer_capability, const u8 *buf,
19747 size_t len)
19748#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
19749static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19750 struct net_device *dev,
19751 u8 *peer, u8 action_code,
19752 u8 dialog_token,
19753 u16 status_code, u32 peer_capability,
19754 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019755#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053019756static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
19757 struct net_device *dev,
19758 u8 *peer, u8 action_code,
19759 u8 dialog_token,
19760 u16 status_code, const u8 *buf,
19761 size_t len)
19762#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019763#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019764{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019765 hdd_adapter_t *pAdapter;
19766 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019767 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070019768 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080019769 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070019770 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053019771 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019772 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053019773#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053019774 u32 peer_capability = 0;
19775#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019776 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019777 hdd_station_ctx_t *pHddStaCtx = NULL;
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019778 tdlsCtx_t *pHddTdlsCtx;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053019779
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019780 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
19781 if (NULL == pAdapter)
19782 {
19783 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19784 "%s: Adapter is NULL",__func__);
19785 return -EINVAL;
19786 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053019787 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
19788 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
19789 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019790
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019791 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019792 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019793 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053019794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019795 "Invalid arguments");
19796 return -EINVAL;
19797 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019798
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019799 if (pHddCtx->isLogpInProgress)
19800 {
19801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19802 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053019803 wlan_hdd_tdls_set_link_status(pAdapter,
19804 peer,
19805 eTDLS_LINK_IDLE,
19806 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080019807 return -EBUSY;
19808 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019809
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053019810 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
19811 {
19812 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19813 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
19814 return -EAGAIN;
19815 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019816
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019817 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
19818 if (!pHddTdlsCtx) {
19819 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19820 "%s: pHddTdlsCtx not valid.", __func__);
19821 }
19822
Hoonki Lee27511902013-03-14 18:19:06 -070019823 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019824 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019825 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019826 "%s: TDLS mode is disabled OR not enabled in FW."
19827 MAC_ADDRESS_STR " action %d declined.",
19828 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019829 return -ENOTSUPP;
19830 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019831
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019832 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
19833
19834 if( NULL == pHddStaCtx )
19835 {
19836 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19837 "%s: HDD station context NULL ",__func__);
19838 return -EINVAL;
19839 }
19840
19841 /* STA should be connected and authenticated
19842 * before sending any TDLS frames
19843 */
19844 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
19845 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
19846 {
19847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19848 "STA is not connected or unauthenticated. "
19849 "connState %u, uIsAuthenticated %u",
19850 pHddStaCtx->conn_info.connState,
19851 pHddStaCtx->conn_info.uIsAuthenticated);
19852 return -EAGAIN;
19853 }
19854
Hoonki Lee27511902013-03-14 18:19:06 -070019855 /* other than teardown frame, other mgmt frames are not sent if disabled */
19856 if (SIR_MAC_TDLS_TEARDOWN != action_code)
19857 {
19858 /* if tdls_mode is disabled to respond to peer's request */
19859 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
19860 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070019862 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019863 " TDLS mode is disabled. action %d declined.",
19864 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070019865
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053019866 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070019867 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053019868
19869 if (vos_max_concurrent_connections_reached())
19870 {
19871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
19872 return -EINVAL;
19873 }
Hoonki Lee27511902013-03-14 18:19:06 -070019874 }
19875
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019876 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
19877 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053019878 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019879 {
19880 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019881 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019882 " TDLS setup is ongoing. action %d declined.",
19883 __func__, MAC_ADDR_ARRAY(peer), action_code);
19884 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019885 }
19886 }
19887
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019888 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
19889 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080019890 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019891 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
19892 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019893 {
19894 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
19895 we return error code at 'add_station()'. Hence we have this
19896 check again in addtion to add_station().
19897 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019898 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080019899 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19901 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019902 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
19903 __func__, MAC_ADDR_ARRAY(peer), action_code,
19904 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053019905 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080019906 }
19907 else
19908 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019909 /* maximum reached. tweak to send error code to peer and return
19910 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019911 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
19913 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053019914 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
19915 __func__, MAC_ADDR_ARRAY(peer), status_code,
19916 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070019917 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080019918 /* fall through to send setup resp with failure status
19919 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080019920 }
19921 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019922 else
19923 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019924 mutex_lock(&pHddCtx->tdls_lock);
19925 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070019926 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019927 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019928 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019929 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070019930 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
19931 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019932 return -EPERM;
19933 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019934 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019935 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080019936 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019937
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019938 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019939 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070019940 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
19941 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019942
Hoonki Leea34dd892013-02-05 22:56:02 -080019943 /*Except teardown responder will not be used so just make 0*/
19944 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080019945 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080019946 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019947
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019948 mutex_lock(&pHddCtx->tdls_lock);
19949 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019950
19951 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
19952 responder = pTdlsPeer->is_responder;
19953 else
Hoonki Leea34dd892013-02-05 22:56:02 -080019954 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019955 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053019956 "%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 -070019957 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
19958 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019959 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070019960 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080019961 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053019962 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019963 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019964
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053019965 /* Discard TDLS setup if peer is removed by user app */
19966 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
19967 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
19968 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
19969 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
19970
19971 mutex_lock(&pHddCtx->tdls_lock);
19972 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
19973 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
19974 mutex_unlock(&pHddCtx->tdls_lock);
19975 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
19976 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
19977 MAC_ADDR_ARRAY(peer), action_code);
19978 return -EINVAL;
19979 }
19980 mutex_unlock(&pHddCtx->tdls_lock);
19981 }
19982
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019983 /* For explicit trigger of DIS_REQ come out of BMPS for
19984 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070019985 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Deepthi Gowrif78f1f72016-03-21 13:13:28 +053019986 (SIR_MAC_TDLS_SETUP_CNF== action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053019987 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
19988 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070019989 {
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019990 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter))) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053019991 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019992 "%s: Sending frame action_code %u.Disable BMPS", __func__,
19993 action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019994 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
19995 if (status != VOS_STATUS_SUCCESS) {
19996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
Ganesh Kondabattini17e60662017-05-25 12:36:07 +053019997 } else {
19998 pHddTdlsCtx->is_tdls_disabled_bmps = true;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053019999 }
Hoonki Lee14621352013-04-16 17:51:19 -070020000 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020001 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020002 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
20004 }
20005 }
Hoonki Lee14621352013-04-16 17:51:19 -070020006 }
20007
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020008 /* make sure doesn't call send_mgmt() while it is pending */
20009 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
20010 {
20011 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080020012 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020013 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020014 ret = -EBUSY;
20015 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020016 }
20017
20018 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020019 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
20020
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020021 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
20022 pAdapter->sessionId, peer, action_code, dialog_token,
20023 status_code, peer_capability, (tANI_U8 *)buf, len,
20024 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020025
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020026 if (VOS_STATUS_SUCCESS != status)
20027 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20029 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020030 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020031 ret = -EINVAL;
20032 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020033 }
20034
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020035 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20036 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
20037 WAIT_TIME_TDLS_MGMT);
20038
Hoonki Leed37cbb32013-04-20 00:31:14 -070020039 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
20040 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
20041
20042 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020043 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070020044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070020045 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070020046 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020047 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080020048
20049 if (pHddCtx->isLogpInProgress)
20050 {
20051 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20052 "%s: LOGP in Progress. Ignore!!!", __func__);
20053 return -EAGAIN;
20054 }
Abhishek Singh837adf22015-10-01 17:37:37 +053020055 if (rc <= 0)
20056 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
20057 WLAN_LOG_INDICATOR_HOST_DRIVER,
20058 WLAN_LOG_REASON_HDD_TIME_OUT,
20059 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080020060
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020061 ret = -EINVAL;
20062 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020063 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053020064 else
20065 {
20066 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20067 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
20068 __func__, rc, pAdapter->mgmtTxCompletionStatus);
20069 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020070
Gopichand Nakkala05922802013-03-14 12:23:19 -070020071 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070020072 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020073 ret = max_sta_failed;
20074 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070020075 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020076
Hoonki Leea34dd892013-02-05 22:56:02 -080020077 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
20078 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020079 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020080 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20081 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020082 }
20083 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
20084 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020085 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
20087 }
Hoonki Leea34dd892013-02-05 22:56:02 -080020088 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020089
20090 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053020091
20092tx_failed:
20093 /* add_station will be called before sending TDLS_SETUP_REQ and
20094 * TDLS_SETUP_RSP and as part of add_station driver will enable
20095 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
20096 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
20097 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
20098 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
20099 */
20100
20101 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
20102 (SIR_MAC_TDLS_SETUP_RSP == action_code))
20103 wlan_hdd_tdls_check_bmps(pAdapter);
20104 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020105}
20106
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020107#if TDLS_MGMT_VERSION2
20108static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20109 u8 *peer, u8 action_code, u8 dialog_token,
20110 u16 status_code, u32 peer_capability,
20111 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020112#else /* TDLS_MGMT_VERSION2 */
20113#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20114static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20115 struct net_device *dev,
20116 const u8 *peer, u8 action_code,
20117 u8 dialog_token, u16 status_code,
20118 u32 peer_capability, bool initiator,
20119 const u8 *buf, size_t len)
20120#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,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, const u8 *buf,
20126 size_t len)
20127#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20128static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
20129 struct net_device *dev,
20130 u8 *peer, u8 action_code,
20131 u8 dialog_token,
20132 u16 status_code, u32 peer_capability,
20133 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020134#else
20135static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
20136 u8 *peer, u8 action_code, u8 dialog_token,
20137 u16 status_code, const u8 *buf, size_t len)
20138#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020139#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020140{
20141 int ret;
20142
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020143 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020144#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020145 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20146 dialog_token, status_code,
20147 peer_capability, buf, len);
20148#else /* TDLS_MGMT_VERSION2 */
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053020149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || \
20150 defined(WITH_BACKPORTS)
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020151 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20152 dialog_token, status_code,
20153 peer_capability, initiator,
20154 buf, len);
20155#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
20156 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20157 dialog_token, status_code,
20158 peer_capability, buf, len);
20159#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
20160 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20161 dialog_token, status_code,
20162 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020163#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020164 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
20165 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020166#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020167#endif
20168 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020169
Anand N Sunkad9f80b742015-07-30 20:05:51 +053020170 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053020171}
Atul Mittal115287b2014-07-08 13:26:33 +053020172
20173int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20175 const u8 *peer,
20176#else
Atul Mittal115287b2014-07-08 13:26:33 +053020177 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020178#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020179 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053020180 cfg80211_exttdls_callback callback)
20181{
20182
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020183 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053020184 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020185 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053020186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20187 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
20188 __func__, MAC_ADDR_ARRAY(peer));
20189
20190 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20191 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20192
20193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020194 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20195 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20196 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020197 return -ENOTSUPP;
20198 }
20199
20200 /* To cater the requirement of establishing the TDLS link
20201 * irrespective of the data traffic , get an entry of TDLS peer.
20202 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020203 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020204 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
20205 if (pTdlsPeer == NULL) {
20206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20207 "%s: peer " MAC_ADDRESS_STR " not existing",
20208 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053020209 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020210 return -EINVAL;
20211 }
20212
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020213 /* check FW TDLS Off Channel capability */
20214 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020215 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053020216 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020217 {
20218 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
20219 pTdlsPeer->peerParams.global_operating_class =
20220 tdls_peer_params->global_operating_class;
20221 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
20222 pTdlsPeer->peerParams.min_bandwidth_kbps =
20223 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020224 /* check configured channel is valid, non dfs and
20225 * not current operating channel */
20226 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
20227 tdls_peer_params->channel)) &&
20228 (pHddStaCtx) &&
20229 (tdls_peer_params->channel !=
20230 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020231 {
20232 pTdlsPeer->isOffChannelConfigured = TRUE;
20233 }
20234 else
20235 {
20236 pTdlsPeer->isOffChannelConfigured = FALSE;
20237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20238 "%s: Configured Tdls Off Channel is not valid", __func__);
20239
20240 }
20241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020242 "%s: tdls_off_channel %d isOffChannelConfigured %d "
20243 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020244 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053020245 pTdlsPeer->isOffChannelConfigured,
20246 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020247 }
20248 else
20249 {
20250 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053020251 "%s: TDLS off channel FW capability %d, "
20252 "host capab %d or Invalid TDLS Peer Params", __func__,
20253 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
20254 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020255 }
20256
Atul Mittal115287b2014-07-08 13:26:33 +053020257 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
20258
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020259 mutex_unlock(&pHddCtx->tdls_lock);
20260
Atul Mittal115287b2014-07-08 13:26:33 +053020261 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20262 " %s TDLS Add Force Peer Failed",
20263 __func__);
20264 return -EINVAL;
20265 }
20266 /*EXT TDLS*/
20267
20268 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020269 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020270 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20271 " %s TDLS set callback Failed",
20272 __func__);
20273 return -EINVAL;
20274 }
20275
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020276 mutex_unlock(&pHddCtx->tdls_lock);
20277
Atul Mittal115287b2014-07-08 13:26:33 +053020278 return(0);
20279
20280}
20281
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020282int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
20283#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20284 const u8 *peer
20285#else
20286 u8 *peer
20287#endif
20288)
Atul Mittal115287b2014-07-08 13:26:33 +053020289{
20290
20291 hddTdlsPeer_t *pTdlsPeer;
20292 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020293
Atul Mittal115287b2014-07-08 13:26:33 +053020294 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20295 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
20296 __func__, MAC_ADDR_ARRAY(peer));
20297
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020298 if (0 != wlan_hdd_validate_context(pHddCtx)) {
20299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
20300 return -EINVAL;
20301 }
20302
Atul Mittal115287b2014-07-08 13:26:33 +053020303 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
20304 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
20305
20306 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020307 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
20308 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
20309 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053020310 return -ENOTSUPP;
20311 }
20312
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020313 mutex_lock(&pHddCtx->tdls_lock);
20314 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053020315
20316 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020317 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020318 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020319 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053020320 __func__, MAC_ADDR_ARRAY(peer));
20321 return -EINVAL;
20322 }
20323 else {
20324 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
20325 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Abhishek Singhff7c2f92016-01-05 15:28:12 +053020326 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_EXT_CTRL,
20327 pTdlsPeer->peerMac);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020328 /* if channel switch is configured, reset
20329 the channel for this peer */
20330 if (TRUE == pTdlsPeer->isOffChannelConfigured)
20331 {
20332 pTdlsPeer->peerParams.channel = 0;
20333 pTdlsPeer->isOffChannelConfigured = FALSE;
20334 }
Atul Mittal115287b2014-07-08 13:26:33 +053020335 }
20336
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020337 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020338 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020339 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053020340 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020341 }
Atul Mittal115287b2014-07-08 13:26:33 +053020342
20343 /*EXT TDLS*/
20344
20345 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020346 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053020347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20348 " %s TDLS set callback Failed",
20349 __func__);
20350 return -EINVAL;
20351 }
Atul Mittal115287b2014-07-08 13:26:33 +053020352
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020353 mutex_unlock(&pHddCtx->tdls_lock);
20354
20355 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053020356}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020357static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020358#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20359 const u8 *peer,
20360#else
20361 u8 *peer,
20362#endif
20363 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020364{
20365 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
20366 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020367 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020368 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053020369
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020370 ENTER();
20371
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053020372 if (!pAdapter) {
20373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
20374 return -EINVAL;
20375 }
20376
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053020377 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
20378 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
20379 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020380 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020381 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080020382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070020383 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020384 return -EINVAL;
20385 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020386
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020387 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020388 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020389 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053020390 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080020391 }
20392
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020393
20394 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020395 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020396 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080020397 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020398 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
20399 "Cannot process TDLS commands",
20400 pHddCtx->cfg_ini->fEnableTDLSSupport,
20401 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020402 return -ENOTSUPP;
20403 }
20404
20405 switch (oper) {
20406 case NL80211_TDLS_ENABLE_LINK:
20407 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020408 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020409 long ret;
Hanumantha Reddy Pothulada389492016-02-11 17:29:27 +053020410 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams = { {0}, 0,
20411 0, 0, 0, 0, 0, 0, {0}, 0, {0} };
Agarwal Ashish16020c42014-12-29 22:01:11 +053020412 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020413 tANI_U16 numCurrTdlsPeers = 0;
20414 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020415 tANI_U8 suppChannelLen = 0;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020416 tSirMacAddr peerMac;
20417 int channel;
20418 tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020419
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20421 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
20422 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020423
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020424 mutex_lock(&pHddCtx->tdls_lock);
20425 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020426 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053020427 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020428 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020429 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20430 " (oper %d) not exsting. ignored",
20431 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20432 return -EINVAL;
20433 }
20434
20435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20436 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20437 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20438 "NL80211_TDLS_ENABLE_LINK");
20439
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020440 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
20441 {
20442 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
20443 MAC_ADDRESS_STR " failed",
20444 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020445 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070020446 return -EINVAL;
20447 }
20448
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020449 /* before starting tdls connection, set tdls
20450 * off channel established status to default value */
20451 pTdlsPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020452
20453 mutex_unlock(&pHddCtx->tdls_lock);
20454
Deepthi Gowri2d85bbf2016-07-25 15:43:31 +053020455 wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020456 /* TDLS Off Channel, Disable tdls channel switch,
20457 when there are more than one tdls link */
20458 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053020459 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020460 {
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020461 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020462 /* get connected peer and send disable tdls off chan */
20463 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020464 if ((connPeer) &&
20465 (connPeer->isOffChannelSupported == TRUE) &&
20466 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020467 {
20468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20469 "%s: More then one peer connected, Disable "
20470 "TDLS channel switch", __func__);
20471
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020472 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020473 vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
20474 channel = connPeer->peerParams.channel;
20475
20476 mutex_unlock(&pHddCtx->tdls_lock);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020477
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020478 ret = sme_SendTdlsChanSwitchReq(
20479 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020480 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020481 peerMac,
20482 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020483 TDLS_OFF_CHANNEL_BW_OFFSET,
20484 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020485 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020486 hddLog(VOS_TRACE_LEVEL_ERROR,
20487 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020488 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020489 }
20490 else
20491 {
20492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20493 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020494 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020495 "isOffChannelConfigured %d",
20496 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020497 (connPeer ? (connPeer->isOffChannelSupported)
20498 : -1),
20499 (connPeer ? (connPeer->isOffChannelConfigured)
20500 : -1));
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020501 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020502 }
20503 }
20504
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020505 mutex_lock(&pHddCtx->tdls_lock);
20506 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20507 if ( NULL == pTdlsPeer ) {
20508 mutex_unlock(&pHddCtx->tdls_lock);
20509 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20510 "%s: " MAC_ADDRESS_STR
20511 " (oper %d) peer got freed in other context. ignored",
20512 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20513 return -EINVAL;
20514 }
20515 peer_status = pTdlsPeer->link_status;
20516 mutex_unlock(&pHddCtx->tdls_lock);
20517
20518 if (eTDLS_LINK_CONNECTED != peer_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020519 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020520 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053020521
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020522 if (0 != wlan_hdd_tdls_get_link_establish_params(
20523 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020525 return -EINVAL;
20526 }
20527 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020528
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020529 ret = sme_SendTdlsLinkEstablishParams(
20530 WLAN_HDD_GET_HAL_CTX(pAdapter),
20531 pAdapter->sessionId, peer,
20532 &tdlsLinkEstablishParams);
20533 if (ret != VOS_STATUS_SUCCESS) {
20534 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
20535 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020536 /* Send TDLS peer UAPSD capabilities to the firmware and
20537 * register with the TL on after the response for this operation
20538 * is received .
20539 */
20540 ret = wait_for_completion_interruptible_timeout(
20541 &pAdapter->tdls_link_establish_req_comp,
20542 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
Masti, Narayanraddie1892a52015-12-15 15:01:01 +053020543
20544 mutex_lock(&pHddCtx->tdls_lock);
20545 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20546 if ( NULL == pTdlsPeer ) {
20547 mutex_unlock(&pHddCtx->tdls_lock);
20548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20549 "%s %d: " MAC_ADDRESS_STR
20550 " (oper %d) peer got freed in other context. ignored",
20551 __func__, __LINE__, MAC_ADDR_ARRAY(peer),
20552 (int)oper);
20553 return -EINVAL;
20554 }
20555 peer_status = pTdlsPeer->link_status;
20556 mutex_unlock(&pHddCtx->tdls_lock);
20557
20558 if (ret <= 0 || (peer_status == eTDLS_LINK_TEARING))
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020559 {
20560 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020561 FL("Link Establish Request Failed Status %ld"),
20562 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053020563 return -EINVAL;
20564 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020565 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053020566
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020567 mutex_lock(&pHddCtx->tdls_lock);
20568 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20569 if ( NULL == pTdlsPeer ) {
20570 mutex_unlock(&pHddCtx->tdls_lock);
20571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20572 "%s: " MAC_ADDRESS_STR
20573 " (oper %d) peer got freed in other context. ignored",
20574 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20575 return -EINVAL;
20576 }
20577
Atul Mittal115287b2014-07-08 13:26:33 +053020578 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20579 eTDLS_LINK_CONNECTED,
20580 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053020581 staDesc.ucSTAId = pTdlsPeer->staId;
20582 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Masti, Narayanraddi3d799022015-12-24 18:22:36 +053020583
20584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20585 "%s: tdlsLinkEstablishParams of peer "
20586 MAC_ADDRESS_STR "uapsdQueues: %d"
20587 "qos: %d maxSp: %d isBufSta: %d isOffChannelSupported: %d"
20588 "isResponder: %d peerstaId: %d",
20589 __func__,
20590 MAC_ADDR_ARRAY(tdlsLinkEstablishParams.peerMac),
20591 tdlsLinkEstablishParams.uapsdQueues,
20592 tdlsLinkEstablishParams.qos,
20593 tdlsLinkEstablishParams.maxSp,
20594 tdlsLinkEstablishParams.isBufSta,
20595 tdlsLinkEstablishParams.isOffChannelSupported,
20596 tdlsLinkEstablishParams.isResponder,
20597 pTdlsPeer->staId);
20598
20599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20600 "%s: StaDesc ucSTAId: %d ucQosEnabled: %d",
20601 __func__,
20602 staDesc.ucSTAId,
20603 staDesc.ucQosEnabled);
20604
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020605 ret = WLANTL_UpdateTdlsSTAClient(
20606 pHddCtx->pvosContext,
20607 &staDesc);
20608 if (ret != VOS_STATUS_SUCCESS) {
20609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
20610 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053020611
Gopichand Nakkala471708b2013-06-04 20:03:01 +053020612 /* Mark TDLS client Authenticated .*/
20613 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
20614 pTdlsPeer->staId,
20615 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020616 if (VOS_STATUS_SUCCESS == status)
20617 {
Hoonki Lee14621352013-04-16 17:51:19 -070020618 if (pTdlsPeer->is_responder == 0)
20619 {
20620 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020621 tdlsConnInfo_t *tdlsInfo;
20622
20623 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
20624
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020625 if (!vos_timer_is_initialized(
20626 &pTdlsPeer->initiatorWaitTimeoutTimer))
20627 {
20628 /* Initialize initiator wait callback */
20629 vos_timer_init(
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053020630 &pTdlsPeer->initiatorWaitTimeoutTimer,
20631 VOS_TIMER_TYPE_SW,
20632 wlan_hdd_tdls_initiator_wait_cb,
20633 tdlsInfo);
Hanumantha Reddy Pothulac8238402016-03-24 18:02:23 +053020634 }
Hoonki Lee14621352013-04-16 17:51:19 -070020635 wlan_hdd_tdls_timer_restart(pAdapter,
20636 &pTdlsPeer->initiatorWaitTimeoutTimer,
20637 WAIT_TIME_TDLS_INITIATOR);
20638 /* suspend initiator TX until it receives direct packet from the
20639 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020640 ret = WLANTL_SuspendDataTx(
20641 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20642 &staId, NULL);
20643 if (ret != VOS_STATUS_SUCCESS) {
20644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
20645 }
Hoonki Lee14621352013-04-16 17:51:19 -070020646 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020647
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020648 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020649 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020650 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020651 suppChannelLen =
20652 tdlsLinkEstablishParams.supportedChannelsLen;
20653
20654 if ((suppChannelLen > 0) &&
20655 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
20656 {
20657 tANI_U8 suppPeerChannel = 0;
20658 int i = 0;
20659 for (i = 0U; i < suppChannelLen; i++)
20660 {
20661 suppPeerChannel =
20662 tdlsLinkEstablishParams.supportedChannels[i];
20663
20664 pTdlsPeer->isOffChannelSupported = FALSE;
20665 if (suppPeerChannel ==
20666 pTdlsPeer->peerParams.channel)
20667 {
20668 pTdlsPeer->isOffChannelSupported = TRUE;
20669 break;
20670 }
20671 }
20672 }
20673 else
20674 {
20675 pTdlsPeer->isOffChannelSupported = FALSE;
20676 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020677 }
20678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20679 "%s: TDLS channel switch request for channel "
20680 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020681 "%d isOffChannelSupported %d", __func__,
20682 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020683 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053020684 suppChannelLen,
20685 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053020686
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020687 /* TDLS Off Channel, Enable tdls channel switch,
20688 when their is only one tdls link and it supports */
20689 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20690 if ((numCurrTdlsPeers == 1) &&
20691 (TRUE == pTdlsPeer->isOffChannelSupported) &&
20692 (TRUE == pTdlsPeer->isOffChannelConfigured))
20693 {
20694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20695 "%s: Send TDLS channel switch request for channel %d",
20696 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020697
20698 pTdlsPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020699 vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
20700 channel = pTdlsPeer->peerParams.channel;
20701
20702 mutex_unlock(&pHddCtx->tdls_lock);
20703
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020704 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
20705 pAdapter->sessionId,
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020706 peerMac,
20707 channel,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020708 TDLS_OFF_CHANNEL_BW_OFFSET,
20709 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020710 if (ret != VOS_STATUS_SUCCESS) {
20711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
20712 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020713 }
20714 else
20715 {
20716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20717 "%s: TDLS channel switch request not sent"
20718 " numCurrTdlsPeers %d "
20719 "isOffChannelSupported %d "
20720 "isOffChannelConfigured %d",
20721 __func__, numCurrTdlsPeers,
20722 pTdlsPeer->isOffChannelSupported,
20723 pTdlsPeer->isOffChannelConfigured);
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020724 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020725 }
20726
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070020727 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020728 else
20729 mutex_unlock(&pHddCtx->tdls_lock);
20730
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020731 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020732
20733 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020734 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
20735 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020736 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020737 int ac;
20738 uint8 ucAc[4] = { WLANTL_AC_VO,
20739 WLANTL_AC_VI,
20740 WLANTL_AC_BK,
20741 WLANTL_AC_BE };
20742 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
20743 for(ac=0; ac < 4; ac++)
20744 {
20745 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
20746 pTdlsPeer->staId, ucAc[ac],
20747 tlTid[ac], tlTid[ac], 0, 0,
20748 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020749 if (status != VOS_STATUS_SUCCESS) {
20750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
20751 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053020752 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053020753 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020754 }
Masti, Narayanraddi09c52d52015-12-19 14:19:18 +053020755
Bhargav Shah66896792015-10-01 18:17:37 +053020756 /* stop TCP delack timer if TDLS is enable */
20757 set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20758 hdd_manage_delack_timer(pHddCtx);
Abhishek Singh67fa6bc2016-01-05 15:57:19 +053020759 hdd_wlan_tdls_enable_link_event(peer,
20760 pTdlsPeer->isOffChannelSupported,
20761 pTdlsPeer->isOffChannelConfigured,
20762 pTdlsPeer->isOffChannelEstablished);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020763 }
20764 break;
20765 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080020766 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020767 tANI_U16 numCurrTdlsPeers = 0;
20768 hddTdlsPeer_t *connPeer = NULL;
20769
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20771 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
20772 __func__, MAC_ADDR_ARRAY(peer));
20773
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020774 mutex_lock(&pHddCtx->tdls_lock);
20775 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020776
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020777
Sunil Dutt41de4e22013-11-14 18:09:02 +053020778 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020779 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020780 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20781 " (oper %d) not exsting. ignored",
20782 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
20783 return -EINVAL;
20784 }
20785
20786 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20787 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
20788 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
20789 "NL80211_TDLS_DISABLE_LINK");
20790
Hoonki Lee5305c3a2013-04-29 23:28:59 -070020791 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080020792 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020793 long status;
20794
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053020795 /* set tdls off channel status to false for this peer */
20796 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053020797 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
20798 eTDLS_LINK_TEARING,
20799 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
20800 eTDLS_LINK_UNSPECIFIED:
20801 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020802 mutex_unlock(&pHddCtx->tdls_lock);
20803
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020804 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
20805
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020806 status = sme_DeleteTdlsPeerSta(
20807 WLAN_HDD_GET_HAL_CTX(pAdapter),
20808 pAdapter->sessionId, peer );
20809 if (status != VOS_STATUS_SUCCESS) {
20810 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
20811 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020812
20813 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
20814 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020815
20816 mutex_lock(&pHddCtx->tdls_lock);
20817 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
20818 if ( NULL == pTdlsPeer ) {
20819 mutex_unlock(&pHddCtx->tdls_lock);
20820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
20821 " peer was freed in other context",
20822 __func__, MAC_ADDR_ARRAY(peer));
20823 return -EINVAL;
20824 }
20825
Atul Mittal271a7652014-09-12 13:18:22 +053020826 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053020827 eTDLS_LINK_IDLE,
20828 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020829 mutex_unlock(&pHddCtx->tdls_lock);
20830
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020831 if (status <= 0)
20832 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070020833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20834 "%s: Del station failed status %ld",
20835 __func__, status);
20836 return -EPERM;
20837 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020838
20839 /* TDLS Off Channel, Enable tdls channel switch,
20840 when their is only one tdls link and it supports */
20841 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
20842 if (numCurrTdlsPeers == 1)
20843 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020844 tSirMacAddr peerMac;
20845 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020846
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020847 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020848 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053020849
20850 if (connPeer == NULL) {
20851 mutex_unlock(&pHddCtx->tdls_lock);
20852 hddLog(VOS_TRACE_LEVEL_ERROR,
20853 "%s connPeer is NULL", __func__);
20854 return -EINVAL;
20855 }
20856
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020857 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
20858 channel = connPeer->peerParams.channel;
20859
20860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
20861 "%s: TDLS channel switch "
20862 "isOffChannelSupported %d "
20863 "isOffChannelConfigured %d "
20864 "isOffChannelEstablished %d",
20865 __func__,
20866 (connPeer ? connPeer->isOffChannelSupported : -1),
20867 (connPeer ? connPeer->isOffChannelConfigured : -1),
20868 (connPeer ? connPeer->isOffChannelEstablished : -1));
20869
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020870 if ((connPeer) &&
20871 (connPeer->isOffChannelSupported == TRUE) &&
20872 (connPeer->isOffChannelConfigured == TRUE))
20873 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053020874 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020875 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020876 status = sme_SendTdlsChanSwitchReq(
20877 WLAN_HDD_GET_HAL_CTX(pAdapter),
20878 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020879 peerMac,
20880 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053020881 TDLS_OFF_CHANNEL_BW_OFFSET,
20882 TDLS_CHANNEL_SWITCH_ENABLE);
20883 if (status != VOS_STATUS_SUCCESS) {
20884 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
20885 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020886 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020887 else
20888 mutex_unlock(&pHddCtx->tdls_lock);
20889 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020890 else
20891 {
20892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20893 "%s: TDLS channel switch request not sent "
20894 "numCurrTdlsPeers %d ",
20895 __func__, numCurrTdlsPeers);
20896 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020897 }
20898 else
20899 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053020900 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20902 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080020903 }
Bhargav Shah66896792015-10-01 18:17:37 +053020904 if (numCurrTdlsPeers == 0) {
20905 /* start TCP delack timer if TDLS is disable */
20906 clear_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
20907 hdd_manage_delack_timer(pHddCtx);
20908 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080020909 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070020910 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020911 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020912 {
Atul Mittal115287b2014-07-08 13:26:33 +053020913 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020914
Atul Mittal115287b2014-07-08 13:26:33 +053020915 if (0 != status)
20916 {
20917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020918 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053020919 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020920 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053020921 break;
20922 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020923 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053020924 {
Atul Mittal115287b2014-07-08 13:26:33 +053020925 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
20926 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053020927 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053020928 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053020929
Atul Mittal115287b2014-07-08 13:26:33 +053020930 if (0 != status)
20931 {
20932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020933 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053020934 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053020935 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053020936 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053020937 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020938 case NL80211_TDLS_DISCOVERY_REQ:
20939 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053020941 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020942 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020943 return -ENOTSUPP;
20944 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053020945 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
20946 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020947 return -ENOTSUPP;
20948 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053020949
20950 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020951 return 0;
20952}
Chilam NG571c65a2013-01-19 12:27:36 +053020953
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020954static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
20956 const u8 *peer,
20957#else
20958 u8 *peer,
20959#endif
20960 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053020961{
20962 int ret;
20963
20964 vos_ssr_protect(__func__);
20965 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
20966 vos_ssr_unprotect(__func__);
20967
20968 return ret;
20969}
20970
Chilam NG571c65a2013-01-19 12:27:36 +053020971int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
20972 struct net_device *dev, u8 *peer)
20973{
Arif Hussaina7c8e412013-11-20 11:06:42 -080020974 hddLog(VOS_TRACE_LEVEL_INFO,
20975 "tdls send discover req: "MAC_ADDRESS_STR,
20976 MAC_ADDR_ARRAY(peer));
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020977#if TDLS_MGMT_VERSION2
20978 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20979 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20980#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020981#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
20982 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20983 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
20984#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
20985 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20986 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20987#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
20988 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20989 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
20990#else
Chilam NG571c65a2013-01-19 12:27:36 +053020991 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
20992 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053020993#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053020994#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053020995}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080020996#endif
20997
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053020998#ifdef WLAN_FEATURE_GTK_OFFLOAD
20999/*
21000 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
21001 * Callback rountine called upon receiving response for
21002 * get offload info
21003 */
21004void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
21005 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
21006{
21007
21008 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021009 tANI_U8 tempReplayCounter[8];
21010 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021011
21012 ENTER();
21013
21014 if (NULL == pAdapter)
21015 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053021016 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021017 "%s: HDD adapter is Null", __func__);
21018 return ;
21019 }
21020
21021 if (NULL == pGtkOffloadGetInfoRsp)
21022 {
21023 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21024 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
21025 return ;
21026 }
21027
21028 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
21029 {
21030 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21031 "%s: wlan Failed to get replay counter value",
21032 __func__);
21033 return ;
21034 }
21035
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021036 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21037 /* Update replay counter */
21038 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
21039 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21040
21041 {
21042 /* changing from little to big endian since supplicant
21043 * works on big endian format
21044 */
21045 int i;
21046 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
21047
21048 for (i = 0; i < 8; i++)
21049 {
21050 tempReplayCounter[7-i] = (tANI_U8)p[i];
21051 }
21052 }
21053
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021054 /* Update replay counter to NL */
21055 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021056 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021057}
21058
21059/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021060 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021061 * This function is used to offload GTK rekeying job to the firmware.
21062 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021063int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021064 struct cfg80211_gtk_rekey_data *data)
21065{
21066 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21067 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21068 hdd_station_ctx_t *pHddStaCtx;
21069 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021070 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021071 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021072 eHalStatus status = eHAL_STATUS_FAILURE;
21073
21074 ENTER();
21075
21076 if (NULL == pAdapter)
21077 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053021078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021079 "%s: HDD adapter is Null", __func__);
21080 return -ENODEV;
21081 }
21082
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053021083 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21084 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
21085 pAdapter->sessionId, pAdapter->device_mode));
21086
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021087 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021088 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021089 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053021090 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021091 }
21092
21093 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21094 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
21095 if (NULL == hHal)
21096 {
21097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21098 "%s: HAL context is Null!!!", __func__);
21099 return -EAGAIN;
21100 }
21101
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021102 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
21103 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
21104 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
21105 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021106 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021107 {
21108 /* changing from big to little endian since driver
21109 * works on little endian format
21110 */
21111 tANI_U8 *p =
21112 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
21113 int i;
21114
21115 for (i = 0; i < 8; i++)
21116 {
21117 p[7-i] = data->replay_ctr[i];
21118 }
21119 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021120
21121 if (TRUE == pHddCtx->hdd_wlan_suspended)
21122 {
21123 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021124 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
21125 sizeof (tSirGtkOffloadParams));
21126 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021127 pAdapter->sessionId);
21128
21129 if (eHAL_STATUS_SUCCESS != status)
21130 {
21131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21132 "%s: sme_SetGTKOffload failed, returned %d",
21133 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021134
21135 /* Need to clear any trace of key value in the memory.
21136 * Thus zero out the memory even though it is local
21137 * variable.
21138 */
21139 vos_mem_zero(&hddGtkOffloadReqParams,
21140 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021141 return status;
21142 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21144 "%s: sme_SetGTKOffload successfull", __func__);
21145 }
21146 else
21147 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21149 "%s: wlan not suspended GTKOffload request is stored",
21150 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021151 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021152
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053021153 /* Need to clear any trace of key value in the memory.
21154 * Thus zero out the memory even though it is local
21155 * variable.
21156 */
21157 vos_mem_zero(&hddGtkOffloadReqParams,
21158 sizeof(hddGtkOffloadReqParams));
21159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021160 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053021161 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021162}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053021163
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021164int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
21165 struct cfg80211_gtk_rekey_data *data)
21166{
21167 int ret;
21168
21169 vos_ssr_protect(__func__);
21170 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
21171 vos_ssr_unprotect(__func__);
21172
21173 return ret;
21174}
21175#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021176/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021177 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021178 * This function is used to set access control policy
21179 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021180static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21181 struct net_device *dev,
21182 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021183{
21184 int i;
21185 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21186 hdd_hostapd_state_t *pHostapdState;
21187 tsap_Config_t *pConfig;
21188 v_CONTEXT_t pVosContext = NULL;
21189 hdd_context_t *pHddCtx;
21190 int status;
21191
21192 ENTER();
21193
21194 if (NULL == pAdapter)
21195 {
21196 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21197 "%s: HDD adapter is Null", __func__);
21198 return -ENODEV;
21199 }
21200
21201 if (NULL == params)
21202 {
21203 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21204 "%s: params is Null", __func__);
21205 return -EINVAL;
21206 }
21207
21208 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21209 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021210 if (0 != status)
21211 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021212 return status;
21213 }
21214
21215 pVosContext = pHddCtx->pvosContext;
21216 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
21217
21218 if (NULL == pHostapdState)
21219 {
21220 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21221 "%s: pHostapdState is Null", __func__);
21222 return -EINVAL;
21223 }
21224
21225 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
21226 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021227 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21228 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
21229 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021230
21231 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
21232 {
21233 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
21234
21235 /* default value */
21236 pConfig->num_accept_mac = 0;
21237 pConfig->num_deny_mac = 0;
21238
21239 /**
21240 * access control policy
21241 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
21242 * listed in hostapd.deny file.
21243 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
21244 * listed in hostapd.accept file.
21245 */
21246 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
21247 {
21248 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
21249 }
21250 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
21251 {
21252 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
21253 }
21254 else
21255 {
21256 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21257 "%s:Acl Policy : %d is not supported",
21258 __func__, params->acl_policy);
21259 return -ENOTSUPP;
21260 }
21261
21262 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
21263 {
21264 pConfig->num_accept_mac = params->n_acl_entries;
21265 for (i = 0; i < params->n_acl_entries; i++)
21266 {
21267 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21268 "** Add ACL MAC entry %i in WhiletList :"
21269 MAC_ADDRESS_STR, i,
21270 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21271
21272 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
21273 sizeof(qcmacaddr));
21274 }
21275 }
21276 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
21277 {
21278 pConfig->num_deny_mac = params->n_acl_entries;
21279 for (i = 0; i < params->n_acl_entries; i++)
21280 {
21281 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21282 "** Add ACL MAC entry %i in BlackList :"
21283 MAC_ADDRESS_STR, i,
21284 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
21285
21286 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
21287 sizeof(qcmacaddr));
21288 }
21289 }
21290
21291 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
21292 {
21293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21294 "%s: SAP Set Mac Acl fail", __func__);
21295 return -EINVAL;
21296 }
21297 }
21298 else
21299 {
21300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053021301 "%s: Invalid device_mode = %s (%d)",
21302 __func__, hdd_device_modetoString(pAdapter->device_mode),
21303 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021304 return -EINVAL;
21305 }
21306
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021307 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053021308 return 0;
21309}
21310
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053021311static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
21312 struct net_device *dev,
21313 const struct cfg80211_acl_data *params)
21314{
21315 int ret;
21316 vos_ssr_protect(__func__);
21317 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
21318 vos_ssr_unprotect(__func__);
21319
21320 return ret;
21321}
21322
Leo Chang9056f462013-08-01 19:21:11 -070021323#ifdef WLAN_NL80211_TESTMODE
21324#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070021325void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070021326(
21327 void *pAdapter,
21328 void *indCont
21329)
21330{
Leo Changd9df8aa2013-09-26 13:32:26 -070021331 tSirLPHBInd *lphbInd;
21332 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053021333 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070021334
21335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021336 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070021337
c_hpothu73f35e62014-04-18 13:40:08 +053021338 if (pAdapter == NULL)
21339 {
21340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21341 "%s: pAdapter is NULL\n",__func__);
21342 return;
21343 }
21344
Leo Chang9056f462013-08-01 19:21:11 -070021345 if (NULL == indCont)
21346 {
21347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070021348 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070021349 return;
21350 }
21351
c_hpothu73f35e62014-04-18 13:40:08 +053021352 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070021353 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070021354 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053021355 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070021356 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070021357 GFP_ATOMIC);
21358 if (!skb)
21359 {
21360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21361 "LPHB timeout, NL buffer alloc fail");
21362 return;
21363 }
21364
Leo Changac3ba772013-10-07 09:47:04 -070021365 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070021366 {
21367 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21368 "WLAN_HDD_TM_ATTR_CMD put fail");
21369 goto nla_put_failure;
21370 }
Leo Changac3ba772013-10-07 09:47:04 -070021371 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070021372 {
21373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21374 "WLAN_HDD_TM_ATTR_TYPE put fail");
21375 goto nla_put_failure;
21376 }
Leo Changac3ba772013-10-07 09:47:04 -070021377 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070021378 sizeof(tSirLPHBInd), lphbInd))
21379 {
21380 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21381 "WLAN_HDD_TM_ATTR_DATA put fail");
21382 goto nla_put_failure;
21383 }
Leo Chang9056f462013-08-01 19:21:11 -070021384 cfg80211_testmode_event(skb, GFP_ATOMIC);
21385 return;
21386
21387nla_put_failure:
21388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21389 "NLA Put fail");
21390 kfree_skb(skb);
21391
21392 return;
21393}
21394#endif /* FEATURE_WLAN_LPHB */
21395
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021396static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070021397{
21398 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
21399 int err = 0;
21400#ifdef FEATURE_WLAN_LPHB
21401 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070021402 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021403
21404 ENTER();
21405
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021406 err = wlan_hdd_validate_context(pHddCtx);
21407 if (0 != err)
21408 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021409 return err;
21410 }
Leo Chang9056f462013-08-01 19:21:11 -070021411#endif /* FEATURE_WLAN_LPHB */
21412
21413 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
21414 if (err)
21415 {
21416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21417 "%s Testmode INV ATTR", __func__);
21418 return err;
21419 }
21420
21421 if (!tb[WLAN_HDD_TM_ATTR_CMD])
21422 {
21423 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21424 "%s Testmode INV CMD", __func__);
21425 return -EINVAL;
21426 }
21427
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021428 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21429 TRACE_CODE_HDD_CFG80211_TESTMODE,
21430 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070021431 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
21432 {
21433#ifdef FEATURE_WLAN_LPHB
21434 /* Low Power Heartbeat configuration request */
21435 case WLAN_HDD_TM_CMD_WLAN_HB:
21436 {
21437 int buf_len;
21438 void *buf;
21439 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080021440 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070021441
21442 if (!tb[WLAN_HDD_TM_ATTR_DATA])
21443 {
21444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21445 "%s Testmode INV DATA", __func__);
21446 return -EINVAL;
21447 }
21448
21449 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
21450 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080021451
Manjeet Singh3c577442017-02-10 19:03:38 +053021452 if (buf_len > sizeof(*hb_params)) {
21453 hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
21454 buf_len);
21455 return -ERANGE;
21456 }
21457
Amar Singhal05852702014-02-04 14:40:00 -080021458 hb_params_temp =(tSirLPHBReq *)buf;
21459 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
21460 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
21461 return -EINVAL;
21462
Leo Chang9056f462013-08-01 19:21:11 -070021463 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
21464 if (NULL == hb_params)
21465 {
21466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21467 "%s Request Buffer Alloc Fail", __func__);
21468 return -EINVAL;
21469 }
21470
Ashish Kumar Dhanotiya3a8c0a72017-07-13 18:58:59 +053021471 vos_mem_zero(hb_params, sizeof(tSirLPHBReq));
Leo Chang9056f462013-08-01 19:21:11 -070021472 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070021473 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
21474 hb_params,
21475 wlan_hdd_cfg80211_lphb_ind_handler);
21476 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070021477 {
Leo Changd9df8aa2013-09-26 13:32:26 -070021478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21479 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070021480 vos_mem_free(hb_params);
21481 }
Leo Chang9056f462013-08-01 19:21:11 -070021482 return 0;
21483 }
21484#endif /* FEATURE_WLAN_LPHB */
21485 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053021486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
21487 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070021488 return -EOPNOTSUPP;
21489 }
21490
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021491 EXIT();
21492 return err;
Leo Chang9056f462013-08-01 19:21:11 -070021493}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021494
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053021495static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
21496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
21497 struct wireless_dev *wdev,
21498#endif
21499 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021500{
21501 int ret;
21502
21503 vos_ssr_protect(__func__);
21504 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
21505 vos_ssr_unprotect(__func__);
21506
21507 return ret;
21508}
Leo Chang9056f462013-08-01 19:21:11 -070021509#endif /* CONFIG_NL80211_TESTMODE */
21510
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021511extern void hdd_set_wlan_suspend_mode(bool suspend);
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021512static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021513 struct net_device *dev,
21514 int idx, struct survey_info *survey)
21515{
21516 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
21517 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053021518 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021519 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053021520 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021521 v_S7_t snr,rssi;
21522 int status, i, j, filled = 0;
21523
21524 ENTER();
21525
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021526 if (NULL == pAdapter)
21527 {
21528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21529 "%s: HDD adapter is Null", __func__);
21530 return -ENODEV;
21531 }
21532
21533 if (NULL == wiphy)
21534 {
21535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
21536 "%s: wiphy is Null", __func__);
21537 return -ENODEV;
21538 }
21539
21540 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
21541 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021542 if (0 != status)
21543 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021544 return status;
21545 }
21546
Mihir Sheted9072e02013-08-21 17:02:29 +053021547 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
21548
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021549 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053021550 0 != pAdapter->survey_idx ||
21551 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021552 {
21553 /* The survey dump ops when implemented completely is expected to
21554 * return a survey of all channels and the ops is called by the
21555 * kernel with incremental values of the argument 'idx' till it
21556 * returns -ENONET. But we can only support the survey for the
21557 * operating channel for now. survey_idx is used to track
21558 * that the ops is called only once and then return -ENONET for
21559 * the next iteration
21560 */
21561 pAdapter->survey_idx = 0;
21562 return -ENONET;
21563 }
21564
Mukul Sharma9d5233b2015-06-11 20:28:20 +053021565 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
21566 {
21567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21568 "%s: Roaming in progress, hence return ", __func__);
21569 return -ENONET;
21570 }
21571
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021572 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
21573
21574 wlan_hdd_get_snr(pAdapter, &snr);
21575 wlan_hdd_get_rssi(pAdapter, &rssi);
21576
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021577 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21578 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
21579 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021580 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
21581 hdd_wlan_get_freq(channel, &freq);
21582
21583
Rajeev Kumar Sirasanagandla5b21a9c2018-01-08 17:05:11 +053021584 for (i = 0; i < HDD_NUM_NL80211_BANDS; i++)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021585 {
21586 if (NULL == wiphy->bands[i])
21587 {
21588 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
21589 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
21590 continue;
21591 }
21592
21593 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
21594 {
21595 struct ieee80211_supported_band *band = wiphy->bands[i];
21596
21597 if (band->channels[j].center_freq == (v_U16_t)freq)
21598 {
21599 survey->channel = &band->channels[j];
21600 /* The Rx BDs contain SNR values in dB for the received frames
21601 * while the supplicant expects noise. So we calculate and
21602 * return the value of noise (dBm)
21603 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
21604 */
21605 survey->noise = rssi - snr;
21606 survey->filled = SURVEY_INFO_NOISE_DBM;
21607 filled = 1;
21608 }
21609 }
21610 }
21611
21612 if (filled)
21613 pAdapter->survey_idx = 1;
21614 else
21615 {
21616 pAdapter->survey_idx = 0;
21617 return -ENONET;
21618 }
21619
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021620 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053021621 return 0;
21622}
21623
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053021624static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
21625 struct net_device *dev,
21626 int idx, struct survey_info *survey)
21627{
21628 int ret;
21629
21630 vos_ssr_protect(__func__);
21631 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
21632 vos_ssr_unprotect(__func__);
21633
21634 return ret;
21635}
21636
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021637/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021638 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021639 * this is called when cfg80211 driver resume
21640 * driver updates latest sched_scan scan result(if any) to cfg80211 database
21641 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021642int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021643{
21644 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
21645 hdd_adapter_t *pAdapter;
21646 hdd_adapter_list_node_t *pAdapterNode, *pNext;
21647 VOS_STATUS status = VOS_STATUS_SUCCESS;
21648
21649 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021650
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053021651 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021652 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021653 return 0;
21654 }
21655
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021656 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
21657 NO_SESSION, pHddCtx->isWiphySuspended));
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021658
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021659 if (pHddCtx->is_ap_mode_wow_supported)
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021660 {
21661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21662 "%s: Resume SoftAP", __func__);
21663 hdd_set_wlan_suspend_mode(false);
21664 }
21665
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021666 spin_lock(&pHddCtx->schedScan_lock);
21667 pHddCtx->isWiphySuspended = FALSE;
21668 if (TRUE != pHddCtx->isSchedScanUpdatePending)
21669 {
21670 spin_unlock(&pHddCtx->schedScan_lock);
21671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21672 "%s: Return resume is not due to PNO indication", __func__);
21673 return 0;
21674 }
21675 // Reset flag to avoid updatating cfg80211 data old results again
21676 pHddCtx->isSchedScanUpdatePending = FALSE;
21677 spin_unlock(&pHddCtx->schedScan_lock);
21678
21679 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
21680
21681 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
21682 {
21683 pAdapter = pAdapterNode->pAdapter;
21684 if ( (NULL != pAdapter) &&
21685 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
21686 {
21687 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021688 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
21690 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021691 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021692 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021693 {
21694 /* Acquire wakelock to handle the case where APP's tries to
21695 * suspend immediately after updating the scan results. Whis
21696 * results in app's is in suspended state and not able to
21697 * process the connect request to AP
21698 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053021699 hdd_prevent_suspend_timeout(2000,
21700 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021701 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053021702 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021703
21704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21705 "%s : cfg80211 scan result database updated", __func__);
21706
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021707 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021708 return 0;
21709
21710 }
21711 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
21712 pAdapterNode = pNext;
21713 }
21714
21715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21716 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021717 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021718 return 0;
21719}
21720
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021721int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
21722{
21723 int ret;
21724
21725 vos_ssr_protect(__func__);
21726 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
21727 vos_ssr_unprotect(__func__);
21728
21729 return ret;
21730}
21731
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021732/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021733 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021734 * this is called when cfg80211 driver suspends
21735 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021736int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021737 struct cfg80211_wowlan *wow)
21738{
21739 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021740 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021741
21742 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053021743
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021744 ret = wlan_hdd_validate_context(pHddCtx);
21745 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021746 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021747 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021748 }
21749
Nishank Aggarwalc11826c2016-12-15 18:54:10 +053021750 if (pHddCtx->is_ap_mode_wow_supported) {
Arun Khandavalli08bcafd2016-11-08 14:45:48 +053021751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
21752 "%s: Suspend SoftAP", __func__);
21753 hdd_set_wlan_suspend_mode(true);
21754 }
21755
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053021756
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053021757 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
21758 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
21759 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053021760 pHddCtx->isWiphySuspended = TRUE;
21761
21762 EXIT();
21763
21764 return 0;
21765}
21766
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053021767int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
21768 struct cfg80211_wowlan *wow)
21769{
21770 int ret;
21771
21772 vos_ssr_protect(__func__);
21773 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
21774 vos_ssr_unprotect(__func__);
21775
21776 return ret;
21777}
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021778
21779#ifdef FEATURE_OEM_DATA_SUPPORT
21780static void wlan_hdd_cfg80211_oem_data_rsp_ind_new(void *ctx,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021781 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021782{
21783 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21784
21785 ENTER();
21786
21787 if (wlan_hdd_validate_context(pHddCtx)) {
21788 return;
21789 }
21790 if (!pMsg)
21791 {
21792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
21793 return;
21794 }
21795
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021796 send_oem_data_rsp_msg(evLen, pMsg);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021797
21798 EXIT();
21799 return;
21800
21801}
21802
21803void wlan_hdd_cfg80211_oemdata_callback(void *ctx, const tANI_U16 evType,
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021804 void *pMsg, tANI_U32 evLen)
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021805{
21806 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
21807
21808 ENTER();
21809
21810 if (wlan_hdd_validate_context(pHddCtx)) {
21811 return;
21812 }
21813
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d) evLen %d"), evType, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021815
21816 switch(evType) {
21817 case SIR_HAL_START_OEM_DATA_RSP_IND_NEW:
Padma, Santhosh Kumarf75c37b2016-01-25 10:36:08 +053021818 wlan_hdd_cfg80211_oem_data_rsp_ind_new(ctx, pMsg, evLen);
Padma, Santhosh Kumar2ccac212015-10-20 17:27:27 +053021819 break;
21820 default:
21821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
21822 break;
21823 }
21824 EXIT();
21825}
21826#endif
21827
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021828#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
21829 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021830/**
21831 * __wlan_hdd_cfg80211_abort_scan() - cfg80211 abort scan api
21832 * @wiphy: Pointer to wiphy
21833 * @wdev: Pointer to wireless device structure
21834 *
21835 * This function is used to abort an ongoing scan
21836 *
21837 * Return: None
21838 */
21839static void __wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21840 struct wireless_dev *wdev)
21841{
21842 struct net_device *dev = wdev->netdev;
21843 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21844 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
21845 int ret;
21846
21847 ENTER();
21848
21849 if (NULL == adapter) {
21850 hddLog(VOS_TRACE_LEVEL_FATAL, FL("HDD adapter is NULL"));
21851 return;
21852 }
21853
21854 ret = wlan_hdd_validate_context(hdd_ctx);
21855 if (0 != ret)
21856 return;
21857
21858 wlan_hdd_scan_abort(adapter);
21859
21860 return;
21861}
21862
21863/**
21864 * wlan_hdd_cfg80211_abort_scan - cfg80211 abort scan api
21865 * @wiphy: Pointer to wiphy
21866 * @wdev: Pointer to wireless device structure
21867 *
21868 * Return: None
21869 */
21870void wlan_hdd_cfg80211_abort_scan(struct wiphy *wiphy,
21871 struct wireless_dev *wdev)
21872{
21873 vos_ssr_protect(__func__);
21874 __wlan_hdd_cfg80211_abort_scan(wiphy, wdev);
21875 vos_ssr_unprotect(__func__);
21876
21877 return;
21878}
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053021879#endif
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053021880
Abhishek Singh936c6932017-11-07 17:28:23 +053021881#ifdef CHANNEL_SWITCH_SUPPORTED
21882/**
21883 * __wlan_hdd_cfg80211_channel_switch()- function to switch
21884 * channel in SAP/GO
21885 * @wiphy: wiphy pointer
21886 * @dev: dev pointer.
21887 * @csa_params: Change channel params
21888 *
21889 * This function is called to switch channel in SAP/GO
21890 *
21891 * Return: 0 if success else return non zero
21892 */
21893static int __wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21894 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21895{
21896 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
21897 hdd_context_t *hdd_ctx;
21898 uint8_t channel;
21899 int ret;
21900 v_CONTEXT_t vos_ctx;
21901
21902 hddLog(LOGE, FL("Set Freq %d"), csa_params->chandef.chan->center_freq);
21903
21904 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
21905 ret = wlan_hdd_validate_context(hdd_ctx);
21906 if (ret)
21907 return ret;
21908
21909 vos_ctx = (WLAN_HDD_GET_CTX(adapter))->pvosContext;
21910 if (!vos_ctx) {
21911 hddLog(LOGE, FL("Vos ctx is null"));
21912 return -EINVAL;
21913 }
21914
21915 if ((WLAN_HDD_SOFTAP != adapter->device_mode) &&
21916 (WLAN_HDD_P2P_GO != adapter->device_mode))
21917 return -ENOTSUPP;
21918
21919 channel = vos_freq_to_chan(csa_params->chandef.chan->center_freq);
Abhishek Singhceb6fe22017-11-27 13:53:18 +053021920 ret = wlansap_set_channel_change(vos_ctx, channel, false);
Abhishek Singh936c6932017-11-07 17:28:23 +053021921
21922 return ret;
21923}
21924
21925/**
21926 * wlan_hdd_cfg80211_channel_switch()- function to switch
21927 * channel in SAP/GO
21928 * @wiphy: wiphy pointer
21929 * @dev: dev pointer.
21930 * @csa_params: Change channel params
21931 *
21932 * This function is called to switch channel in SAP/GO
21933 *
21934 * Return: 0 if success else return non zero
21935 */
21936static int wlan_hdd_cfg80211_channel_switch(struct wiphy *wiphy,
21937 struct net_device *dev, struct cfg80211_csa_settings *csa_params)
21938{
21939 int ret;
21940
21941 vos_ssr_protect(__func__);
21942 ret = __wlan_hdd_cfg80211_channel_switch(wiphy, dev, csa_params);
21943 vos_ssr_unprotect(__func__);
21944
21945 return ret;
21946}
21947#endif
21948
Jeff Johnson295189b2012-06-20 16:38:30 -070021949/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053021950static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070021951{
21952 .add_virtual_intf = wlan_hdd_add_virtual_intf,
21953 .del_virtual_intf = wlan_hdd_del_virtual_intf,
21954 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
21955 .change_station = wlan_hdd_change_station,
21956#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
21957 .add_beacon = wlan_hdd_cfg80211_add_beacon,
21958 .del_beacon = wlan_hdd_cfg80211_del_beacon,
21959 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021960#else
21961 .start_ap = wlan_hdd_cfg80211_start_ap,
21962 .change_beacon = wlan_hdd_cfg80211_change_beacon,
21963 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070021964#endif
21965 .change_bss = wlan_hdd_cfg80211_change_bss,
21966 .add_key = wlan_hdd_cfg80211_add_key,
21967 .get_key = wlan_hdd_cfg80211_get_key,
21968 .del_key = wlan_hdd_cfg80211_del_key,
21969 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021970#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070021971 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080021972#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021973 .scan = wlan_hdd_cfg80211_scan,
21974 .connect = wlan_hdd_cfg80211_connect,
21975 .disconnect = wlan_hdd_cfg80211_disconnect,
21976 .join_ibss = wlan_hdd_cfg80211_join_ibss,
21977 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
21978 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
21979 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
21980 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070021981 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
21982 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053021983 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070021984#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
21985 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
21986 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
21987 .set_txq_params = wlan_hdd_set_txq_params,
21988#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070021989 .get_station = wlan_hdd_cfg80211_get_station,
21990 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
21991 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070021992 .add_station = wlan_hdd_cfg80211_add_station,
21993#ifdef FEATURE_WLAN_LFR
21994 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
21995 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
21996 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
21997#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070021998#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
21999 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
22000#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080022001#ifdef FEATURE_WLAN_TDLS
22002 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
22003 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
22004#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053022005#ifdef WLAN_FEATURE_GTK_OFFLOAD
22006 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
22007#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053022008#ifdef FEATURE_WLAN_SCAN_PNO
22009 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
22010 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
22011#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053022012 .resume = wlan_hdd_cfg80211_resume_wlan,
22013 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053022014 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070022015#ifdef WLAN_NL80211_TESTMODE
22016 .testmode_cmd = wlan_hdd_cfg80211_testmode,
22017#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053022018 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)) || \
22020 defined(CFG80211_ABORT_SCAN)
Kanchanapally, Vidyullathac4735162016-02-09 17:49:39 +053022021 .abort_scan = wlan_hdd_cfg80211_abort_scan,
Kanchanapally, Vidyullatha740d64e2016-05-03 15:25:54 +053022022#endif
Abhishek Singh936c6932017-11-07 17:28:23 +053022023#ifdef CHANNEL_SWITCH_SUPPORTED
22024 .channel_switch = wlan_hdd_cfg80211_channel_switch,
22025#endif
22026
Jeff Johnson295189b2012-06-20 16:38:30 -070022027};
22028