blob: f19b89068e25e6a0124da600b015a77675ab890b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
5 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006/**========================================================================
7
8 \file wlan_hdd_cfg80211.c
9
10 \brief WLAN Host Device Driver implementation
11
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012 Copyright 2008 (c) Qualcomm Technologies, Inc. All Rights Reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -070013
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014 Qualcomm Technologies Confidential and Proprietary.
Jeff Johnson295189b2012-06-20 16:38:30 -070015
16 ========================================================================*/
17
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070018/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070019
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070020 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070021
22
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070023 This section contains comments describing changes made to the module.
24 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070025
26
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070027 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070028
29
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070030 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070031 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070032 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070033
34 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070035 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070036 ==========================================================================*/
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038
39#include <linux/version.h>
40#include <linux/module.h>
41#include <linux/kernel.h>
42#include <linux/init.h>
43#include <linux/wireless.h>
44#include <wlan_hdd_includes.h>
45#include <net/arp.h>
46#include <net/cfg80211.h>
47#include <linux/wireless.h>
48#include <wlan_hdd_wowl.h>
49#include <aniGlobal.h>
50#include "ccmApi.h"
51#include "sirParams.h"
52#include "dot11f.h"
53#include "wlan_hdd_assoc.h"
54#include "wlan_hdd_wext.h"
55#include "sme_Api.h"
56#include "wlan_hdd_p2p.h"
57#include "wlan_hdd_cfg80211.h"
58#include "wlan_hdd_hostapd.h"
59#include "sapInternal.h"
60#include "wlan_hdd_softap_tx_rx.h"
61#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053062#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053063#include "wlan_hdd_power.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070064#ifdef WLAN_BTAMP_FEATURE
65#include "bap_hdd_misc.h"
66#endif
67#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080068#ifdef FEATURE_WLAN_TDLS
69#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053070#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053071#include "wlan_qct_wda.h"
Mohit Khanna698ba2a2012-12-04 15:08:18 -080072#endif
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053073#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070074#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070075
76#define g_mode_rates_size (12)
77#define a_mode_rates_size (8)
78#define FREQ_BASE_80211G (2407)
79#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070080#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +053081#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -070082#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
83 ((int) OFFSET_OF( tSirBssDescription, ieFields)))
84
85#define HDD2GHZCHAN(freq, chan, flag) { \
86 .band = IEEE80211_BAND_2GHZ, \
87 .center_freq = (freq), \
88 .hw_value = (chan),\
89 .flags = (flag), \
90 .max_antenna_gain = 0 ,\
91 .max_power = 30, \
92}
93
94#define HDD5GHZCHAN(freq, chan, flag) { \
95 .band = IEEE80211_BAND_5GHZ, \
96 .center_freq = (freq), \
97 .hw_value = (chan),\
98 .flags = (flag), \
99 .max_antenna_gain = 0 ,\
100 .max_power = 30, \
101}
102
103#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
104{\
105 .bitrate = rate, \
106 .hw_value = rate_id, \
107 .flags = flag, \
108}
109
Lee Hoonkic1262f22013-01-24 21:59:00 -0800110#ifndef WLAN_FEATURE_TDLS_DEBUG
111#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
112#else
113#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_ERROR
114#endif
115
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530116#ifdef WLAN_FEATURE_VOWIFI_11R
117#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
118#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
119#endif
120
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530121static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700122{
123 WLAN_CIPHER_SUITE_WEP40,
124 WLAN_CIPHER_SUITE_WEP104,
125 WLAN_CIPHER_SUITE_TKIP,
126#ifdef FEATURE_WLAN_CCX
127#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
128 WLAN_CIPHER_SUITE_KRK,
129 WLAN_CIPHER_SUITE_CCMP,
130#else
131 WLAN_CIPHER_SUITE_CCMP,
132#endif
133#ifdef FEATURE_WLAN_WAPI
134 WLAN_CIPHER_SUITE_SMS4,
135#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700136#ifdef WLAN_FEATURE_11W
137 WLAN_CIPHER_SUITE_AES_CMAC,
138#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700139};
140
141static inline int is_broadcast_ether_addr(const u8 *addr)
142{
143 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
144 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
145}
146
147static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530148{
Jeff Johnson295189b2012-06-20 16:38:30 -0700149 HDD2GHZCHAN(2412, 1, 0) ,
150 HDD2GHZCHAN(2417, 2, 0) ,
151 HDD2GHZCHAN(2422, 3, 0) ,
152 HDD2GHZCHAN(2427, 4, 0) ,
153 HDD2GHZCHAN(2432, 5, 0) ,
154 HDD2GHZCHAN(2437, 6, 0) ,
155 HDD2GHZCHAN(2442, 7, 0) ,
156 HDD2GHZCHAN(2447, 8, 0) ,
157 HDD2GHZCHAN(2452, 9, 0) ,
158 HDD2GHZCHAN(2457, 10, 0) ,
159 HDD2GHZCHAN(2462, 11, 0) ,
160 HDD2GHZCHAN(2467, 12, 0) ,
161 HDD2GHZCHAN(2472, 13, 0) ,
162 HDD2GHZCHAN(2484, 14, 0) ,
163};
164
Jeff Johnson295189b2012-06-20 16:38:30 -0700165static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
166{
167 HDD2GHZCHAN(2412, 1, 0) ,
168 HDD2GHZCHAN(2437, 6, 0) ,
169 HDD2GHZCHAN(2462, 11, 0) ,
170};
Jeff Johnson295189b2012-06-20 16:38:30 -0700171
172static struct ieee80211_channel hdd_channels_5_GHZ[] =
173{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700174 HDD5GHZCHAN(4920, 240, 0) ,
175 HDD5GHZCHAN(4940, 244, 0) ,
176 HDD5GHZCHAN(4960, 248, 0) ,
177 HDD5GHZCHAN(4980, 252, 0) ,
178 HDD5GHZCHAN(5040, 208, 0) ,
179 HDD5GHZCHAN(5060, 212, 0) ,
180 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700181 HDD5GHZCHAN(5180, 36, 0) ,
182 HDD5GHZCHAN(5200, 40, 0) ,
183 HDD5GHZCHAN(5220, 44, 0) ,
184 HDD5GHZCHAN(5240, 48, 0) ,
185 HDD5GHZCHAN(5260, 52, 0) ,
186 HDD5GHZCHAN(5280, 56, 0) ,
187 HDD5GHZCHAN(5300, 60, 0) ,
188 HDD5GHZCHAN(5320, 64, 0) ,
189 HDD5GHZCHAN(5500,100, 0) ,
190 HDD5GHZCHAN(5520,104, 0) ,
191 HDD5GHZCHAN(5540,108, 0) ,
192 HDD5GHZCHAN(5560,112, 0) ,
193 HDD5GHZCHAN(5580,116, 0) ,
194 HDD5GHZCHAN(5600,120, 0) ,
195 HDD5GHZCHAN(5620,124, 0) ,
196 HDD5GHZCHAN(5640,128, 0) ,
197 HDD5GHZCHAN(5660,132, 0) ,
198 HDD5GHZCHAN(5680,136, 0) ,
199 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800200#ifdef FEATURE_WLAN_CH144
201 HDD5GHZCHAN(5720,144, 0) ,
202#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700203 HDD5GHZCHAN(5745,149, 0) ,
204 HDD5GHZCHAN(5765,153, 0) ,
205 HDD5GHZCHAN(5785,157, 0) ,
206 HDD5GHZCHAN(5805,161, 0) ,
207 HDD5GHZCHAN(5825,165, 0) ,
208};
209
210static struct ieee80211_rate g_mode_rates[] =
211{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530212 HDD_G_MODE_RATETAB(10, 0x1, 0),
213 HDD_G_MODE_RATETAB(20, 0x2, 0),
214 HDD_G_MODE_RATETAB(55, 0x4, 0),
215 HDD_G_MODE_RATETAB(110, 0x8, 0),
216 HDD_G_MODE_RATETAB(60, 0x10, 0),
217 HDD_G_MODE_RATETAB(90, 0x20, 0),
218 HDD_G_MODE_RATETAB(120, 0x40, 0),
219 HDD_G_MODE_RATETAB(180, 0x80, 0),
220 HDD_G_MODE_RATETAB(240, 0x100, 0),
221 HDD_G_MODE_RATETAB(360, 0x200, 0),
222 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700223 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530224};
Jeff Johnson295189b2012-06-20 16:38:30 -0700225
226static struct ieee80211_rate a_mode_rates[] =
227{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530228 HDD_G_MODE_RATETAB(60, 0x10, 0),
229 HDD_G_MODE_RATETAB(90, 0x20, 0),
230 HDD_G_MODE_RATETAB(120, 0x40, 0),
231 HDD_G_MODE_RATETAB(180, 0x80, 0),
232 HDD_G_MODE_RATETAB(240, 0x100, 0),
233 HDD_G_MODE_RATETAB(360, 0x200, 0),
234 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700235 HDD_G_MODE_RATETAB(540, 0x800, 0),
236};
237
238static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
239{
240 .channels = hdd_channels_2_4_GHZ,
241 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
242 .band = IEEE80211_BAND_2GHZ,
243 .bitrates = g_mode_rates,
244 .n_bitrates = g_mode_rates_size,
245 .ht_cap.ht_supported = 1,
246 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
247 | IEEE80211_HT_CAP_GRN_FLD
248 | IEEE80211_HT_CAP_DSSSCCK40
249 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
250 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
251 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
252 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
253 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
254 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
255};
256
Jeff Johnson295189b2012-06-20 16:38:30 -0700257static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
258{
259 .channels = hdd_social_channels_2_4_GHZ,
260 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
261 .band = IEEE80211_BAND_2GHZ,
262 .bitrates = g_mode_rates,
263 .n_bitrates = g_mode_rates_size,
264 .ht_cap.ht_supported = 1,
265 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
266 | IEEE80211_HT_CAP_GRN_FLD
267 | IEEE80211_HT_CAP_DSSSCCK40
268 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
269 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
270 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
271 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
272 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
273 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
274};
Jeff Johnson295189b2012-06-20 16:38:30 -0700275
276static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
277{
278 .channels = hdd_channels_5_GHZ,
279 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
280 .band = IEEE80211_BAND_5GHZ,
281 .bitrates = a_mode_rates,
282 .n_bitrates = a_mode_rates_size,
283 .ht_cap.ht_supported = 1,
284 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
285 | IEEE80211_HT_CAP_GRN_FLD
286 | IEEE80211_HT_CAP_DSSSCCK40
287 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
288 | IEEE80211_HT_CAP_SGI_40
289 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
290 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
291 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
292 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
293 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
294 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
295};
296
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530297/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700298 TX/RX direction for each kind of interface */
299static const struct ieee80211_txrx_stypes
300wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
301 [NL80211_IFTYPE_STATION] = {
302 .tx = 0xffff,
303 .rx = BIT(SIR_MAC_MGMT_ACTION) |
304 BIT(SIR_MAC_MGMT_PROBE_REQ),
305 },
306 [NL80211_IFTYPE_AP] = {
307 .tx = 0xffff,
308 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
309 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
310 BIT(SIR_MAC_MGMT_PROBE_REQ) |
311 BIT(SIR_MAC_MGMT_DISASSOC) |
312 BIT(SIR_MAC_MGMT_AUTH) |
313 BIT(SIR_MAC_MGMT_DEAUTH) |
314 BIT(SIR_MAC_MGMT_ACTION),
315 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700316 [NL80211_IFTYPE_ADHOC] = {
317 .tx = 0xffff,
318 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
319 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
320 BIT(SIR_MAC_MGMT_PROBE_REQ) |
321 BIT(SIR_MAC_MGMT_DISASSOC) |
322 BIT(SIR_MAC_MGMT_AUTH) |
323 BIT(SIR_MAC_MGMT_DEAUTH) |
324 BIT(SIR_MAC_MGMT_ACTION),
325 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700326 [NL80211_IFTYPE_P2P_CLIENT] = {
327 .tx = 0xffff,
328 .rx = BIT(SIR_MAC_MGMT_ACTION) |
329 BIT(SIR_MAC_MGMT_PROBE_REQ),
330 },
331 [NL80211_IFTYPE_P2P_GO] = {
332 /* This is also same as for SoftAP */
333 .tx = 0xffff,
334 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
335 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
336 BIT(SIR_MAC_MGMT_PROBE_REQ) |
337 BIT(SIR_MAC_MGMT_DISASSOC) |
338 BIT(SIR_MAC_MGMT_AUTH) |
339 BIT(SIR_MAC_MGMT_DEAUTH) |
340 BIT(SIR_MAC_MGMT_ACTION),
341 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700342};
343
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800344#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800345static const struct ieee80211_iface_limit
346wlan_hdd_iface_limit[] = {
347 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800348 /* max = 3 ; Our driver create two interfaces during driver init
349 * wlan0 and p2p0 interfaces. p2p0 is considered as station
350 * interface until a group is formed. In JB architecture, once the
351 * group is formed, interface type of p2p0 is changed to P2P GO or
352 * Client.
353 * When supplicant remove the group, it first issue a set interface
354 * cmd to change the mode back to Station. In JB this works fine as
355 * we advertize two station type interface during driver init.
356 * Some vendors create separate interface for P2P GO/Client,
357 * after group formation(Third one). But while group remove
358 * supplicant first tries to change the mode(3rd interface) to STATION
359 * But as we advertized only two sta type interfaces nl80211 was
360 * returning error for the third one which was leading to failure in
361 * delete interface. Ideally while removing the group, supplicant
362 * should not try to change the 3rd interface mode to Station type.
363 * Till we get a fix in wpa_supplicant, we advertize max STA
364 * interface type to 3
365 */
366 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800367 .types = BIT(NL80211_IFTYPE_STATION),
368 },
369 {
370 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700371 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800372 },
373 {
374 .max = 1,
375 .types = BIT(NL80211_IFTYPE_P2P_GO) |
376 BIT(NL80211_IFTYPE_P2P_CLIENT),
377 },
378};
379
380/* By default, only single channel concurrency is allowed */
381static struct ieee80211_iface_combination
382wlan_hdd_iface_combination = {
383 .limits = wlan_hdd_iface_limit,
384 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800385 /*
386 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
387 * and p2p0 interfaces during driver init
388 * Some vendors create separate interface for P2P operations.
389 * wlan0: STA interface
390 * p2p0: P2P Device interface, action frames goes
391 * through this interface.
392 * p2p-xx: P2P interface, After GO negotiation this interface is
393 * created for p2p operations(GO/CLIENT interface).
394 */
395 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800396 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
397 .beacon_int_infra_match = false,
398};
399#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800400
Jeff Johnson295189b2012-06-20 16:38:30 -0700401static struct cfg80211_ops wlan_hdd_cfg80211_ops;
402
403/* Data rate 100KBPS based on IE Index */
404struct index_data_rate_type
405{
406 v_U8_t beacon_rate_index;
407 v_U16_t supported_rate[4];
408};
409
410/* 11B, 11G Rate table include Basic rate and Extended rate
411 The IDX field is the rate index
412 The HI field is the rate when RSSI is strong or being ignored
413 (in this case we report actual rate)
414 The MID field is the rate when RSSI is moderate
415 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
416 The LO field is the rate when RSSI is low
417 (in this case we don't report rates, actual current rate used)
418 */
419static const struct
420{
421 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700422 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700423} supported_data_rate[] =
424{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700425/* IDX HI HM LM LO (RSSI-based index */
426 {2, { 10, 10, 10, 0}},
427 {4, { 20, 20, 10, 0}},
428 {11, { 55, 20, 10, 0}},
429 {12, { 60, 55, 20, 0}},
430 {18, { 90, 55, 20, 0}},
431 {22, {110, 55, 20, 0}},
432 {24, {120, 90, 60, 0}},
433 {36, {180, 120, 60, 0}},
434 {44, {220, 180, 60, 0}},
435 {48, {240, 180, 90, 0}},
436 {66, {330, 180, 90, 0}},
437 {72, {360, 240, 90, 0}},
438 {96, {480, 240, 120, 0}},
439 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700440};
441
442/* MCS Based rate table */
443static struct index_data_rate_type supported_mcs_rate[] =
444{
445/* MCS L20 L40 S20 S40 */
446 {0, {65, 135, 72, 150}},
447 {1, {130, 270, 144, 300}},
448 {2, {195, 405, 217, 450}},
449 {3, {260, 540, 289, 600}},
450 {4, {390, 810, 433, 900}},
451 {5, {520, 1080, 578, 1200}},
452 {6, {585, 1215, 650, 1350}},
453 {7, {650, 1350, 722, 1500}}
454};
455
Leo Chang6f8870f2013-03-26 18:11:36 -0700456#ifdef WLAN_FEATURE_11AC
457
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530458#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700459
460struct index_vht_data_rate_type
461{
462 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530463 v_U16_t supported_VHT80_rate[2];
464 v_U16_t supported_VHT40_rate[2];
465 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700466};
467
468typedef enum
469{
470 DATA_RATE_11AC_MAX_MCS_7,
471 DATA_RATE_11AC_MAX_MCS_8,
472 DATA_RATE_11AC_MAX_MCS_9,
473 DATA_RATE_11AC_MAX_MCS_NA
474} eDataRate11ACMaxMcs;
475
476/* MCS Based VHT rate table */
477static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
478{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530479/* MCS L80 S80 L40 S40 L20 S40*/
480 {0, {293, 325}, {135, 150}, {65, 72}},
481 {1, {585, 650}, {270, 300}, {130, 144}},
482 {2, {878, 975}, {405, 450}, {195, 217}},
483 {3, {1170, 1300}, {540, 600}, {260, 289}},
484 {4, {1755, 1950}, {810, 900}, {390, 433}},
485 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
486 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
487 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
488 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
489 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700490};
491#endif /* WLAN_FEATURE_11AC */
492
Jeff Johnson295189b2012-06-20 16:38:30 -0700493extern struct net_device_ops net_ops_struct;
494
Leo Chang9056f462013-08-01 19:21:11 -0700495#ifdef WLAN_NL80211_TESTMODE
496enum wlan_hdd_tm_attr
497{
498 WLAN_HDD_TM_ATTR_INVALID = 0,
499 WLAN_HDD_TM_ATTR_CMD = 1,
500 WLAN_HDD_TM_ATTR_DATA = 2,
501 WLAN_HDD_TM_ATTR_TYPE = 3,
502 /* keep last */
503 WLAN_HDD_TM_ATTR_AFTER_LAST,
504 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
505};
506
507enum wlan_hdd_tm_cmd
508{
509 WLAN_HDD_TM_CMD_WLAN_HB = 1,
510};
511
512#define WLAN_HDD_TM_DATA_MAX_LEN 5000
513
514static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
515{
516 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
517 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
518 .len = WLAN_HDD_TM_DATA_MAX_LEN },
519};
520#endif /* WLAN_NL80211_TESTMODE */
521
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800522#ifdef FEATURE_WLAN_CH_AVOID
523/*
524 * FUNCTION: wlan_hdd_send_avoid_freq_event
525 * This is called when wlan driver needs to send vendor specific
526 * avoid frequency range event to userspace
527 */
528int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
529 tHddAvoidFreqList *pAvoidFreqList)
530{
531 struct sk_buff *vendor_event;
532
533 ENTER();
534
535 if (!pHddCtx)
536 {
537 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
538 "%s: HDD context is null", __func__);
539 return -1;
540 }
541
542 if (!pAvoidFreqList)
543 {
544 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
545 "%s: pAvoidFreqList is null", __func__);
546 return -1;
547 }
548
549 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
550 sizeof(tHddAvoidFreqList),
551 QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
552 GFP_KERNEL);
553 if (!vendor_event)
554 {
555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
556 "%s: cfg80211_vendor_event_alloc failed", __func__);
557 return -1;
558 }
559
560 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
561 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
562
563 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
564
565 EXIT();
566 return 0;
567}
568#endif /* FEATURE_WLAN_CH_AVOID */
569
570/* vendor specific events */
571static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
572{
573#ifdef FEATURE_WLAN_CH_AVOID
574 {
575 .vendor_id = QCOM_NL80211_VENDOR_ID,
576 .subcmd = QCOM_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
577 },
578#endif /* FEATURE_WLAN_CH_AVOID */
579};
580
Jeff Johnson295189b2012-06-20 16:38:30 -0700581/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530582 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530583 * This function is called by hdd_wlan_startup()
584 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530585 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -0700586 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530587struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -0700588{
589 struct wiphy *wiphy;
590 ENTER();
591
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530592 /*
593 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -0700594 */
595 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
596
597 if (!wiphy)
598 {
599 /* Print error and jump into err label and free the memory */
600 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
601 return NULL;
602 }
603
604 return wiphy;
605}
606
607/*
608 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530609 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -0700610 * private ioctl to change the band value
611 */
612int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
613{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530614 int i, j;
615 eNVChannelEnabledType channelEnabledState;
616
Jeff Johnsone7245742012-09-05 17:12:55 -0700617 ENTER();
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530618 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -0700619 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530620
621 if (NULL == wiphy->bands[i])
622 {
623 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
624 __func__, i);
625 continue;
626 }
627
628 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
629 {
630 struct ieee80211_supported_band *band = wiphy->bands[i];
631
632 channelEnabledState = vos_nv_getChannelEnabledState(
633 band->channels[j].hw_value);
634
635 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
636 {
637 // Enable Social channels for P2P
638 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq) &&
639 NV_CHANNEL_ENABLE == channelEnabledState)
640 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
641 else
642 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
643 continue;
644 }
645 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
646 {
647 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
648 continue;
649 }
650
651 if (NV_CHANNEL_DISABLE == channelEnabledState ||
652 NV_CHANNEL_INVALID == channelEnabledState)
653 {
654 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
655 }
656 else if (NV_CHANNEL_DFS == channelEnabledState)
657 {
658 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
659 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
660 }
661 else
662 {
663 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
664 |IEEE80211_CHAN_RADAR);
665 }
666 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700667 }
668 return 0;
669}
670/*
671 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530672 * This function is called by hdd_wlan_startup()
673 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -0700674 * This function is used to initialize and register wiphy structure.
675 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530676int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -0700677 struct wiphy *wiphy,
678 hdd_config_t *pCfg
679 )
680{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530681 int i, j;
Jeff Johnsone7245742012-09-05 17:12:55 -0700682 ENTER();
683
Jeff Johnson295189b2012-06-20 16:38:30 -0700684 /* Now bind the underlying wlan device with wiphy */
685 set_wiphy_dev(wiphy, dev);
686
687 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700688
Kiet Lam6c583332013-10-14 05:37:09 +0530689#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -0700690 /* the flag for the other case would be initialzed in
691 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -0700692 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +0530693#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700694
Amar Singhalfddc28c2013-09-05 13:03:40 -0700695 /* This will disable updating of NL channels from passive to
696 * active if a beacon is received on passive channel. */
697 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Amar Singhalf0073192013-09-20 12:34:56 -0700698
Amar Singhalfddc28c2013-09-05 13:03:40 -0700699
Amar Singhala49cbc52013-10-08 18:37:44 -0700700
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700701#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -0700702 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
703 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
704 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -0700705 | WIPHY_FLAG_OFFCHAN_TX;
Kiet Lam6c583332013-10-14 05:37:09 +0530706 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700707#endif
Amar Singhala49cbc52013-10-08 18:37:44 -0700708
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700709#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
710 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -0800711#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -0700712 || pCfg->isFastRoamIniFeatureEnabled
713#endif
714#ifdef FEATURE_WLAN_CCX
715 || pCfg->isCcxIniFeatureEnabled
716#endif
717 )
718 {
719 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
720 }
James Zmuda77fb5ae2013-01-29 08:00:17 -0800721#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800722#ifdef FEATURE_WLAN_TDLS
723 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
724 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
725#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530726#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +0530727 if (pCfg->configPNOScanSupport)
728 {
729 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
730 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
731 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
732 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
733 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +0530734#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -0800735
Amar Singhalfddc28c2013-09-05 13:03:40 -0700736#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700737 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
738 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -0700739 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700740 driver need to determine what to do with both
741 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -0700742
743 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -0700744#else
745 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -0700746#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700747
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530748 wiphy->max_scan_ssids = MAX_SCAN_SSID;
749
Madan Mohan Koyyalamudi6815b162013-07-19 17:17:46 +0530750 wiphy->max_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -0700751
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +0530752 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
753
Jeff Johnson295189b2012-06-20 16:38:30 -0700754 /* Supports STATION & AD-HOC modes right now */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530755 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -0700756 | BIT(NL80211_IFTYPE_ADHOC)
Jeff Johnson295189b2012-06-20 16:38:30 -0700757 | BIT(NL80211_IFTYPE_P2P_CLIENT)
758 | BIT(NL80211_IFTYPE_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -0700759 | BIT(NL80211_IFTYPE_AP);
760
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800762 if( pCfg->enableMCC )
763 {
764 /* Currently, supports up to two channels */
765 wlan_hdd_iface_combination.num_different_channels = 2;
766
767 if( !pCfg->allowMCCGODiffBI )
768 wlan_hdd_iface_combination.beacon_int_infra_match = true;
769
770 }
771 wiphy->iface_combinations = &wlan_hdd_iface_combination;
772 wiphy->n_iface_combinations = 1;
773#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800774
Jeff Johnson295189b2012-06-20 16:38:30 -0700775 /* Before registering we need to update the ht capabilitied based
776 * on ini values*/
777 if( !pCfg->ShortGI20MhzEnable )
778 {
779 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
780 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
781 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
782 }
783
784 if( !pCfg->ShortGI40MhzEnable )
785 {
786 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
787 }
788
789 if( !pCfg->nChannelBondingMode5GHz )
790 {
791 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
792 }
793
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +0530794 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
795 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
796
797 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
798 {
799
800 if (NULL == wiphy->bands[i])
801 {
802 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
803 __func__, i);
804 continue;
805 }
806
807 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
808 {
809 struct ieee80211_supported_band *band = wiphy->bands[i];
810
811 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
812 {
813 // Enable social channels for P2P
814 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
815 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
816 else
817 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
818 continue;
819 }
820 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
821 {
822 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
823 continue;
824 }
825 }
Jeff Johnson295189b2012-06-20 16:38:30 -0700826 }
827 /*Initialise the supported cipher suite details*/
828 wiphy->cipher_suites = hdd_cipher_suites;
829 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
830
831 /*signal strength in mBm (100*dBm) */
832 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
833
834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnson295189b2012-06-20 16:38:30 -0700835 wiphy->max_remain_on_channel_duration = 1000;
836#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700837
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800838 wiphy->n_vendor_commands = 0;
839 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
840 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
841
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530842 EXIT();
843 return 0;
844}
845
846/* In this function we are registering wiphy. */
847int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
848{
849 ENTER();
850 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700851 if (0 > wiphy_register(wiphy))
852 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530853 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -0700854 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
855 return -EIO;
856 }
857
858 EXIT();
859 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530860}
Jeff Johnson295189b2012-06-20 16:38:30 -0700861
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530862/* In this function we are updating channel list when,
863 regulatory domain is FCC and country code is US.
864 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
865 As per FCC smart phone is not a indoor device.
866 GO should not opeate on indoor channels */
867void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
868{
869 int j;
870 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
871 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
872 //Default counrtycode from NV at the time of wiphy initialization.
873 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
874 &defaultCountryCode[0]))
875 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -0700876 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530877 }
878 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
879 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +0530880 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
881 {
882 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
883 return;
884 }
885 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
886 {
887 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
888 // Mark UNII -1 band channel as passive
889 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
890 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
891 }
892 }
893}
894
Jeff Johnson295189b2012-06-20 16:38:30 -0700895/* In this function we will do all post VOS start initialization.
896 In this function we will register for all frame in which supplicant
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530897 is interested.
Jeff Johnson295189b2012-06-20 16:38:30 -0700898*/
899void wlan_hdd_cfg80211_post_voss_start(hdd_adapter_t* pAdapter)
900{
Jeff Johnson295189b2012-06-20 16:38:30 -0700901 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
902 /* Register for all P2P action, public action etc frames */
903 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
904
Jeff Johnsone7245742012-09-05 17:12:55 -0700905 ENTER();
906
Jeff Johnson295189b2012-06-20 16:38:30 -0700907 /* Right now we are registering these frame when driver is getting
908 initialized. Once we will move to 2.6.37 kernel, in which we have
909 frame register ops, we will move this code as a part of that */
910 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530911 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -0700912 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
913
914 /* GAS Initial Response */
915 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
916 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530917
Jeff Johnson295189b2012-06-20 16:38:30 -0700918 /* GAS Comeback Request */
919 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
920 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
921
922 /* GAS Comeback Response */
923 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
924 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
925
926 /* P2P Public Action */
927 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530928 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700929 P2P_PUBLIC_ACTION_FRAME_SIZE );
930
931 /* P2P Action */
932 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
933 (v_U8_t*)P2P_ACTION_FRAME,
934 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700935
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +0530936 /* WNM BSS Transition Request frame */
937 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
938 (v_U8_t*)WNM_BSS_ACTION_FRAME,
939 WNM_BSS_ACTION_FRAME_SIZE );
940
Chet Lanctot186b5732013-03-18 10:26:30 -0700941#ifdef WLAN_FEATURE_11W
942 /* SA Query Response Action Frame */
943 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
944 (v_U8_t*)SA_QUERY_FRAME_RSP,
945 SA_QUERY_FRAME_RSP_SIZE );
946#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700947}
948
949void wlan_hdd_cfg80211_pre_voss_stop(hdd_adapter_t* pAdapter)
950{
Jeff Johnson295189b2012-06-20 16:38:30 -0700951 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
952 /* Register for all P2P action, public action etc frames */
953 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
954
Jeff Johnsone7245742012-09-05 17:12:55 -0700955 ENTER();
956
Jeff Johnson295189b2012-06-20 16:38:30 -0700957 /* Right now we are registering these frame when driver is getting
958 initialized. Once we will move to 2.6.37 kernel, in which we have
959 frame register ops, we will move this code as a part of that */
960 /* GAS Initial Request */
961
962 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
963 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
964
965 /* GAS Initial Response */
966 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
967 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530968
Jeff Johnson295189b2012-06-20 16:38:30 -0700969 /* GAS Comeback Request */
970 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
971 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
972
973 /* GAS Comeback Response */
974 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
975 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
976
977 /* P2P Public Action */
978 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530979 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -0700980 P2P_PUBLIC_ACTION_FRAME_SIZE );
981
982 /* P2P Action */
983 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
984 (v_U8_t*)P2P_ACTION_FRAME,
985 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -0700986
987#ifdef WLAN_FEATURE_11W
988 /* SA Query Response Action Frame */
989 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
990 (v_U8_t*)SA_QUERY_FRAME_RSP,
991 SA_QUERY_FRAME_RSP_SIZE );
992#endif /* WLAN_FEATURE_11W */
Jeff Johnson295189b2012-06-20 16:38:30 -0700993}
994
995#ifdef FEATURE_WLAN_WAPI
996void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
997 const u8 *mac_addr, u8 *key , int key_Len)
998{
999 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1000 tCsrRoamSetKey setKey;
1001 v_BOOL_t isConnected = TRUE;
1002 int status = 0;
1003 v_U32_t roamId= 0xFF;
1004 tANI_U8 *pKeyPtr = NULL;
1005 int n = 0;
1006
Arif Hussain6d2a3322013-11-17 19:50:10 -08001007 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07001008 __func__,pAdapter->device_mode);
1009
Gopichand Nakkalae7480202013-02-11 15:24:22 +05301010 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07001011 setKey.keyId = key_index; // Store Key ID
1012 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
1013 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
1014 setKey.paeRole = 0 ; // the PAE role
1015 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
1016 {
1017 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
1018 }
1019 else
1020 {
1021 isConnected = hdd_connIsConnected(pHddStaCtx);
1022 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
1023 }
1024 setKey.keyLength = key_Len;
1025 pKeyPtr = setKey.Key;
1026 memcpy( pKeyPtr, key, key_Len);
1027
Arif Hussain6d2a3322013-11-17 19:50:10 -08001028 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07001029 __func__, key_Len);
1030 for (n = 0 ; n < key_Len; n++)
1031 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
1032 __func__,n,setKey.Key[n]);
1033
1034 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
1035 if ( isConnected )
1036 {
1037 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
1038 pAdapter->sessionId, &setKey, &roamId );
1039 }
1040 if ( status != 0 )
1041 {
1042 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1043 "[%4d] sme_RoamSetKey returned ERROR status= %d",
1044 __LINE__, status );
1045 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1046 }
1047}
1048#endif /* FEATURE_WLAN_WAPI*/
1049
1050#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301051int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07001052 beacon_data_t **ppBeacon,
1053 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001054#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301055int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001056 beacon_data_t **ppBeacon,
1057 struct cfg80211_beacon_data *params,
1058 int dtim_period)
1059#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301060{
Jeff Johnson295189b2012-06-20 16:38:30 -07001061 int size;
1062 beacon_data_t *beacon = NULL;
1063 beacon_data_t *old = NULL;
1064 int head_len,tail_len;
1065
Jeff Johnsone7245742012-09-05 17:12:55 -07001066 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07001067 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301068 {
1069 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1070 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001071 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301072 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001073
1074 old = pAdapter->sessionCtx.ap.beacon;
1075
1076 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301077 {
1078 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1079 FL("session(%d) old and new heads points to NULL"),
1080 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001081 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301082 }
1083
1084 if (params->tail && !params->tail_len)
1085 {
1086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1087 FL("tail_len is zero but tail is not NULL"));
1088 return -EINVAL;
1089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001090
Jeff Johnson295189b2012-06-20 16:38:30 -07001091#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
1092 /* Kernel 3.0 is not updating dtim_period for set beacon */
1093 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301094 {
1095 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1096 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001097 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301098 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001099#endif
1100
1101 if(params->head)
1102 head_len = params->head_len;
1103 else
1104 head_len = old->head_len;
1105
1106 if(params->tail || !old)
1107 tail_len = params->tail_len;
1108 else
1109 tail_len = old->tail_len;
1110
1111 size = sizeof(beacon_data_t) + head_len + tail_len;
1112
1113 beacon = kzalloc(size, GFP_KERNEL);
1114
1115 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301116 {
1117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1118 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07001119 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001121
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001122#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001123 if(params->dtim_period || !old )
1124 beacon->dtim_period = params->dtim_period;
1125 else
1126 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001127#else
1128 if(dtim_period || !old )
1129 beacon->dtim_period = dtim_period;
1130 else
1131 beacon->dtim_period = old->dtim_period;
1132#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301133
Jeff Johnson295189b2012-06-20 16:38:30 -07001134 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
1135 beacon->tail = beacon->head + head_len;
1136 beacon->head_len = head_len;
1137 beacon->tail_len = tail_len;
1138
1139 if(params->head) {
1140 memcpy (beacon->head,params->head,beacon->head_len);
1141 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301142 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07001143 if(old)
1144 memcpy (beacon->head,old->head,beacon->head_len);
1145 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301146
Jeff Johnson295189b2012-06-20 16:38:30 -07001147 if(params->tail) {
1148 memcpy (beacon->tail,params->tail,beacon->tail_len);
1149 }
1150 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301151 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 memcpy (beacon->tail,old->tail,beacon->tail_len);
1153 }
1154
1155 *ppBeacon = beacon;
1156
1157 kfree(old);
1158
1159 return 0;
1160
1161}
Jeff Johnson295189b2012-06-20 16:38:30 -07001162
1163v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(v_U8_t *pIes, int length, v_U8_t eid)
1164{
1165 int left = length;
1166 v_U8_t *ptr = pIes;
1167 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301168
Jeff Johnson295189b2012-06-20 16:38:30 -07001169 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301170 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001171 elem_id = ptr[0];
1172 elem_len = ptr[1];
1173 left -= 2;
1174 if(elem_len > left)
1175 {
1176 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001177 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001178 eid,elem_len,left);
1179 return NULL;
1180 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301181 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07001182 {
1183 return ptr;
1184 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301185
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 left -= elem_len;
1187 ptr += (elem_len + 2);
1188 }
1189 return NULL;
1190}
1191
Jeff Johnson295189b2012-06-20 16:38:30 -07001192/* Check if rate is 11g rate or not */
1193static int wlan_hdd_rate_is_11g(u8 rate)
1194{
Sanjay Devnani28322e22013-06-21 16:13:40 -07001195 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07001196 u8 i;
1197 for (i = 0; i < 8; i++)
1198 {
1199 if(rate == gRateArray[i])
1200 return TRUE;
1201 }
1202 return FALSE;
1203}
1204
1205/* Check for 11g rate and set proper 11g only mode */
1206static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
1207 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
1208{
1209 u8 i, num_rates = pIe[0];
1210
1211 pIe += 1;
1212 for ( i = 0; i < num_rates; i++)
1213 {
1214 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
1215 {
1216 /* If rate set have 11g rate than change the mode to 11G */
1217 *pSapHw_mode = eSAP_DOT11_MODE_11g;
1218 if (pIe[i] & BASIC_RATE_MASK)
1219 {
1220 /* If we have 11g rate as basic rate, it means mode
1221 is 11g only mode.
1222 */
1223 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
1224 *pCheckRatesfor11g = FALSE;
1225 }
1226 }
1227 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
1228 {
1229 *require_ht = TRUE;
1230 }
1231 }
1232 return;
1233}
1234
1235static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
1236{
1237 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1238 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1239 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1240 u8 checkRatesfor11g = TRUE;
1241 u8 require_ht = FALSE;
1242 u8 *pIe=NULL;
1243
1244 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
1245
1246 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
1247 pBeacon->head_len, WLAN_EID_SUPP_RATES);
1248 if (pIe != NULL)
1249 {
1250 pIe += 1;
1251 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1252 &pConfig->SapHw_mode);
1253 }
1254
1255 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1256 WLAN_EID_EXT_SUPP_RATES);
1257 if (pIe != NULL)
1258 {
1259
1260 pIe += 1;
1261 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
1262 &pConfig->SapHw_mode);
1263 }
1264
1265 if( pConfig->channel > 14 )
1266 {
1267 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
1268 }
1269
1270 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
1271 WLAN_EID_HT_CAPABILITY);
1272
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301273 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001274 {
1275 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
1276 if(require_ht)
1277 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
1278 }
1279}
1280
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301281static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
1282 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
1283{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001284 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301285 v_U8_t *pIe = NULL;
1286 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1287
1288 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
1289 pBeacon->tail, pBeacon->tail_len);
1290
1291 if (pIe)
1292 {
1293 ielen = pIe[1] + 2;
1294 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1295 {
1296 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
1297 }
1298 else
1299 {
1300 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
1301 return -EINVAL;
1302 }
1303 *total_ielen += ielen;
1304 }
1305 return 0;
1306}
1307
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001308static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
1309 v_U8_t *genie, v_U8_t *total_ielen)
1310{
1311 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1312 int left = pBeacon->tail_len;
1313 v_U8_t *ptr = pBeacon->tail;
1314 v_U8_t elem_id, elem_len;
1315 v_U16_t ielen = 0;
1316
1317 if ( NULL == ptr || 0 == left )
1318 return;
1319
1320 while (left >= 2)
1321 {
1322 elem_id = ptr[0];
1323 elem_len = ptr[1];
1324 left -= 2;
1325 if (elem_len > left)
1326 {
1327 hddLog( VOS_TRACE_LEVEL_ERROR,
1328 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
1329 elem_id, elem_len, left);
1330 return;
1331 }
1332 if (IE_EID_VENDOR == elem_id)
1333 {
1334 /* skipping the VSIE's which we don't want to include or
1335 * it will be included by existing code
1336 */
1337 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
1338#ifdef WLAN_FEATURE_WFD
1339 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
1340#endif
1341 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1342 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1343 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
1344 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
1345 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
1346 {
1347 ielen = ptr[1] + 2;
1348 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
1349 {
1350 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
1351 *total_ielen += ielen;
1352 }
1353 else
1354 {
1355 hddLog( VOS_TRACE_LEVEL_ERROR,
1356 "IE Length is too big "
1357 "IEs eid=%d elem_len=%d total_ie_lent=%d",
1358 elem_id, elem_len, *total_ielen);
1359 }
1360 }
1361 }
1362
1363 left -= elem_len;
1364 ptr += (elem_len + 2);
1365 }
1366 return;
1367}
1368
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001369#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07001370static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1371 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001372#else
1373static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
1374 struct cfg80211_beacon_data *params)
1375#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001376{
1377 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301378 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001379 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07001380 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07001381
1382 genie = vos_mem_malloc(MAX_GENIE_LEN);
1383
1384 if(genie == NULL) {
1385
1386 return -ENOMEM;
1387 }
1388
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301389 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1390 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001391 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301392 hddLog(LOGE,
1393 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301394 ret = -EINVAL;
1395 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001396 }
1397
1398#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301399 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1400 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
1401 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301402 hddLog(LOGE,
1403 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301404 ret = -EINVAL;
1405 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001406 }
1407#endif
1408
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301409 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
1410 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07001411 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05301412 hddLog(LOGE,
1413 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301414 ret = -EINVAL;
1415 goto done;
1416 }
1417
1418 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
1419 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07001420 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07001421 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001422
1423 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1424 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
1425 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
1426 {
1427 hddLog(LOGE,
1428 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001429 ret = -EINVAL;
1430 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001431 }
1432
1433 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1434 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
1435 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1436 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1437 ==eHAL_STATUS_FAILURE)
1438 {
1439 hddLog(LOGE,
1440 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001441 ret = -EINVAL;
1442 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001443 }
1444
1445 // Added for ProResp IE
1446 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
1447 {
1448 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
1449 u8 probe_rsp_ie_len[3] = {0};
1450 u8 counter = 0;
1451 /* Check Probe Resp Length if it is greater then 255 then Store
1452 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
1453 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
1454 Store More then 255 bytes into One Variable.
1455 */
1456 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
1457 {
1458 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
1459 {
1460 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
1461 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
1462 }
1463 else
1464 {
1465 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
1466 rem_probe_resp_ie_len = 0;
1467 }
1468 }
1469
1470 rem_probe_resp_ie_len = 0;
1471
1472 if (probe_rsp_ie_len[0] > 0)
1473 {
1474 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1475 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
1476 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1477 probe_rsp_ie_len[0], NULL,
1478 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1479 {
1480 hddLog(LOGE,
1481 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001482 ret = -EINVAL;
1483 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001484 }
1485 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
1486 }
1487
1488 if (probe_rsp_ie_len[1] > 0)
1489 {
1490 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1491 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
1492 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1493 probe_rsp_ie_len[1], NULL,
1494 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1495 {
1496 hddLog(LOGE,
1497 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001498 ret = -EINVAL;
1499 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001500 }
1501 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
1502 }
1503
1504 if (probe_rsp_ie_len[2] > 0)
1505 {
1506 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1507 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
1508 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
1509 probe_rsp_ie_len[2], NULL,
1510 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1511 {
1512 hddLog(LOGE,
1513 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001514 ret = -EINVAL;
1515 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001516 }
1517 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
1518 }
1519
1520 if (probe_rsp_ie_len[1] == 0 )
1521 {
1522 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1523 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
1524 eANI_BOOLEAN_FALSE) )
1525 {
1526 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001527 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001528 }
1529 }
1530
1531 if (probe_rsp_ie_len[2] == 0 )
1532 {
1533 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1534 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
1535 eANI_BOOLEAN_FALSE) )
1536 {
1537 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001538 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001539 }
1540 }
1541
1542 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1543 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
1544 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1545 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1546 == eHAL_STATUS_FAILURE)
1547 {
1548 hddLog(LOGE,
1549 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001550 ret = -EINVAL;
1551 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001552 }
1553 }
1554 else
1555 {
1556 // Reset WNI_CFG_PROBE_RSP Flags
1557 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
1558
1559 hddLog(VOS_TRACE_LEVEL_INFO,
1560 "%s: No Probe Response IE received in set beacon",
1561 __func__);
1562 }
1563
1564 // Added for AssocResp IE
1565 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
1566 {
1567 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1568 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
1569 params->assocresp_ies_len, NULL,
1570 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
1571 {
1572 hddLog(LOGE,
1573 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001574 ret = -EINVAL;
1575 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001576 }
1577
1578 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1579 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
1580 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
1581 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
1582 == eHAL_STATUS_FAILURE)
1583 {
1584 hddLog(LOGE,
1585 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07001586 ret = -EINVAL;
1587 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07001588 }
1589 }
1590 else
1591 {
1592 hddLog(VOS_TRACE_LEVEL_INFO,
1593 "%s: No Assoc Response IE received in set beacon",
1594 __func__);
1595
1596 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
1597 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
1598 eANI_BOOLEAN_FALSE) )
1599 {
1600 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001601 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07001602 }
1603 }
1604
Jeff Johnsone7245742012-09-05 17:12:55 -07001605done:
Jeff Johnson295189b2012-06-20 16:38:30 -07001606 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05301607 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07001608}
Jeff Johnson295189b2012-06-20 16:38:30 -07001609
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301610/*
Jeff Johnson295189b2012-06-20 16:38:30 -07001611 * FUNCTION: wlan_hdd_validate_operation_channel
1612 * called by wlan_hdd_cfg80211_start_bss() and
1613 * wlan_hdd_cfg80211_set_channel()
1614 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301615 * channel list.
1616 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07001617VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001618{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301619
Jeff Johnson295189b2012-06-20 16:38:30 -07001620 v_U32_t num_ch = 0;
1621 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
1622 u32 indx = 0;
1623 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301624 v_U8_t fValidChannel = FALSE, count = 0;
1625 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301626
Jeff Johnson295189b2012-06-20 16:38:30 -07001627 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1628
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301629 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07001630 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301631 /* Validate the channel */
1632 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07001633 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301634 if ( channel == rfChannels[count].channelNum )
1635 {
1636 fValidChannel = TRUE;
1637 break;
1638 }
1639 }
1640 if (fValidChannel != TRUE)
1641 {
1642 hddLog(VOS_TRACE_LEVEL_ERROR,
1643 "%s: Invalid Channel [%d]", __func__, channel);
1644 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07001645 }
1646 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301647 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001648 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05301649 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
1650 valid_ch, &num_ch))
1651 {
1652 hddLog(VOS_TRACE_LEVEL_ERROR,
1653 "%s: failed to get valid channel list", __func__);
1654 return VOS_STATUS_E_FAILURE;
1655 }
1656 for (indx = 0; indx < num_ch; indx++)
1657 {
1658 if (channel == valid_ch[indx])
1659 {
1660 break;
1661 }
1662 }
1663
1664 if (indx >= num_ch)
1665 {
1666 hddLog(VOS_TRACE_LEVEL_ERROR,
1667 "%s: Invalid Channel [%d]", __func__, channel);
1668 return VOS_STATUS_E_FAILURE;
1669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001670 }
1671 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301672
Jeff Johnson295189b2012-06-20 16:38:30 -07001673}
1674
Viral Modi3a32cc52013-02-08 11:14:52 -08001675/**
1676 * FUNCTION: wlan_hdd_cfg80211_set_channel
1677 * This function is used to set the channel number
1678 */
1679static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
1680 struct ieee80211_channel *chan,
1681 enum nl80211_channel_type channel_type
1682 )
1683{
1684 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07001685 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08001686 hdd_adapter_t *pAdapter = NULL;
1687 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301688 hdd_context_t *pHddCtx;
1689 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001690
1691 ENTER();
1692
1693 if( NULL == dev )
1694 {
1695 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001696 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001697 return -ENODEV;
1698 }
1699 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
1700
1701 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001702 "%s: device_mode = %d freq = %d", __func__,
Viral Modi3a32cc52013-02-08 11:14:52 -08001703 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301704
1705 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1706 status = wlan_hdd_validate_context(pHddCtx);
1707
1708 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08001709 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1711 "%s: HDD context is not valid", __func__);
1712 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001713 }
1714
1715 /*
1716 * Do freq to chan conversion
1717 * TODO: for 11a
1718 */
1719
1720 channel = ieee80211_frequency_to_channel(freq);
1721
1722 /* Check freq range */
1723 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
1724 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
1725 {
1726 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001727 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08001728 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
1729 WNI_CFG_CURRENT_CHANNEL_STAMAX);
1730 return -EINVAL;
1731 }
1732
1733 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
1734
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05301735 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
1736 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08001737 {
1738 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
1739 {
1740 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001741 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08001742 return -EINVAL;
1743 }
1744 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1745 "%s: set channel to [%d] for device mode =%d",
1746 __func__, channel,pAdapter->device_mode);
1747 }
1748 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08001749 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08001750 )
1751 {
1752 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1753 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
1754 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1755
1756 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
1757 {
1758 /* Link is up then return cant set channel*/
1759 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001760 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08001761 return -EINVAL;
1762 }
1763
1764 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
1765 pHddStaCtx->conn_info.operationChannel = channel;
1766 pRoamProfile->ChannelInfo.ChannelList =
1767 &pHddStaCtx->conn_info.operationChannel;
1768 }
1769 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08001770 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08001771 )
1772 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301773 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
1774 {
1775 if(VOS_STATUS_SUCCESS !=
1776 wlan_hdd_validate_operation_channel(pAdapter,channel))
1777 {
1778 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001779 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301780 return -EINVAL;
1781 }
1782 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1783 }
1784 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08001785 {
1786 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
1787
1788 /* If auto channel selection is configured as enable/ 1 then ignore
1789 channel set by supplicant
1790 */
1791 if ( cfg_param->apAutoChannelSelection )
1792 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301793 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
1794 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08001795 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
1796 "%s: set channel to auto channel (0) for device mode =%d",
1797 __func__, pAdapter->device_mode);
1798 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301799 else
1800 {
1801 if(VOS_STATUS_SUCCESS !=
1802 wlan_hdd_validate_operation_channel(pAdapter,channel))
1803 {
1804 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001805 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05301806 return -EINVAL;
1807 }
1808 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
1809 }
Viral Modi3a32cc52013-02-08 11:14:52 -08001810 }
1811 }
1812 else
1813 {
1814 hddLog(VOS_TRACE_LEVEL_FATAL,
1815 "%s: Invalid device mode failed to set valid channel", __func__);
1816 return -EINVAL;
1817 }
1818 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05301819 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08001820}
1821
Jeff Johnson295189b2012-06-20 16:38:30 -07001822#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
1823static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1824 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001825#else
1826static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
1827 struct cfg80211_beacon_data *params,
1828 const u8 *ssid, size_t ssid_len,
1829 enum nl80211_hidden_ssid hidden_ssid)
1830#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001831{
1832 tsap_Config_t *pConfig;
1833 beacon_data_t *pBeacon = NULL;
1834 struct ieee80211_mgmt *pMgmt_frame;
1835 v_U8_t *pIe=NULL;
1836 v_U16_t capab_info;
1837 eCsrAuthType RSNAuthType;
1838 eCsrEncryptionType RSNEncryptType;
1839 eCsrEncryptionType mcRSNEncryptType;
1840 int status = VOS_STATUS_SUCCESS;
1841 tpWLAN_SAPEventCB pSapEventCallback;
1842 hdd_hostapd_state_t *pHostapdState;
1843 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
1844 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301845 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001846 struct qc_mac_acl_entry *acl_entry = NULL;
1847 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08001848 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07001849
1850 ENTER();
1851
1852 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
1853
1854 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
1855
1856 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
1857
1858 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
1859
1860 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
1861
1862 //channel is already set in the set_channel Call back
1863 //pConfig->channel = pCommitConfig->channel;
1864
1865 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301866 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07001867 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
1868
1869 pConfig->dtim_period = pBeacon->dtim_period;
1870
Arif Hussain6d2a3322013-11-17 19:50:10 -08001871 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07001872 pConfig->dtim_period);
1873
1874
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08001875 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07001876 {
1877 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001878 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05301879 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
1880 {
1881 tANI_BOOLEAN restartNeeded;
1882 pConfig->ieee80211d = 1;
1883 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
1884 sme_setRegInfo(hHal, pConfig->countryCode);
1885 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
1886 }
1887 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07001888 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07001889 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07001890 pConfig->ieee80211d = 1;
1891 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
1892 sme_setRegInfo(hHal, pConfig->countryCode);
1893 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07001894 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001895 else
1896 {
1897 pConfig->ieee80211d = 0;
1898 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301899 /*
1900 * If auto channel is configured i.e. channel is 0,
1901 * so skip channel validation.
1902 */
1903 if( AUTO_CHANNEL_SELECT != pConfig->channel )
1904 {
1905 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
1906 {
1907 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08001908 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05301909 return -EINVAL;
1910 }
1911 }
1912 else
1913 {
1914 if(1 != pHddCtx->is_dynamic_channel_range_set)
1915 {
1916 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
1917 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
1918 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
1919 }
1920 pHddCtx->is_dynamic_channel_range_set = 0;
1921 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001922 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07001923 else
Jeff Johnson295189b2012-06-20 16:38:30 -07001924 {
1925 pConfig->ieee80211d = 0;
1926 }
1927 pConfig->authType = eSAP_AUTO_SWITCH;
1928
1929 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301930
1931 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07001932 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
1933
1934 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
1935
1936 /*Set wps station to configured*/
1937 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
1938
1939 if(pIe)
1940 {
1941 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
1942 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08001943 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07001944 return -EINVAL;
1945 }
1946 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
1947 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07001948 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07001949 /* Check 15 bit of WPS IE as it contain information for wps state
1950 * WPS state
1951 */
1952 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
1953 {
1954 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
1955 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
1956 {
1957 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
1958 }
1959 }
1960 }
1961 else
1962 {
1963 pConfig->wps_state = SAP_WPS_DISABLED;
1964 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301965 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07001966
1967 pConfig->RSNWPAReqIELength = 0;
1968 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301969 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07001970 WLAN_EID_RSN);
1971 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301972 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001973 pConfig->RSNWPAReqIELength = pIe[1] + 2;
1974 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
1975 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301976 /* The actual processing may eventually be more extensive than
1977 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07001978 * by the app.
1979 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301980 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07001981 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
1982 &RSNEncryptType,
1983 &mcRSNEncryptType,
1984 &RSNAuthType,
1985 pConfig->pRSNWPAReqIE[1]+2,
1986 pConfig->pRSNWPAReqIE );
1987
1988 if( VOS_STATUS_SUCCESS == status )
1989 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05301990 /* Now copy over all the security attributes you have
1991 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07001992 * */
1993 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
1994 pConfig->mcRSNEncryptType = mcRSNEncryptType;
1995 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
1996 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05301997 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08001998 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07001999 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2000 }
2001 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302002
Jeff Johnson295189b2012-06-20 16:38:30 -07002003 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2004 pBeacon->tail, pBeacon->tail_len);
2005
2006 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
2007 {
2008 if (pConfig->pRSNWPAReqIE)
2009 {
2010 /*Mixed mode WPA/WPA2*/
2011 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
2012 pConfig->RSNWPAReqIELength += pIe[1] + 2;
2013 }
2014 else
2015 {
2016 pConfig->RSNWPAReqIELength = pIe[1] + 2;
2017 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
2018 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302019 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07002020 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
2021 &RSNEncryptType,
2022 &mcRSNEncryptType,
2023 &RSNAuthType,
2024 pConfig->pRSNWPAReqIE[1]+2,
2025 pConfig->pRSNWPAReqIE );
2026
2027 if( VOS_STATUS_SUCCESS == status )
2028 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302029 /* Now copy over all the security attributes you have
2030 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07002031 * */
2032 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
2033 pConfig->mcRSNEncryptType = mcRSNEncryptType;
2034 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
2035 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05302036 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08002037 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07002038 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2039 }
2040 }
2041 }
2042
Jeff Johnson4416a782013-03-25 14:17:50 -07002043 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
2044 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
2045 return -EINVAL;
2046 }
2047
Jeff Johnson295189b2012-06-20 16:38:30 -07002048 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
2049
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002050#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002051 if (params->ssid != NULL)
2052 {
2053 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
2054 pConfig->SSIDinfo.ssid.length = params->ssid_len;
2055 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2056 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2057 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002058#else
2059 if (ssid != NULL)
2060 {
2061 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
2062 pConfig->SSIDinfo.ssid.length = ssid_len;
2063 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2064 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
2065 }
2066#endif
2067
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302068 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07002069 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302070
Jeff Johnson295189b2012-06-20 16:38:30 -07002071 /* default value */
2072 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
2073 pConfig->num_accept_mac = 0;
2074 pConfig->num_deny_mac = 0;
2075
2076 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2077 pBeacon->tail, pBeacon->tail_len);
2078
2079 /* pIe for black list is following form:
2080 type : 1 byte
2081 length : 1 byte
2082 OUI : 4 bytes
2083 acl type : 1 byte
2084 no of mac addr in black list: 1 byte
2085 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302086 */
2087 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002088 {
2089 pConfig->SapMacaddr_acl = pIe[6];
2090 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002091 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002092 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302093 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
2094 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002095 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2096 for (i = 0; i < pConfig->num_deny_mac; i++)
2097 {
2098 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2099 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302100 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002101 }
2102 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
2103 pBeacon->tail, pBeacon->tail_len);
2104
2105 /* pIe for white list is following form:
2106 type : 1 byte
2107 length : 1 byte
2108 OUI : 4 bytes
2109 acl type : 1 byte
2110 no of mac addr in white list: 1 byte
2111 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302112 */
2113 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002114 {
2115 pConfig->SapMacaddr_acl = pIe[6];
2116 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08002117 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002118 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302119 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
2120 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002121 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
2122 for (i = 0; i < pConfig->num_accept_mac; i++)
2123 {
2124 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
2125 acl_entry++;
2126 }
2127 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05302128
Jeff Johnson295189b2012-06-20 16:38:30 -07002129 wlan_hdd_set_sapHwmode(pHostapdAdapter);
2130
Jeff Johnsone7245742012-09-05 17:12:55 -07002131#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002132 /* Overwrite the hostapd setting for HW mode only for 11ac.
Kiet Lam0f320422013-11-21 19:29:17 +05302133 * This is valid only if mode is set to 11n in hostapd, either AUTO or
2134 * 11ac in .ini and 11ac is supported by both host and firmware.
2135 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
2136 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002137 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
2138 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302139 (((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_AUTO) ||
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08002140 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac) ||
Kiet Lam0f320422013-11-21 19:29:17 +05302141 ((WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->dot11Mode == eHDD_DOT11_MODE_11ac_ONLY)) &&
2142 (sme_IsFeatureSupportedByDriver(DOT11AC)) && (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07002143 {
2144 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Ravi Joshi83bfaa12013-05-28 22:12:08 -07002145
2146 /* Disable VHT support in 2.4 GHz band */
2147 if (pConfig->channel <= 14 &&
2148 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->enableVhtFor24GHzBand == FALSE)
2149 {
2150 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
2151 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002152 }
2153#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302154
Ravi Joshiaeb7d9e2013-05-02 12:28:14 -07002155 if ( AUTO_CHANNEL_SELECT != pConfig->channel )
2156 {
2157 sme_SelectCBMode(hHal,
2158 sapConvertSapPhyModeToCsrPhyMode(pConfig->SapHw_mode),
2159 pConfig->channel);
2160 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002161 // ht_capab is not what the name conveys,this is used for protection bitmap
2162 pConfig->ht_capab =
2163 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
2164
2165 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
2166 {
2167 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
2168 return -EINVAL;
2169 }
2170
2171 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302172 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07002173 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
2174 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302175 pConfig->obssProtEnabled =
2176 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07002177
Arif Hussain6d2a3322013-11-17 19:50:10 -08002178 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07002179 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08002180 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
2181 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
2182 (int)pConfig->channel);
2183 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
2184 pConfig->SapHw_mode, pConfig->privacy,
2185 pConfig->authType);
2186 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
2187 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
2188 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
2189 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07002190
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302191 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07002192 {
2193 //Bss already started. just return.
2194 //TODO Probably it should update some beacon params.
2195 hddLog( LOGE, "Bss Already started...Ignore the request");
2196 EXIT();
2197 return 0;
2198 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302199
Jeff Johnson295189b2012-06-20 16:38:30 -07002200 pConfig->persona = pHostapdAdapter->device_mode;
2201
2202 pSapEventCallback = hdd_hostapd_SAPEventCB;
2203 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
2204 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
2205 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002206 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002207 return -EINVAL;
2208 }
2209
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302210 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07002211 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
2212
2213 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302214
Jeff Johnson295189b2012-06-20 16:38:30 -07002215 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302216 {
2217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002218 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07002219 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07002220 VOS_ASSERT(0);
2221 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302222
Jeff Johnson295189b2012-06-20 16:38:30 -07002223 //Succesfully started Bss update the state bit.
2224 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
2225
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002226#ifdef WLAN_FEATURE_P2P_DEBUG
2227 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
2228 {
2229 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
2230 {
2231 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2232 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002233 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002234 }
2235 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
2236 {
2237 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
2238 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08002239 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002240 }
2241 }
2242#endif
2243
Jeff Johnson295189b2012-06-20 16:38:30 -07002244 pHostapdState->bCommit = TRUE;
2245 EXIT();
2246
2247 return 0;
2248}
2249
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002250#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302251static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
2252 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07002253 struct beacon_parameters *params)
2254{
2255 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302256 hdd_context_t *pHddCtx;
2257 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002258
2259 ENTER();
2260
Arif Hussain6d2a3322013-11-17 19:50:10 -08002261 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%d",pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002262
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302263 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2264 status = wlan_hdd_validate_context(pHddCtx);
2265
2266 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002267 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2269 "%s: HDD context is not valid", __func__);
2270 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002271 }
2272
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302273 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002274 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002275 )
2276 {
2277 beacon_data_t *old,*new;
2278
2279 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302280
Jeff Johnson295189b2012-06-20 16:38:30 -07002281 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302282 {
2283 hddLog(VOS_TRACE_LEVEL_WARN,
2284 FL("already beacon info added to session(%d)"),
2285 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002286 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302287 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002288
2289 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2290
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302291 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07002292 {
2293 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002294 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002295 return -EINVAL;
2296 }
2297
2298 pAdapter->sessionCtx.ap.beacon = new;
2299
2300 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2301 }
2302
2303 EXIT();
2304 return status;
2305}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302306
2307static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07002308 struct net_device *dev,
2309 struct beacon_parameters *params)
2310{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302311 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302312 hdd_context_t *pHddCtx;
2313 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002314
2315 ENTER();
2316
Arif Hussain6d2a3322013-11-17 19:50:10 -08002317 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002318 __func__,pAdapter->device_mode);
2319
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302320 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2321 status = wlan_hdd_validate_context(pHddCtx);
2322
2323 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002324 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302325 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2326 "%s: HDD context is not valid", __func__);
2327 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002328 }
2329
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302330 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002331 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302332 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002333 {
2334 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302335
Jeff Johnson295189b2012-06-20 16:38:30 -07002336 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302337
Jeff Johnson295189b2012-06-20 16:38:30 -07002338 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302339 {
2340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2341 FL("session(%d) old and new heads points to NULL"),
2342 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002343 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002345
2346 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
2347
2348 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302349 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002350 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002351 return -EINVAL;
2352 }
2353
2354 pAdapter->sessionCtx.ap.beacon = new;
2355
2356 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
2357 }
2358
2359 EXIT();
2360 return status;
2361}
2362
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002363#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
2364
2365#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07002366static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
2367 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002368#else
2369static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
2370 struct net_device *dev)
2371#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002372{
2373 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07002374 hdd_context_t *pHddCtx = NULL;
2375 hdd_scaninfo_t *pScanInfo = NULL;
2376 hdd_adapter_t *staAdapter = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302377 VOS_STATUS status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002378
2379 ENTER();
2380
2381 if (NULL == pAdapter)
2382 {
2383 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07002384 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002385 return -ENODEV;
2386 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002387
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302388 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2389 status = wlan_hdd_validate_context(pHddCtx);
2390
2391 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002392 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2394 "%s: HDD context is not valid", __func__);
2395 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07002396 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002397
2398 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_INFRA_STATION);
2399 if (NULL == staAdapter)
2400 {
2401 staAdapter = hdd_get_adapter(pAdapter->pHddCtx, WLAN_HDD_P2P_CLIENT);
2402 if (NULL == staAdapter)
2403 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
2405 "%s: HDD adapter context for STA/P2P-CLI is Null",
2406 __func__);
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07002407 }
2408 }
2409
2410 pScanInfo = &pHddCtx->scan_info;
2411
Arif Hussain6d2a3322013-11-17 19:50:10 -08002412 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002413 __func__,pAdapter->device_mode);
2414
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002415 if ((pScanInfo != NULL) && pScanInfo->mScanPending && staAdapter)
Jeff Johnsone7245742012-09-05 17:12:55 -07002416 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302417 long ret;
2418
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002419 INIT_COMPLETION(pScanInfo->abortscan_event_var);
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05302420 hdd_abort_mac_scan(staAdapter->pHddCtx, pAdapter->sessionId,
2421 eCSR_SCAN_ABORT_DEFAULT);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302422 ret = wait_for_completion_interruptible_timeout(
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08002423 &pScanInfo->abortscan_event_var,
Jeff Johnsone7245742012-09-05 17:12:55 -07002424 msecs_to_jiffies(WLAN_WAIT_TIME_ABORTSCAN));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302425 if (ret <= 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07002426 {
Rajesh Chauhan52d885b2013-11-01 10:54:25 -07002427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302428 FL("Timeout occurred while waiting for abortscan %ld"),
2429 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002430
2431 if (pHddCtx->isLogpInProgress)
2432 {
2433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2434 "%s: LOGP in Progress. Ignore!!!", __func__);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302435
2436 VOS_ASSERT(pScanInfo->mScanPending);
Yue Ma4f55ef32014-01-23 16:45:33 -08002437 return -EAGAIN;
2438 }
Jeff Johnsone7245742012-09-05 17:12:55 -07002439 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07002440 }
2441 }
2442
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05302443 hdd_hostapd_stop(dev);
2444
Jeff Johnson295189b2012-06-20 16:38:30 -07002445 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002446 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07002447 )
2448 {
2449 beacon_data_t *old;
2450
2451 old = pAdapter->sessionCtx.ap.beacon;
2452
2453 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302454 {
2455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2456 FL("session(%d) beacon data points to NULL"),
2457 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07002458 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302459 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002460
Jeff Johnson295189b2012-06-20 16:38:30 -07002461 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07002462
2463 mutex_lock(&pHddCtx->sap_lock);
2464 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
2465 {
Jeff Johnson4416a782013-03-25 14:17:50 -07002466 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07002467 {
2468 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
2469
2470 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
2471
2472 if (!VOS_IS_STATUS_SUCCESS(status))
2473 {
2474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002475 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07002476 VOS_ASSERT(0);
2477 }
2478 }
2479 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
2480 }
2481 mutex_unlock(&pHddCtx->sap_lock);
2482
2483 if(status != VOS_STATUS_SUCCESS)
2484 {
2485 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002486 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07002487 return -EINVAL;
2488 }
2489
Jeff Johnson4416a782013-03-25 14:17:50 -07002490 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002491 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
2492 ==eHAL_STATUS_FAILURE)
2493 {
2494 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002495 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002496 }
2497
Jeff Johnson4416a782013-03-25 14:17:50 -07002498 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07002499 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
2500 eANI_BOOLEAN_FALSE) )
2501 {
2502 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002503 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07002504 }
2505
2506 // Reset WNI_CFG_PROBE_RSP Flags
2507 wlan_hdd_reset_prob_rspies(pAdapter);
2508
2509 pAdapter->sessionCtx.ap.beacon = NULL;
2510 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07002511#ifdef WLAN_FEATURE_P2P_DEBUG
2512 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
2513 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
2514 {
2515 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
2516 "GO got removed");
2517 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
2518 }
2519#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002520 }
2521 EXIT();
2522 return status;
2523}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002524
2525#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2526
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302527static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
2528 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002529 struct cfg80211_ap_settings *params)
2530{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302531 hdd_adapter_t *pAdapter;
2532 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302533 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002534
2535 ENTER();
2536
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302537 if (NULL == dev)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002538 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302540 "%s: Device is Null", __func__);
2541 return -ENODEV;
2542 }
2543
2544 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2545 if (NULL == pAdapter)
2546 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302547 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302548 "%s: HDD adapter is Null", __func__);
2549 return -ENODEV;
2550 }
2551
2552 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
2553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302554 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302555 "%s: HDD adapter magic is invalid", __func__);
2556 return -ENODEV;
2557 }
2558
2559 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302560 status = wlan_hdd_validate_context(pHddCtx);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302561
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302562 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302563 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302564 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2565 "%s: HDD context is not valid", __func__);
2566 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302567 }
2568
2569 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %d",
2570 __func__, pAdapter->device_mode);
2571
2572 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002573 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002574 )
2575 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302576 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002577
2578 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302579
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002580 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302581 {
2582 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
2583 FL("already beacon info added to session(%d)"),
2584 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002585 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302586 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002587
2588 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, &params->beacon, params->dtim_period);
2589
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302590 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002591 {
2592 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05302593 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002594 return -EINVAL;
2595 }
2596 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08002597#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07002598 wlan_hdd_cfg80211_set_channel(wiphy, dev,
2599#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
2600 params->channel, params->channel_type);
2601#else
2602 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
2603#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08002604#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002605 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
2606 params->ssid_len, params->hidden_ssid);
2607 }
2608
2609 EXIT();
2610 return status;
2611}
2612
2613
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302614static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002615 struct net_device *dev,
2616 struct cfg80211_beacon_data *params)
2617{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302618 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302619 hdd_context_t *pHddCtx;
2620 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002621
2622 ENTER();
2623
Arif Hussain6d2a3322013-11-17 19:50:10 -08002624 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002625 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302626
2627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2628 status = wlan_hdd_validate_context(pHddCtx);
2629
2630 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002631 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302632 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2633 "%s: HDD context is not valid", __func__);
2634 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07002635 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002636
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302637 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002638 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302639 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002640 {
2641 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302642
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002643 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302644
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002645 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302646 {
2647 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2648 FL("session(%d) beacon data points to NULL"),
2649 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002650 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302651 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002652
2653 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
2654
2655 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302656 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002657 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07002658 return -EINVAL;
2659 }
2660
2661 pAdapter->sessionCtx.ap.beacon = new;
2662
2663 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0);
2664 }
2665
2666 EXIT();
2667 return status;
2668}
2669
2670#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
2671
Jeff Johnson295189b2012-06-20 16:38:30 -07002672
2673static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
2674 struct net_device *dev,
2675 struct bss_parameters *params)
2676{
2677 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2678
2679 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302680
Arif Hussain6d2a3322013-11-17 19:50:10 -08002681 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07002682 __func__,pAdapter->device_mode);
2683
2684 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07002685 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302686 )
Jeff Johnson295189b2012-06-20 16:38:30 -07002687 {
2688 /* ap_isolate == -1 means that in change bss, upper layer doesn't
2689 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302690 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07002691 {
2692 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302693 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002694 }
2695
2696 EXIT();
2697 return 0;
2698}
2699
Kiet Lam10841362013-11-01 11:36:50 +05302700/* FUNCTION: wlan_hdd_change_country_code_cd
2701* to wait for contry code completion
2702*/
2703void* wlan_hdd_change_country_code_cb(void *pAdapter)
2704{
2705 hdd_adapter_t *call_back_pAdapter = pAdapter;
2706 complete(&call_back_pAdapter->change_country_code);
2707 return NULL;
2708}
2709
Jeff Johnson295189b2012-06-20 16:38:30 -07002710/*
2711 * FUNCTION: wlan_hdd_cfg80211_change_iface
2712 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
2713 */
2714int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
2715 struct net_device *ndev,
2716 enum nl80211_iftype type,
2717 u32 *flags,
2718 struct vif_params *params
2719 )
2720{
2721 struct wireless_dev *wdev;
2722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002723 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07002724 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002725 tCsrRoamProfile *pRoamProfile = NULL;
2726 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302727 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07002728 eMib_dot11DesiredBssType connectedBssType;
2729 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302730 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07002731
2732 ENTER();
2733
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002734 if (!pAdapter)
2735 {
2736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2737 "%s: Adapter context is null", __func__);
2738 return VOS_STATUS_E_FAILURE;
2739 }
2740
2741 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2742 if (!pHddCtx)
2743 {
2744 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2745 "%s: HDD context is null", __func__);
2746 return VOS_STATUS_E_FAILURE;
2747 }
2748
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302749 status = wlan_hdd_validate_context(pHddCtx);
2750
2751 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07002752 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2754 "%s: HDD context is not valid", __func__);
2755 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07002756 }
2757
2758 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
2759 __func__, pAdapter->device_mode);
2760
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05302761 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07002762 wdev = ndev->ieee80211_ptr;
2763
2764#ifdef WLAN_BTAMP_FEATURE
2765 if((NL80211_IFTYPE_P2P_CLIENT == type)||
2766 (NL80211_IFTYPE_ADHOC == type)||
2767 (NL80211_IFTYPE_AP == type)||
2768 (NL80211_IFTYPE_P2P_GO == type))
2769 {
2770 pHddCtx->isAmpAllowed = VOS_FALSE;
2771 // stop AMP traffic
2772 status = WLANBAP_StopAmp();
2773 if(VOS_STATUS_SUCCESS != status )
2774 {
2775 pHddCtx->isAmpAllowed = VOS_TRUE;
2776 hddLog(VOS_TRACE_LEVEL_FATAL,
2777 "%s: Failed to stop AMP", __func__);
2778 return -EINVAL;
2779 }
2780 }
2781#endif //WLAN_BTAMP_FEATURE
2782 /* Reset the current device mode bit mask*/
2783 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
2784
2785 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07002786 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07002787 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07002788 )
2789 {
2790 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08002791 if (!pWextState)
2792 {
2793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2794 "%s: pWextState is null", __func__);
2795 return VOS_STATUS_E_FAILURE;
2796 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002797 pRoamProfile = &pWextState->roamProfile;
2798 LastBSSType = pRoamProfile->BSSType;
2799
2800 switch (type)
2801 {
2802 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07002803 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07002804 hddLog(VOS_TRACE_LEVEL_INFO,
2805 "%s: setting interface Type to INFRASTRUCTURE", __func__);
2806 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07002807#ifdef WLAN_FEATURE_11AC
2808 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
2809 {
2810 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
2811 }
2812#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302813 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07002814 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07002815 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002816 //Check for sub-string p2p to confirm its a p2p interface
2817 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302818 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002819 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
2820 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
2821 }
2822 else
2823 {
2824 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07002825 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08002826 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302827#ifdef FEATURE_WLAN_TDLS
2828 /* The open adapter for the p2p shall skip initializations in
2829 * tdls_init if the device mode is WLAN_HDD_P2P_DEVICE, for
2830 * TDLS is supported only on WLAN_HDD_P2P_CLIENT. Hence invoke
2831 * tdls_init when the change_iface sets the device mode to
2832 * WLAN_HDD_P2P_CLIENT.
2833 */
2834
2835 if ( pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
2836 {
2837 if (0 != wlan_hdd_tdls_init (pAdapter))
2838 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302839 hddLog(VOS_TRACE_LEVEL_ERROR,
2840 "%s: tdls initialization failed", __func__);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +05302841 return -EINVAL;
2842 }
2843 }
2844#endif
2845
Jeff Johnson295189b2012-06-20 16:38:30 -07002846 break;
2847 case NL80211_IFTYPE_ADHOC:
2848 hddLog(VOS_TRACE_LEVEL_INFO,
2849 "%s: setting interface Type to ADHOC", __func__);
2850 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
2851 pRoamProfile->phyMode =
2852 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07002853 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07002854 wdev->iftype = type;
2855 break;
2856
2857 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07002858 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07002859 {
2860 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2861 "%s: setting interface Type to %s", __func__,
2862 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
2863
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08002864 //Cancel any remain on channel for GO mode
2865 if (NL80211_IFTYPE_P2P_GO == type)
2866 {
2867 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
2868 }
Mohit Khanna0f232092012-09-11 14:46:08 -07002869 if (NL80211_IFTYPE_AP == type)
2870 {
2871 /* As Loading WLAN Driver one interface being created for p2p device
2872 * address. This will take one HW STA and the max number of clients
2873 * that can connect to softAP will be reduced by one. so while changing
2874 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
2875 * interface as it is not required in SoftAP mode.
2876 */
2877
2878 // Get P2P Adapter
2879 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
2880
2881 if (pP2pAdapter)
2882 {
2883 hdd_stop_adapter(pHddCtx, pP2pAdapter);
2884 hdd_deinit_adapter(pHddCtx, pP2pAdapter);
2885 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
2886 }
2887 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302888#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07002889
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302890 /* A Mutex Lock is introduced while changing the mode to
2891 * protect the concurrent access for the Adapters by TDLS
2892 * module.
2893 */
2894 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2895 {
2896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2897 "%s: unable to lock list", __func__);
2898 return -EINVAL;
2899 }
2900#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07002901 //De-init the adapter.
2902 hdd_stop_adapter( pHddCtx, pAdapter );
2903 hdd_deinit_adapter( pHddCtx, pAdapter );
2904 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07002905 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
2906 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302907#ifdef FEATURE_WLAN_TDLS
2908 mutex_unlock(&pHddCtx->tdls_lock);
2909#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07002910
2911 //Disable BMPS and IMPS if enabled
2912 //before starting Go
2913 if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
2914 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05302915 if(VOS_STATUS_E_FAILURE ==
Jeff Johnson32d95a32012-09-10 13:15:23 -07002916 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
2917 {
2918 //Fail to Exit BMPS
2919 VOS_ASSERT(0);
2920 }
2921 }
2922
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002923 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
2924 (pConfig->apRandomBssidEnabled))
2925 {
2926 /* To meet Android requirements create a randomized
2927 MAC address of the form 02:1A:11:Fx:xx:xx */
2928 get_random_bytes(&ndev->dev_addr[3], 3);
2929 ndev->dev_addr[0] = 0x02;
2930 ndev->dev_addr[1] = 0x1A;
2931 ndev->dev_addr[2] = 0x11;
2932 ndev->dev_addr[3] |= 0xF0;
2933 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
2934 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08002935 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
2936 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07002937 }
2938
Jeff Johnson295189b2012-06-20 16:38:30 -07002939 hdd_set_ap_ops( pAdapter->dev );
2940
Kiet Lam10841362013-11-01 11:36:50 +05302941 /* This is for only SAP mode where users can
2942 * control country through ini.
2943 * P2P GO follows station country code
2944 * acquired during the STA scanning. */
2945 if((NL80211_IFTYPE_AP == type) &&
2946 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
2947 {
2948 int status = 0;
2949 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
2950 "%s: setting country code from INI ", __func__);
2951 init_completion(&pAdapter->change_country_code);
2952 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
2953 (void *)(tSmeChangeCountryCallback)
2954 wlan_hdd_change_country_code_cb,
2955 pConfig->apCntryCode, pAdapter,
2956 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05302957 eSIR_FALSE,
2958 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05302959 if (eHAL_STATUS_SUCCESS == status)
2960 {
2961 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302962 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05302963 &pAdapter->change_country_code,
2964 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302965 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05302966 {
2967 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05302968 FL("SME Timed out while setting country code %ld"),
2969 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08002970
2971 if (pHddCtx->isLogpInProgress)
2972 {
2973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2974 "%s: LOGP in Progress. Ignore!!!", __func__);
2975 return -EAGAIN;
2976 }
Kiet Lam10841362013-11-01 11:36:50 +05302977 }
2978 }
2979 else
2980 {
2981 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08002982 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05302983 return -EINVAL;
2984 }
2985 }
Jeff Johnson295189b2012-06-20 16:38:30 -07002986 status = hdd_init_ap_mode(pAdapter);
2987 if(status != VOS_STATUS_SUCCESS)
2988 {
2989 hddLog(VOS_TRACE_LEVEL_FATAL,
2990 "%s: Error initializing the ap mode", __func__);
2991 return -EINVAL;
2992 }
2993 hdd_set_conparam(1);
2994
Jeff Johnson295189b2012-06-20 16:38:30 -07002995 /*interface type changed update in wiphy structure*/
2996 if(wdev)
2997 {
2998 wdev->iftype = type;
2999 pHddCtx->change_iface = type;
3000 }
3001 else
3002 {
3003 hddLog(VOS_TRACE_LEVEL_ERROR,
3004 "%s: ERROR !!!! Wireless dev is NULL", __func__);
3005 return -EINVAL;
3006 }
3007 goto done;
3008 }
3009
3010 default:
3011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3012 __func__);
3013 return -EOPNOTSUPP;
3014 }
3015 }
3016 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003017 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07003018 )
3019 {
3020 switch(type)
3021 {
3022 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07003023 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07003024 case NL80211_IFTYPE_ADHOC:
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303025#ifdef FEATURE_WLAN_TDLS
3026
3027 /* A Mutex Lock is introduced while changing the mode to
3028 * protect the concurrent access for the Adapters by TDLS
3029 * module.
3030 */
3031 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
3032 {
3033 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3034 "%s: unable to lock list", __func__);
3035 return -EINVAL;
3036 }
3037#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07003038 hdd_stop_adapter( pHddCtx, pAdapter );
3039 hdd_deinit_adapter( pHddCtx, pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003040 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08003041 //Check for sub-string p2p to confirm its a p2p interface
3042 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003043 {
3044 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
3045 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
3046 }
3047 else
3048 {
3049 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07003050 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08003051 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003052 hdd_set_conparam(0);
3053 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003054 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
3055 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303056#ifdef FEATURE_WLAN_TDLS
3057 mutex_unlock(&pHddCtx->tdls_lock);
3058#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05303059 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07003060 if( VOS_STATUS_SUCCESS != status )
3061 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07003062 /* In case of JB, for P2P-GO, only change interface will be called,
3063 * This is the right place to enable back bmps_imps()
3064 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05303065 if (pHddCtx->hdd_wlan_suspended)
3066 {
3067 hdd_set_pwrparams(pHddCtx);
3068 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003069 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07003070 goto done;
3071 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07003072 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07003073 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07003074 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
3075 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07003076 goto done;
3077 default:
3078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
3079 __func__);
3080 return -EOPNOTSUPP;
3081
3082 }
3083
3084 }
3085 else
3086 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303087 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%d)",
3088 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003089 return -EOPNOTSUPP;
3090 }
3091
3092
3093 if(pRoamProfile)
3094 {
3095 if ( LastBSSType != pRoamProfile->BSSType )
3096 {
3097 /*interface type changed update in wiphy structure*/
3098 wdev->iftype = type;
3099
3100 /*the BSS mode changed, We need to issue disconnect
3101 if connected or in IBSS disconnect state*/
3102 if ( hdd_connGetConnectedBssType(
3103 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
3104 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
3105 {
3106 /*need to issue a disconnect to CSR.*/
3107 INIT_COMPLETION(pAdapter->disconnect_comp_var);
3108 if( eHAL_STATUS_SUCCESS ==
3109 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
3110 pAdapter->sessionId,
3111 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
3112 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303113 ret = wait_for_completion_interruptible_timeout(
3114 &pAdapter->disconnect_comp_var,
3115 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
3116 if (ret <= 0)
3117 {
3118 hddLog(VOS_TRACE_LEVEL_ERROR,
3119 FL("wait on disconnect_comp_var failed %ld"), ret);
3120 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003121 }
3122 }
3123 }
3124 }
3125
3126done:
3127 /*set bitmask based on updated value*/
3128 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07003129
3130 /* Only STA mode support TM now
3131 * all other mode, TM feature should be disabled */
3132 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
3133 (~VOS_STA & pHddCtx->concurrency_mode) )
3134 {
3135 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
3136 }
3137
Jeff Johnson295189b2012-06-20 16:38:30 -07003138#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303139 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07003140 (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
3141 {
3142 //we are ok to do AMP
3143 pHddCtx->isAmpAllowed = VOS_TRUE;
3144 }
3145#endif //WLAN_BTAMP_FEATURE
3146 EXIT();
3147 return 0;
3148}
3149
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003150#ifdef FEATURE_WLAN_TDLS
3151static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
3152 struct net_device *dev, u8 *mac, bool update, tCsrStaParams *StaParams)
3153{
3154 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3155 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3156 VOS_STATUS status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003157 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303158 long ret;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003159
3160 ENTER();
3161
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303162 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003163 {
3164 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3165 "Invalid arguments");
3166 return -EINVAL;
3167 }
Hoonki Lee27511902013-03-14 18:19:06 -07003168
3169 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
3170 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
3171 {
3172 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3173 "%s: TDLS mode is disabled OR not enabled in FW."
3174 MAC_ADDRESS_STR " Request declined.",
3175 __func__, MAC_ADDR_ARRAY(mac));
3176 return -ENOTSUPP;
3177 }
3178
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003179 if (pHddCtx->isLogpInProgress)
3180 {
3181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3182 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07003183 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003184 return -EBUSY;
3185 }
3186
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303187 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003188
3189 if ( NULL == pTdlsPeer ) {
3190 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3191 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
3192 __func__, MAC_ADDR_ARRAY(mac), update);
3193 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003194 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003195
3196 /* in add station, we accept existing valid staId if there is */
3197 if ((0 == update) &&
3198 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
3199 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003200 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003201 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003202 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003203 " link_status %d. staId %d. add station ignored.",
3204 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
3205 return 0;
3206 }
3207 /* in change station, we accept only when staId is valid */
3208 if ((1 == update) &&
3209 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
3210 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
3211 {
3212 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3213 "%s: " MAC_ADDRESS_STR
3214 " link status %d. staId %d. change station %s.",
3215 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
3216 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
3217 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003218 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003219
3220 /* when others are on-going, we want to change link_status to idle */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303221 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003222 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3224 "%s: " MAC_ADDRESS_STR
3225 " TDLS setup is ongoing. Request declined.",
3226 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003227 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003228 }
3229
3230 /* first to check if we reached to maximum supported TDLS peer.
3231 TODO: for now, return -EPERM looks working fine,
3232 but need to check if any other errno fit into this category.*/
3233 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
3234 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3236 "%s: " MAC_ADDRESS_STR
3237 " TDLS Max peer already connected. Request declined.",
3238 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07003239 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003240 }
3241 else
3242 {
3243 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05303244 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003245 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003246 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3248 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
3249 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003250 return -EPERM;
3251 }
3252 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003253 if (0 == update)
3254 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_CONNECTING);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003255
Jeff Johnsond75fe012013-04-06 10:53:06 -07003256 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303257 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003258 {
3259 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3260 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003261 if(StaParams->htcap_present)
3262 {
3263 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3264 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
3265 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3266 "ht_capa->extended_capabilities: %0x",
3267 StaParams->HTCap.extendedHtCapInfo);
3268 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003269 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3270 "params->capability: %0x",StaParams->capability);
3271 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003272 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07003273 if(StaParams->vhtcap_present)
3274 {
3275 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3276 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
3277 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
3278 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
3279 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003280 {
3281 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003283 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
3284 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
3285 "[%d]: %x ", i, StaParams->supported_rates[i]);
3286 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07003287 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05303288 else if ((1 == update) && (NULL == StaParams))
3289 {
3290 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3291 "%s : update is true, but staParams is NULL. Error!", __func__);
3292 return -EPERM;
3293 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003294
3295 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
3296
3297 if (!update)
3298 {
3299 status = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3300 pAdapter->sessionId, mac);
3301 }
3302 else
3303 {
3304 status = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
3305 pAdapter->sessionId, mac, StaParams);
3306 }
3307
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303308 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003309 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
3310
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303311 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003312 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303314 "%s: timeout waiting for tdls add station indication %ld",
3315 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003316 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003317 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303318
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003319 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
3320 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07003321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003322 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07003323 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003324 }
3325
3326 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07003327
3328error:
3329 wlan_hdd_tdls_set_link_status(pAdapter, mac, eTDLS_LINK_IDLE);
3330 return -EPERM;
3331
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003332}
3333#endif
3334
Jeff Johnson295189b2012-06-20 16:38:30 -07003335static int wlan_hdd_change_station(struct wiphy *wiphy,
3336 struct net_device *dev,
3337 u8 *mac,
3338 struct station_parameters *params)
3339{
3340 VOS_STATUS status = VOS_STATUS_SUCCESS;
3341 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkala29149562013-05-10 21:43:41 +05303342 hdd_context_t *pHddCtx;
3343 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003344 v_MACADDR_t STAMacAddress;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003345#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003346 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003347 tANI_U8 isBufSta = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003348#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07003349 ENTER();
3350
Gopichand Nakkala29149562013-05-10 21:43:41 +05303351 if ((NULL == pAdapter))
3352 {
3353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3354 "invalid adapter ");
3355 return -EINVAL;
3356 }
3357
3358 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3359 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3360
3361 if ((NULL == pHddCtx) || (NULL == pHddStaCtx))
3362 {
3363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
3364 "invalid HDD state or HDD station context");
3365 return -EINVAL;
3366 }
3367
3368 if (pHddCtx->isLogpInProgress)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003369 {
3370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3371 "%s:LOGP in Progress. Ignore!!!", __func__);
3372 return -EAGAIN;
3373 }
3374
Jeff Johnson295189b2012-06-20 16:38:30 -07003375 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
3376
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003377 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
3378 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07003379 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003380 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07003381 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303382 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07003383 WLANTL_STA_AUTHENTICATED);
3384
Gopichand Nakkala29149562013-05-10 21:43:41 +05303385 if (status != VOS_STATUS_SUCCESS)
3386 {
3387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3388 "%s: Not able to change TL state to AUTHENTICATED", __func__);
3389 return -EINVAL;
3390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003391 }
3392 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07003393 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
3394 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05303395#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003396 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
3397 StaParams.capability = params->capability;
3398 StaParams.uapsd_queues = params->uapsd_queues;
3399 StaParams.max_sp = params->max_sp;
3400
3401 if (0 != params->ext_capab_len)
3402 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
3403 sizeof(StaParams.extn_capability));
3404
3405 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003406 {
3407 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003408 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003409 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003410
3411 StaParams.supported_rates_len = params->supported_rates_len;
3412
3413 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
3414 * The supported_rates array , for all the structures propogating till Add Sta
3415 * to the firmware has to be modified , if the supplicant (ieee80211) is
3416 * modified to send more rates.
3417 */
3418
3419 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
3420 */
3421 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
3422 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
3423
3424 if (0 != StaParams.supported_rates_len) {
3425 int i = 0;
3426 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
3427 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003429 "Supported Rates with Length %d", StaParams.supported_rates_len);
3430 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07003431 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003432 "[%d]: %0x", i, StaParams.supported_rates[i]);
3433 }
3434
3435 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07003436 {
3437 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003438 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07003439 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07003440
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003441 if (0 != params->ext_capab_len ) {
3442 /*Define A Macro : TODO Sunil*/
3443 if ((1<<4) & StaParams.extn_capability[3]) {
3444 isBufSta = 1;
3445 }
3446 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05303447 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac, params->uapsd_queues,
3448 params->max_sp, isBufSta);
3449 if (VOS_STATUS_SUCCESS != status) {
3450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3451 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
3452 return -EINVAL;
3453 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08003454 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
3455
3456 if (VOS_STATUS_SUCCESS != status) {
3457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3458 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
3459 return -EINVAL;
3460 }
3461 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07003462#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05303463 }
Jeff Johnsone7245742012-09-05 17:12:55 -07003464 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07003465 return status;
3466}
3467
3468/*
Jeff Johnson295189b2012-06-20 16:38:30 -07003469 * FUNCTION: wlan_hdd_cfg80211_add_key
3470 * This function is used to initialize the key information
3471 */
3472#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003473static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003474 struct net_device *ndev,
3475 u8 key_index, bool pairwise,
3476 const u8 *mac_addr,
3477 struct key_params *params
3478 )
3479#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003480static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003481 struct net_device *ndev,
3482 u8 key_index, const u8 *mac_addr,
3483 struct key_params *params
3484 )
3485#endif
3486{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003487 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003488 tCsrRoamSetKey setKey;
3489 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303490 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003491 v_U32_t roamId= 0xFF;
3492 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003493 hdd_hostapd_state_t *pHostapdState;
3494 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003495 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303496 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07003497
3498 ENTER();
3499
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303500 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3501 status = wlan_hdd_validate_context(pHddCtx);
3502
3503 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003504 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05303505 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3506 "%s: HDD context is not valid", __func__);
3507 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07003508 }
3509
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003510 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
3511 __func__, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07003512
3513 if (CSR_MAX_NUM_KEY <= key_index)
3514 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003515 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003516 key_index);
3517
3518 return -EINVAL;
3519 }
3520
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003521 if (CSR_MAX_KEY_LEN < params->key_len)
3522 {
3523 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
3524 params->key_len);
3525
3526 return -EINVAL;
3527 }
3528
3529 hddLog(VOS_TRACE_LEVEL_INFO,
3530 "%s: called with key index = %d & key length %d",
3531 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07003532
3533 /*extract key idx, key len and key*/
3534 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3535 setKey.keyId = key_index;
3536 setKey.keyLength = params->key_len;
3537 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
3538
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003539 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07003540 {
3541 case WLAN_CIPHER_SUITE_WEP40:
3542 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
3543 break;
3544
3545 case WLAN_CIPHER_SUITE_WEP104:
3546 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
3547 break;
3548
3549 case WLAN_CIPHER_SUITE_TKIP:
3550 {
3551 u8 *pKey = &setKey.Key[0];
3552 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
3553
3554 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
3555
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003556 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07003557
3558 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003559 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003560 |--------------|----------|----------|
3561 <---16bytes---><--8bytes--><--8bytes-->
3562
3563 */
3564 /*Sme expects the 32 bytes key to be in the below order
3565
3566 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003567 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07003568 |--------------|----------|----------|
3569 <---16bytes---><--8bytes--><--8bytes-->
3570 */
3571 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003572 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07003573
3574 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003575 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003576
3577 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003578 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07003579
3580
3581 break;
3582 }
3583
3584 case WLAN_CIPHER_SUITE_CCMP:
3585 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
3586 break;
3587
3588#ifdef FEATURE_WLAN_WAPI
3589 case WLAN_CIPHER_SUITE_SMS4:
3590 {
3591 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3592 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
3593 params->key, params->key_len);
3594 return 0;
3595 }
3596#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003597
Jeff Johnson295189b2012-06-20 16:38:30 -07003598#ifdef FEATURE_WLAN_CCX
3599 case WLAN_CIPHER_SUITE_KRK:
3600 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
3601 break;
3602#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07003603
3604#ifdef WLAN_FEATURE_11W
3605 case WLAN_CIPHER_SUITE_AES_CMAC:
3606 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07003607 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07003608#endif
3609
Jeff Johnson295189b2012-06-20 16:38:30 -07003610 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07003611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07003612 __func__, params->cipher);
3613 return -EOPNOTSUPP;
3614 }
3615
3616 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
3617 __func__, setKey.encType);
3618
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003619 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07003620#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3621 (!pairwise)
3622#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003623 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07003624#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003625 )
3626 {
3627 /* set group key*/
3628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3629 "%s- %d: setting Broadcast key",
3630 __func__, __LINE__);
3631 setKey.keyDirection = eSIR_RX_ONLY;
3632 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3633 }
3634 else
3635 {
3636 /* set pairwise key*/
3637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3638 "%s- %d: setting pairwise key",
3639 __func__, __LINE__);
3640 setKey.keyDirection = eSIR_TX_RX;
3641 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3642 }
3643 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
3644 {
3645 setKey.keyDirection = eSIR_TX_RX;
3646 /*Set the group key*/
3647 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3648 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07003649
Shailender Karmuchi642e9812013-05-30 14:34:49 -07003650 if ( 0 != status )
3651 {
3652 hddLog(VOS_TRACE_LEVEL_ERROR,
3653 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3654 return -EINVAL;
3655 }
3656 /*Save the keys here and call sme_RoamSetKey for setting
3657 the PTK after peer joins the IBSS network*/
3658 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
3659 &setKey, sizeof(tCsrRoamSetKey));
3660 return status;
3661 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05303662 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
3663 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
3664 {
Jeff Johnson295189b2012-06-20 16:38:30 -07003665 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003666 if( pHostapdState->bssState == BSS_START )
3667 {
c_hpothu7c55da62014-01-23 18:34:02 +05303668 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3669 vos_status = wlan_hdd_check_ula_done(pAdapter);
3670
3671 if ( vos_status != VOS_STATUS_SUCCESS )
3672 {
3673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3674 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3675 __LINE__, vos_status );
3676
3677 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3678
3679 return -EINVAL;
3680 }
3681
Jeff Johnson295189b2012-06-20 16:38:30 -07003682 status = WLANSAP_SetKeySta( pVosContext, &setKey);
3683
3684 if ( status != eHAL_STATUS_SUCCESS )
3685 {
3686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3687 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3688 __LINE__, status );
3689 }
3690 }
3691
3692 /* Saving WEP keys */
3693 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
3694 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
3695 {
3696 //Save the wep key in ap context. Issue setkey after the BSS is started.
3697 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
3698 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
3699 }
3700 else
3701 {
3702 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003703 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07003704 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
3705 }
3706 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003707 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
3708 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07003709 {
3710 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3711 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3712
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
3714 if (!pairwise)
3715#else
3716 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
3717#endif
3718 {
3719 /* set group key*/
3720 if (pHddStaCtx->roam_info.deferKeyComplete)
3721 {
3722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
3723 "%s- %d: Perform Set key Complete",
3724 __func__, __LINE__);
3725 hdd_PerformRoamSetKeyComplete(pAdapter);
3726 }
3727 }
3728
Jeff Johnson295189b2012-06-20 16:38:30 -07003729 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
3730
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08003731 pWextState->roamProfile.Keys.defaultIndex = key_index;
3732
3733
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07003734 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07003735 params->key, params->key_len);
3736
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303737
Jeff Johnson295189b2012-06-20 16:38:30 -07003738 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3739
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303740 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003741 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303742 __func__, setKey.peerMac[0], setKey.peerMac[1],
3743 setKey.peerMac[2], setKey.peerMac[3],
3744 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003745 setKey.keyDirection);
3746
3747 vos_status = wlan_hdd_check_ula_done(pAdapter);
3748
3749 if ( vos_status != VOS_STATUS_SUCCESS )
3750 {
3751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3752 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
3753 __LINE__, vos_status );
3754
3755 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3756
3757 return -EINVAL;
3758
3759 }
3760
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003761#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303762 /* The supplicant may attempt to set the PTK once pre-authentication
3763 is done. Save the key in the UMAC and include it in the ADD BSS
3764 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003765 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303766 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003767 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05303768 hddLog(VOS_TRACE_LEVEL_INFO_MED,
3769 "%s: Update PreAuth Key success", __func__);
3770 return 0;
3771 }
3772 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
3773 {
3774 hddLog(VOS_TRACE_LEVEL_ERROR,
3775 "%s: Update PreAuth Key failed", __func__);
Gopichand Nakkalad7d13652013-02-15 01:48:00 +05303776 return -EINVAL;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07003777 }
3778#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07003779
3780 /* issue set key request to SME*/
3781 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
3782 pAdapter->sessionId, &setKey, &roamId );
3783
3784 if ( 0 != status )
3785 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303786 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07003787 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
3788 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3789 return -EINVAL;
3790 }
3791
3792
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303793 /* in case of IBSS as there was no information available about WEP keys during
3794 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07003795 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303796 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
3797 !( ( IW_AUTH_KEY_MGMT_802_1X
3798 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07003799 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
3800 )
3801 &&
3802 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
3803 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
3804 )
3805 )
3806 {
3807 setKey.keyDirection = eSIR_RX_ONLY;
3808 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
3809
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303810 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003811 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303812 __func__, setKey.peerMac[0], setKey.peerMac[1],
3813 setKey.peerMac[2], setKey.peerMac[3],
3814 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07003815 setKey.keyDirection);
3816
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303817 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07003818 pAdapter->sessionId, &setKey, &roamId );
3819
3820 if ( 0 != status )
3821 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303822 hddLog(VOS_TRACE_LEVEL_ERROR,
3823 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003824 __func__, status);
3825 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
3826 return -EINVAL;
3827 }
3828 }
3829 }
3830
3831 return 0;
3832}
3833
3834/*
3835 * FUNCTION: wlan_hdd_cfg80211_get_key
3836 * This function is used to get the key information
3837 */
3838#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303839static int wlan_hdd_cfg80211_get_key(
3840 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003841 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303842 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003843 const u8 *mac_addr, void *cookie,
3844 void (*callback)(void *cookie, struct key_params*)
3845 )
3846#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303847static int wlan_hdd_cfg80211_get_key(
3848 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003849 struct net_device *ndev,
3850 u8 key_index, const u8 *mac_addr, void *cookie,
3851 void (*callback)(void *cookie, struct key_params*)
3852 )
3853#endif
3854{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303855 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07003856 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3857 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
3858 struct key_params params;
3859
3860 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303861
Arif Hussain6d2a3322013-11-17 19:50:10 -08003862 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07003863 __func__,pAdapter->device_mode);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303864
Jeff Johnson295189b2012-06-20 16:38:30 -07003865 memset(&params, 0, sizeof(params));
3866
3867 if (CSR_MAX_NUM_KEY <= key_index)
3868 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05303869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07003870 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303871 }
Jeff Johnson295189b2012-06-20 16:38:30 -07003872
3873 switch(pRoamProfile->EncryptionType.encryptionType[0])
3874 {
3875 case eCSR_ENCRYPT_TYPE_NONE:
3876 params.cipher = IW_AUTH_CIPHER_NONE;
3877 break;
3878
3879 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3880 case eCSR_ENCRYPT_TYPE_WEP40:
3881 params.cipher = WLAN_CIPHER_SUITE_WEP40;
3882 break;
3883
3884 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3885 case eCSR_ENCRYPT_TYPE_WEP104:
3886 params.cipher = WLAN_CIPHER_SUITE_WEP104;
3887 break;
3888
3889 case eCSR_ENCRYPT_TYPE_TKIP:
3890 params.cipher = WLAN_CIPHER_SUITE_TKIP;
3891 break;
3892
3893 case eCSR_ENCRYPT_TYPE_AES:
3894 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
3895 break;
3896
3897 default:
3898 params.cipher = IW_AUTH_CIPHER_NONE;
3899 break;
3900 }
3901
3902 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
3903 params.seq_len = 0;
3904 params.seq = NULL;
3905 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
3906 callback(cookie, &params);
3907 return 0;
3908}
3909
3910/*
3911 * FUNCTION: wlan_hdd_cfg80211_del_key
3912 * This function is used to delete the key information
3913 */
3914#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303915static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003916 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303917 u8 key_index,
3918 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07003919 const u8 *mac_addr
3920 )
3921#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303922static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07003923 struct net_device *ndev,
3924 u8 key_index,
3925 const u8 *mac_addr
3926 )
3927#endif
3928{
3929 int status = 0;
3930
3931 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303932 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07003933 //it is observed that this is invalidating peer
3934 //key index whenever re-key is done. This is affecting data link.
3935 //It should be ok to ignore del_key.
3936#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303937 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
3938 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07003939 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
3940 tCsrRoamSetKey setKey;
3941 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303942
Jeff Johnson295189b2012-06-20 16:38:30 -07003943 ENTER();
3944
3945 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
3946 __func__,pAdapter->device_mode);
3947
3948 if (CSR_MAX_NUM_KEY <= key_index)
3949 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07003951 key_index);
3952
3953 return -EINVAL;
3954 }
3955
3956 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
3957 setKey.keyId = key_index;
3958
3959 if (mac_addr)
3960 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
3961 else
3962 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
3963
3964 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
3965
3966 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07003967 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303968 )
3969 {
3970
3971 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07003972 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
3973 if( pHostapdState->bssState == BSS_START)
3974 {
3975 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303976
Jeff Johnson295189b2012-06-20 16:38:30 -07003977 if ( status != eHAL_STATUS_SUCCESS )
3978 {
3979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
3980 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
3981 __LINE__, status );
3982 }
3983 }
3984 }
3985 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303986 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07003987 )
3988 {
3989 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3990
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303991 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
3992
3993 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07003994 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303995 __func__, setKey.peerMac[0], setKey.peerMac[1],
3996 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07003997 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05303998 if(pAdapter->sessionCtx.station.conn_info.connState ==
3999 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07004000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304001 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004002 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304003
Jeff Johnson295189b2012-06-20 16:38:30 -07004004 if ( 0 != status )
4005 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304006 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004007 "%s: sme_RoamSetKey failure, returned %d",
4008 __func__, status);
4009 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
4010 return -EINVAL;
4011 }
4012 }
4013 }
4014#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07004015 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07004016 return status;
4017}
4018
4019/*
4020 * FUNCTION: wlan_hdd_cfg80211_set_default_key
4021 * This function is used to set the default tx key index
4022 */
4023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
4024static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4025 struct net_device *ndev,
4026 u8 key_index,
4027 bool unicast, bool multicast)
4028#else
4029static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
4030 struct net_device *ndev,
4031 u8 key_index)
4032#endif
4033{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304035 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05304036 hdd_wext_state_t *pWextState;
4037 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304038 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004039
4040 ENTER();
4041
Gopichand Nakkala29149562013-05-10 21:43:41 +05304042 if ((NULL == pAdapter))
4043 {
4044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4045 "invalid adapter");
4046 return -EINVAL;
4047 }
4048
4049 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4050 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4051
4052 if ((NULL == pWextState) || (NULL == pHddStaCtx))
4053 {
4054 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4055 "invalid Wext state or HDD context");
4056 return -EINVAL;
4057 }
4058
Arif Hussain6d2a3322013-11-17 19:50:10 -08004059 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004060 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304061
Jeff Johnson295189b2012-06-20 16:38:30 -07004062 if (CSR_MAX_NUM_KEY <= key_index)
4063 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004065 key_index);
4066
4067 return -EINVAL;
4068 }
4069
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304070 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4071 status = wlan_hdd_validate_context(pHddCtx);
4072
4073 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004074 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4076 "%s: HDD context is not valid", __func__);
4077 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004078 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304079
Jeff Johnson295189b2012-06-20 16:38:30 -07004080 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07004081 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304082 )
Jeff Johnson295189b2012-06-20 16:38:30 -07004083 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05304084 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08004085 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304086 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08004087 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07004088 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304089 {
4090 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07004091 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304092
Jeff Johnson295189b2012-06-20 16:38:30 -07004093 tCsrRoamSetKey setKey;
4094 v_U32_t roamId= 0xFF;
4095 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304096
4097 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004098 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304099
Jeff Johnson295189b2012-06-20 16:38:30 -07004100 Keys->defaultIndex = (u8)key_index;
4101 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
4102 setKey.keyId = key_index;
4103 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304104
4105 vos_mem_copy(&setKey.Key[0],
4106 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07004107 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304108
Gopichand Nakkala29149562013-05-10 21:43:41 +05304109 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304110
4111 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07004112 &pHddStaCtx->conn_info.bssId[0],
4113 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304114
Gopichand Nakkala29149562013-05-10 21:43:41 +05304115 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
4116 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
4117 eCSR_ENCRYPT_TYPE_WEP104)
4118 {
4119 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
4120 even though ap is configured for WEP-40 encryption. In this canse the key length
4121 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
4122 type(104) and switching encryption type to 40*/
4123 pWextState->roamProfile.EncryptionType.encryptionType[0] =
4124 eCSR_ENCRYPT_TYPE_WEP40;
4125 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4126 eCSR_ENCRYPT_TYPE_WEP40;
4127 }
4128
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304129 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07004130 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304131
Jeff Johnson295189b2012-06-20 16:38:30 -07004132 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304133 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07004134 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304135
Jeff Johnson295189b2012-06-20 16:38:30 -07004136 if ( 0 != status )
4137 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304138 hddLog(VOS_TRACE_LEVEL_ERROR,
4139 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07004140 status);
4141 return -EINVAL;
4142 }
4143 }
4144 }
4145
4146 /* In SoftAp mode setting key direction for default mode */
4147 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
4148 {
4149 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
4150 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
4151 (eCSR_ENCRYPT_TYPE_AES !=
4152 pWextState->roamProfile.EncryptionType.encryptionType[0])
4153 )
4154 {
4155 /* Saving key direction for default key index to TX default */
4156 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
4157 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
4158 }
4159 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304160
Jeff Johnson295189b2012-06-20 16:38:30 -07004161 return status;
4162}
4163
Jeff Johnson295189b2012-06-20 16:38:30 -07004164/*
4165 * FUNCTION: wlan_hdd_cfg80211_inform_bss
4166 * This function is used to inform the BSS details to nl80211 interface.
4167 */
4168static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
4169 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
4170{
4171 struct net_device *dev = pAdapter->dev;
4172 struct wireless_dev *wdev = dev->ieee80211_ptr;
4173 struct wiphy *wiphy = wdev->wiphy;
4174 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
4175 int chan_no;
4176 int ie_length;
4177 const char *ie;
4178 unsigned int freq;
4179 struct ieee80211_channel *chan;
4180 int rssi = 0;
4181 struct cfg80211_bss *bss = NULL;
4182
4183 ENTER();
4184
4185 if( NULL == pBssDesc )
4186 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004187 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004188 return bss;
4189 }
4190
4191 chan_no = pBssDesc->channelId;
4192 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
4193 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
4194
4195 if( NULL == ie )
4196 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004197 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004198 return bss;
4199 }
4200
4201#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
4202 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
4203 {
4204 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4205 }
4206 else
4207 {
4208 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4209 }
4210#else
4211 freq = ieee80211_channel_to_frequency(chan_no);
4212#endif
4213
4214 chan = __ieee80211_get_channel(wiphy, freq);
4215
4216 bss = cfg80211_get_bss(wiphy, chan, pBssDesc->bssId,
4217 &roamProfile->SSID.ssId[0], roamProfile->SSID.length,
4218 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
4219 if (bss == NULL)
4220 {
4221 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
4222
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304223 return (cfg80211_inform_bss(wiphy, chan, pBssDesc->bssId,
4224 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07004225 pBssDesc->capabilityInfo,
4226 pBssDesc->beaconInterval, ie, ie_length,
4227 rssi, GFP_KERNEL ));
4228}
4229 else
4230 {
4231 return bss;
4232 }
4233}
4234
4235
4236
4237/*
4238 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
4239 * This function is used to inform the BSS details to nl80211 interface.
4240 */
4241struct cfg80211_bss*
4242wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
4243 tSirBssDescription *bss_desc
4244 )
4245{
4246 /*
4247 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
4248 already exists in bss data base of cfg80211 for that particular BSS ID.
4249 Using cfg80211_inform_bss_frame to update the bss entry instead of
4250 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
4251 now there is no possibility to get the mgmt(probe response) frame from PE,
4252 converting bss_desc to ieee80211_mgmt(probe response) and passing to
4253 cfg80211_inform_bss_frame.
4254 */
4255 struct net_device *dev = pAdapter->dev;
4256 struct wireless_dev *wdev = dev->ieee80211_ptr;
4257 struct wiphy *wiphy = wdev->wiphy;
4258 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004259#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4260 qcom_ie_age *qie_age = NULL;
4261 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
4262#else
Jeff Johnson295189b2012-06-20 16:38:30 -07004263 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004264#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004265 const char *ie =
4266 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
4267 unsigned int freq;
4268 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304269 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004270 struct cfg80211_bss *bss_status = NULL;
4271 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
4272 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07004273 hdd_context_t *pHddCtx;
4274 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07004275#ifdef WLAN_OPEN_SOURCE
4276 struct timespec ts;
4277#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07004278
Wilson Yangf80a0542013-10-07 13:02:37 -07004279 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4280 status = wlan_hdd_validate_context(pHddCtx);
4281
4282 /*bss_update is not allowed during wlan driver loading or unloading*/
4283 if (pHddCtx->isLoadUnloadInProgress)
4284 {
4285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4286 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4287 return NULL;
4288 }
4289
4290
4291 if (0 != status)
4292 {
4293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4294 "%s: HDD context is not valid", __func__);
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004295 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004296 }
4297
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05304298 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07004299 if (!mgmt)
4300 {
4301 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4302 "%s: memory allocation failed ", __func__);
4303 return NULL;
4304 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07004305
Jeff Johnson295189b2012-06-20 16:38:30 -07004306 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07004307
4308#ifdef WLAN_OPEN_SOURCE
4309 /* Android does not want the timestamp from the frame.
4310 Instead it wants a monotonic increasing value */
4311 get_monotonic_boottime(&ts);
4312 mgmt->u.probe_resp.timestamp =
4313 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
4314#else
4315 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07004316 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
4317 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07004318
4319#endif
4320
Jeff Johnson295189b2012-06-20 16:38:30 -07004321 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
4322 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08004323
4324#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
4325 /* GPS Requirement: need age ie per entry. Using vendor specific. */
4326 /* Assuming this is the last IE, copy at the end */
4327 ie_length -=sizeof(qcom_ie_age);
4328 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
4329 qie_age->element_id = QCOM_VENDOR_IE_ID;
4330 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
4331 qie_age->oui_1 = QCOM_OUI1;
4332 qie_age->oui_2 = QCOM_OUI2;
4333 qie_age->oui_3 = QCOM_OUI3;
4334 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
4335 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
4336#endif
4337
Jeff Johnson295189b2012-06-20 16:38:30 -07004338 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +05304339 if (bss_desc->fProbeRsp)
4340 {
4341 mgmt->frame_control |=
4342 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
4343 }
4344 else
4345 {
4346 mgmt->frame_control |=
4347 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
4348 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004349
4350#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304351 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004352 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
4353 {
4354 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
4355 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304356 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07004357 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
4358
4359 {
4360 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
4361 }
4362 else
4363 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
4365 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -07004366 kfree(mgmt);
4367 return NULL;
4368 }
4369#else
4370 freq = ieee80211_channel_to_frequency(chan_no);
4371#endif
4372 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004373 /*when the band is changed on the fly using the GUI, three things are done
4374 * 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)
4375 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
4376 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
4377 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
4378 * and discards the channels correponding to previous band and calls back with zero bss results.
4379 * 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
4380 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
4381 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
4382 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
4383 * So drop the bss and continue to next bss.
4384 */
4385 if(chan == NULL)
4386 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304387 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -07004388 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -08004389 return NULL;
4390 }
Jeff Johnson295189b2012-06-20 16:38:30 -07004391 /*To keep the rssi icon of the connected AP in the scan window
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304392 *and the rssi icon of the wireless networks in sync
Jeff Johnson295189b2012-06-20 16:38:30 -07004393 * */
4394 if (( eConnectionState_Associated ==
4395 pAdapter->sessionCtx.station.conn_info.connState ) &&
4396 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
4397 pAdapter->sessionCtx.station.conn_info.bssId,
4398 WNI_CFG_BSSID_LEN)))
4399 {
4400 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
4401 rssi = (pAdapter->rssi * 100);
4402 }
4403 else
4404 {
4405 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
4406 }
4407
Nirav Shah20ac06f2013-12-12 18:14:06 +05304408 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
4409 "RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
4410 chan->center_freq, (int)(rssi/100));
4411
Jeff Johnson295189b2012-06-20 16:38:30 -07004412 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
4413 frame_len, rssi, GFP_KERNEL);
4414 kfree(mgmt);
4415 return bss_status;
4416}
4417
4418/*
4419 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
4420 * This function is used to update the BSS data base of CFG8011
4421 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304422struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004423 tCsrRoamInfo *pRoamInfo
4424 )
4425{
4426 tCsrRoamConnectedProfile roamProfile;
4427 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4428 struct cfg80211_bss *bss = NULL;
4429
4430 ENTER();
4431
4432 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
4433 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
4434
4435 if (NULL != roamProfile.pBssDesc)
4436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304437 bss = wlan_hdd_cfg80211_inform_bss(pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07004438 &roamProfile);
4439
4440 if (NULL == bss)
4441 {
4442 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
4443 __func__);
4444 }
4445
4446 sme_RoamFreeConnectProfile(hHal, &roamProfile);
4447 }
4448 else
4449 {
4450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
4451 __func__);
4452 }
4453 return bss;
4454}
4455
4456/*
4457 * FUNCTION: wlan_hdd_cfg80211_update_bss
4458 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304459static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
4460 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -07004461 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304462{
Jeff Johnson295189b2012-06-20 16:38:30 -07004463 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4464 tCsrScanResultInfo *pScanResult;
4465 eHalStatus status = 0;
4466 tScanResultHandle pResult;
4467 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07004468 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07004469
4470 ENTER();
4471
Wilson Yangf80a0542013-10-07 13:02:37 -07004472 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4473
4474 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -07004475 {
Wilson Yangf80a0542013-10-07 13:02:37 -07004476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
4477 "%s:LOGP in Progress. Ignore!!!",__func__);
4478 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -07004479 }
4480
Wilson Yangf80a0542013-10-07 13:02:37 -07004481
4482 /*bss_update is not allowed during wlan driver loading or unloading*/
4483 if (pHddCtx->isLoadUnloadInProgress)
4484 {
4485 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4486 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
4487 return VOS_STATUS_E_PERM;
4488 }
4489
4490
Jeff Johnson295189b2012-06-20 16:38:30 -07004491 /*
4492 * start getting scan results and populate cgf80211 BSS database
4493 */
4494 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
4495
4496 /* no scan results */
4497 if (NULL == pResult)
4498 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05304499 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
4500 __func__, status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004501 return status;
4502 }
4503
4504 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
4505
4506 while (pScanResult)
4507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304508 /*
4509 * cfg80211_inform_bss() is not updating ie field of bss entry, if
4510 * entry already exists in bss data base of cfg80211 for that
4511 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
4512 * bss entry instead of cfg80211_inform_bss, But this call expects
4513 * mgmt packet as input. As of now there is no possibility to get
4514 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -07004515 * ieee80211_mgmt(probe response) and passing to c
4516 * fg80211_inform_bss_frame.
4517 * */
4518
4519 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
4520 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304521
Jeff Johnson295189b2012-06-20 16:38:30 -07004522
4523 if (NULL == bss_status)
4524 {
4525 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004526 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004527 }
4528 else
4529 {
Yue Maf49ba872013-08-19 12:04:25 -07004530 cfg80211_put_bss(
4531#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
4532 wiphy,
4533#endif
4534 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -07004535 }
4536
4537 pScanResult = sme_ScanResultGetNext(hHal, pResult);
4538 }
4539
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304540 sme_ScanResultPurge(hHal, pResult);
Jeff Johnson295189b2012-06-20 16:38:30 -07004541
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304542 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004543}
4544
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004545void
4546hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
4547{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304548 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -08004549 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004550} /****** end hddPrintMacAddr() ******/
4551
4552void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004553hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004554{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304555 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -08004556 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07004557 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
4558 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
4559 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004560} /****** end hddPrintPmkId() ******/
4561
4562//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
4563//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
4564
4565//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
4566//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
4567
4568#define dump_bssid(bssid) \
4569 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004570 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
4571 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004572 }
4573
4574#define dump_pmkid(pMac, pmkid) \
4575 { \
Jeff Johnsone7245742012-09-05 17:12:55 -07004576 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
4577 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004578 }
4579
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07004580#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004581/*
4582 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
4583 * This function is used to notify the supplicant of a new PMKSA candidate.
4584 */
4585int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304586 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004587 int index, bool preauth )
4588{
Jeff Johnsone7245742012-09-05 17:12:55 -07004589#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004590 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004591 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004592
4593 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -07004594 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004595
4596 if( NULL == pRoamInfo )
4597 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004598 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004599 return -EINVAL;
4600 }
4601
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004602 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
4603 {
4604 dump_bssid(pRoamInfo->bssid);
4605 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004606 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -07004607 }
Jeff Johnsone7245742012-09-05 17:12:55 -07004608#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304609 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07004610}
4611#endif //FEATURE_WLAN_LFR
4612
Yue Maef608272013-04-08 23:09:17 -07004613#ifdef FEATURE_WLAN_LFR_METRICS
4614/*
4615 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
4616 * 802.11r/LFR metrics reporting function to report preauth initiation
4617 *
4618 */
4619#define MAX_LFR_METRICS_EVENT_LENGTH 100
4620VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
4621 tCsrRoamInfo *pRoamInfo)
4622{
4623 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4624 union iwreq_data wrqu;
4625
4626 ENTER();
4627
4628 if (NULL == pAdapter)
4629 {
4630 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4631 return VOS_STATUS_E_FAILURE;
4632 }
4633
4634 /* create the event */
4635 memset(&wrqu, 0, sizeof(wrqu));
4636 memset(metrics_notification, 0, sizeof(metrics_notification));
4637
4638 wrqu.data.pointer = metrics_notification;
4639 wrqu.data.length = scnprintf(metrics_notification,
4640 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
4641 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4642
4643 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4644
4645 EXIT();
4646
4647 return VOS_STATUS_SUCCESS;
4648}
4649
4650/*
4651 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
4652 * 802.11r/LFR metrics reporting function to report preauth completion
4653 * or failure
4654 */
4655VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
4656 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
4657{
4658 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4659 union iwreq_data wrqu;
4660
4661 ENTER();
4662
4663 if (NULL == pAdapter)
4664 {
4665 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4666 return VOS_STATUS_E_FAILURE;
4667 }
4668
4669 /* create the event */
4670 memset(&wrqu, 0, sizeof(wrqu));
4671 memset(metrics_notification, 0, sizeof(metrics_notification));
4672
4673 scnprintf(metrics_notification, sizeof(metrics_notification),
4674 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
4675 MAC_ADDR_ARRAY(pRoamInfo->bssid));
4676
4677 if (1 == preauth_status)
4678 strncat(metrics_notification, " TRUE", 5);
4679 else
4680 strncat(metrics_notification, " FALSE", 6);
4681
4682 wrqu.data.pointer = metrics_notification;
4683 wrqu.data.length = strlen(metrics_notification);
4684
4685 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4686
4687 EXIT();
4688
4689 return VOS_STATUS_SUCCESS;
4690}
4691
4692/*
4693 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
4694 * 802.11r/LFR metrics reporting function to report handover initiation
4695 *
4696 */
4697VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
4698 tCsrRoamInfo *pRoamInfo)
4699{
4700 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
4701 union iwreq_data wrqu;
4702
4703 ENTER();
4704
4705 if (NULL == pAdapter)
4706 {
4707 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
4708 return VOS_STATUS_E_FAILURE;
4709 }
4710
4711 /* create the event */
4712 memset(&wrqu, 0, sizeof(wrqu));
4713 memset(metrics_notification, 0, sizeof(metrics_notification));
4714
4715 wrqu.data.pointer = metrics_notification;
4716 wrqu.data.length = scnprintf(metrics_notification,
4717 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
4718 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
4719
4720 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
4721
4722 EXIT();
4723
4724 return VOS_STATUS_SUCCESS;
4725}
4726#endif
4727
Jeff Johnson295189b2012-06-20 16:38:30 -07004728/*
4729 * FUNCTION: hdd_cfg80211_scan_done_callback
4730 * scanning callback function, called after finishing scan
4731 *
4732 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304733static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -07004734 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
4735{
4736 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304737 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -07004738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004739 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4740 hdd_scaninfo_t *pScanInfo = &pHddCtx->scan_info;
Jeff Johnson295189b2012-06-20 16:38:30 -07004741 struct cfg80211_scan_request *req = NULL;
4742 int ret = 0;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304743 long waitRet = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07004744
4745 ENTER();
4746
4747 hddLog(VOS_TRACE_LEVEL_INFO,
4748 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -08004749 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004750 __func__, halHandle, pContext, (int) scanId, (int) status);
4751
Kiet Lamac06e2c2013-10-23 16:25:07 +05304752 pScanInfo->mScanPendingCounter = 0;
4753
Jeff Johnson295189b2012-06-20 16:38:30 -07004754 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304755 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -07004756 &pScanInfo->scan_req_completion_event,
4757 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304758 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -07004759 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05304760 hddLog(VOS_TRACE_LEVEL_ERROR,
4761 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -07004762 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004763 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004764 }
4765
Yue Maef608272013-04-08 23:09:17 -07004766 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -07004767 {
4768 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07004769 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004770 }
4771
4772 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304773 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -07004774 {
4775 hddLog(VOS_TRACE_LEVEL_INFO,
4776 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -08004777 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -07004778 (int) scanId);
4779 }
4780
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304781 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07004782 pAdapter);
4783
4784 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304785 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07004786
4787
4788 /* If any client wait scan result through WEXT
4789 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004790 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -07004791 {
4792 /* The other scan request waiting for current scan finish
4793 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004794 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004795 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004796 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -07004797 }
4798 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004799 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -07004800 {
4801 struct net_device *dev = pAdapter->dev;
4802 union iwreq_data wrqu;
4803 int we_event;
4804 char *msg;
4805
4806 memset(&wrqu, '\0', sizeof(wrqu));
4807 we_event = SIOCGIWSCAN;
4808 msg = NULL;
4809 wireless_send_event(dev, we_event, &wrqu, msg);
4810 }
4811 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07004812 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004813
4814 /* Get the Scan Req */
4815 req = pAdapter->request;
4816
4817 if (!req)
4818 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08004819 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004820 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -07004821 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -07004822 }
4823
4824 /*
4825 * setting up 0, just in case.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304826 */
Jeff Johnson295189b2012-06-20 16:38:30 -07004827 req->n_ssids = 0;
4828 req->n_channels = 0;
4829 req->ie = 0;
4830
Jeff Johnson295189b2012-06-20 16:38:30 -07004831 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -07004832 /* Scan is no longer pending */
4833 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07004834
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -07004835 /*
4836 * cfg80211_scan_done informing NL80211 about completion
4837 * of scanning
4838 */
4839 cfg80211_scan_done(req, false);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -08004840 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -07004841
Jeff Johnsone7245742012-09-05 17:12:55 -07004842allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07004843 /* release the wake lock at the end of the scan*/
4844 hdd_allow_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07004845
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004846 /* Acquire wakelock to handle the case where APP's tries to suspend
4847 * immediatly after the driver gets connect request(i.e after scan)
4848 * from supplicant, this result in app's is suspending and not able
4849 * to process the connect request to AP */
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05304850 hdd_prevent_suspend_timeout(1000);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -07004851
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07004852#ifdef FEATURE_WLAN_TDLS
4853 wlan_hdd_tdls_scan_done_callback(pAdapter);
4854#endif
4855
Jeff Johnson295189b2012-06-20 16:38:30 -07004856 EXIT();
4857 return 0;
4858}
4859
4860/*
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004861 * FUNCTION: hdd_isScanAllowed
4862 * Go through each adapter and check if scan allowed
4863 *
4864 */
4865v_BOOL_t hdd_isScanAllowed( hdd_context_t *pHddCtx )
4866{
4867 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
4868 hdd_station_ctx_t *pHddStaCtx = NULL;
4869 hdd_adapter_t *pAdapter = NULL;
4870 VOS_STATUS status = 0;
4871 v_U8_t staId = 0;
4872 v_U8_t *staMac = NULL;
4873
c_hpothu9b781ba2013-12-30 20:57:45 +05304874 if (TRUE == pHddCtx->btCoexModeSet)
4875 {
4876 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
4877 FL("BTCoex Mode operation in progress, Do not allow scan"));
4878 return VOS_FALSE;
4879 }
4880
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004881 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
4882
4883 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
4884 {
4885 pAdapter = pAdapterNode->pAdapter;
4886
4887 if( pAdapter )
4888 {
4889 hddLog(VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304890 "%s: Adapter with device mode %d exists",
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004891 __func__, pAdapter->device_mode);
4892 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
4893 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
4894 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
4895 {
4896 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4897 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
4898 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
4899 {
4900 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
4901 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004902 "%s: client " MAC_ADDRESS_STR
4903 " is in the middle of WPS/EAPOL exchange.", __func__,
4904 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004905 return VOS_FALSE;
4906 }
4907 }
4908 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
4909 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
4910 {
4911 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
4912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304913 if ((pAdapter->aStaInfo[staId].isUsed) &&
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004914 (WLANTL_STA_CONNECTED == pAdapter->aStaInfo[staId].tlSTAState))
4915 {
4916 staMac = (v_U8_t *) &(pAdapter->aStaInfo[staId].macAddrSTA.bytes[0]);
4917
4918 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -08004919 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
4920 "middle of WPS/EAPOL exchange.", __func__,
4921 MAC_ADDR_ARRAY(staMac));
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004922 return VOS_FALSE;
4923 }
4924 }
4925 }
4926 }
4927 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
4928 pAdapterNode = pNext;
4929 }
4930 hddLog(VOS_TRACE_LEVEL_INFO,
4931 "%s: Scan allowed", __func__);
4932 return VOS_TRUE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304933}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08004934
4935/*
Jeff Johnson295189b2012-06-20 16:38:30 -07004936 * FUNCTION: wlan_hdd_cfg80211_scan
4937 * this scan respond to scan trigger and update cfg80211 scan database
4938 * later, scan dump command can be used to recieve scan results
4939 */
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08004940int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
4941#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
4942 struct net_device *dev,
4943#endif
4944 struct cfg80211_scan_request *request)
4945{
4946#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
4947 struct net_device *dev = request->wdev->netdev;
4948#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05304949 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07004950 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
4951 hdd_wext_state_t *pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304952 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004953 tCsrScanRequest scanRequest;
4954 tANI_U8 *channelList = NULL, i;
4955 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304956 int status;
4957 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004958 v_U8_t* pP2pIe = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07004959
4960 ENTER();
4961
Arif Hussain6d2a3322013-11-17 19:50:10 -08004962 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07004963 __func__,pAdapter->device_mode);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004964
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05304965 status = wlan_hdd_validate_context(pHddCtx);
4966
4967 if (0 != status)
4968 {
4969 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
4970 "%s: HDD context is not valid", __func__);
4971 return status;
4972 }
4973
4974 cfg_param = pHddCtx->cfg_ini;
4975 pScanInfo = &pHddCtx->scan_info;
4976
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004977 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004978 (eConnectionState_Connecting ==
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004979 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004980 {
4981 hddLog(VOS_TRACE_LEVEL_ERROR,
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08004982 "%s: %p(%d) Connection in progress: Scan request denied (EBUSY)", __func__, \
4983 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004984 return -EBUSY;
4985 }
4986
Jeff Johnson295189b2012-06-20 16:38:30 -07004987#ifdef WLAN_BTAMP_FEATURE
4988 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004989 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -07004990 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08004991 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07004992 "%s: No scanning when AMP is on", __func__);
4993 return -EOPNOTSUPP;
4994 }
4995#endif
4996 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004997 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07004998 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08004999 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005000 "%s: Not scanning on device_mode = %d",
5001 __func__, pAdapter->device_mode);
5002 return -EOPNOTSUPP;
5003 }
5004
5005 if (TRUE == pScanInfo->mScanPending)
5006 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305007 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
5008 {
5009 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
5010 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005011 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005012 }
5013
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305014 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -07005015 //Channel and action frame is pending
5016 //Otherwise Cancel Remain On Channel and allow Scan
5017 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005018 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -07005019 {
Kiet Lamac06e2c2013-10-23 16:25:07 +05305020 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -07005021 return -EBUSY;
5022 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005023#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005024 /* if tdls disagree scan right now, return immediately.
5025 tdls will schedule the scan when scan is allowed. (return SUCCESS)
5026 or will reject the scan if any TDLS is in progress. (return -EBUSY)
5027 */
5028 status = wlan_hdd_tdls_scan_callback (pAdapter,
5029 wiphy,
5030#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
5031 dev,
Gopichand Nakkalac3c42b92013-03-20 19:42:34 -07005032#endif
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005033 request);
5034 if(status <= 0)
5035 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305036 if(!status)
5037 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
5038 "scan rejected %d", __func__, status);
5039 else
5040 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
5041 __func__, status);
5042
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07005043 return status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08005044 }
5045#endif
Jeff Johnson32d95a32012-09-10 13:15:23 -07005046
Jeff Johnson295189b2012-06-20 16:38:30 -07005047 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
5048 {
5049 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -08005050 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005051 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305052 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005053 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
5054 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305055 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005056 "%s: MAX TM Level Scan not allowed", __func__);
5057 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305058 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -07005059 }
5060 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
5061
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -08005062 /* Check if scan is allowed at this point of time.
5063 */
5064 if (!hdd_isScanAllowed(pHddCtx))
5065 {
5066 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
5067 return -EBUSY;
5068 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305069
Jeff Johnson295189b2012-06-20 16:38:30 -07005070 vos_mem_zero( &scanRequest, sizeof(scanRequest));
5071
5072 if (NULL != request)
5073 {
5074 hddLog(VOS_TRACE_LEVEL_INFO, "scan request for ssid = %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305075 (int)request->n_ssids);
Jeff Johnson295189b2012-06-20 16:38:30 -07005076
5077 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
5078 * Becasue of this, driver is assuming that this is not wildcard scan and so
5079 * is not aging out the scan results.
5080 */
Jeff Johnson32d95a32012-09-10 13:15:23 -07005081 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -07005082 {
5083 request->n_ssids = 0;
5084 }
5085
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07005086 if ((request->ssids) && (0 < request->n_ssids))
Jeff Johnson295189b2012-06-20 16:38:30 -07005087 {
5088 tCsrSSIDInfo *SsidInfo;
5089 int j;
5090 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
5091 /* Allocate num_ssid tCsrSSIDInfo structure */
5092 SsidInfo = scanRequest.SSIDs.SSIDList =
5093 ( tCsrSSIDInfo *)vos_mem_malloc(
5094 request->n_ssids*sizeof(tCsrSSIDInfo));
5095
5096 if(NULL == scanRequest.SSIDs.SSIDList)
5097 {
5098 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305099 "%s: memory alloc failed SSIDInfo buffer", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005100 return -ENOMEM;
5101 }
5102
5103 /* copy all the ssid's and their length */
5104 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
5105 {
5106 /* get the ssid length */
5107 SsidInfo->SSID.length = request->ssids[j].ssid_len;
5108 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
5109 SsidInfo->SSID.length);
5110 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
Nirav Shah20ac06f2013-12-12 18:14:06 +05305111 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
Jeff Johnson295189b2012-06-20 16:38:30 -07005112 j, SsidInfo->SSID.ssId);
5113 }
5114 /* set the scan type to active */
5115 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5116 }
5117 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
5118 {
5119 /* set the scan type to active */
5120 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5121 }
5122 else
5123 {
5124 /*Set the scan type to default type, in this case it is ACTIVE*/
5125 scanRequest.scanType = pScanInfo->scan_mode;
5126 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305127 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -07005128 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
5129 }
5130 else
5131 {
5132 /* set the scan type to active */
5133 scanRequest.scanType = eSIR_ACTIVE_SCAN;
5134 vos_mem_set( scanRequest.bssid, sizeof( tCsrBssid ), 0xff );
5135
5136 /* set min and max channel time to zero */
5137 scanRequest.minChnTime = 0;
5138 scanRequest.maxChnTime = 0;
5139 }
5140
5141 /* set BSSType to default type */
5142 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
5143
5144 /*TODO: scan the requested channels only*/
5145
5146 /*Right now scanning all the channels */
5147 if( request )
5148 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305149 hddLog(VOS_TRACE_LEVEL_INFO,
5150 "No of Scan Channels: %d", request->n_channels);
Jeff Johnson295189b2012-06-20 16:38:30 -07005151 if( request->n_channels )
5152 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305153 char chList [(request->n_channels*5)+1];
5154 int len;
Jeff Johnson295189b2012-06-20 16:38:30 -07005155 channelList = vos_mem_malloc( request->n_channels );
5156 if( NULL == channelList )
5157 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05305158 hddLog(VOS_TRACE_LEVEL_ERROR,
Nirav Shah20ac06f2013-12-12 18:14:06 +05305159 "%s: memory alloc failed channelList", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005160 status = -ENOMEM;
5161 goto free_mem;
5162 }
5163
Nirav Shah20ac06f2013-12-12 18:14:06 +05305164 for( i = 0, len = 0; i < request->n_channels ; i++ )
5165 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005166 channelList[i] = request->channels[i]->hw_value;
Nirav Shah20ac06f2013-12-12 18:14:06 +05305167 len += snprintf(chList+len, 5, "%d ", channelList[i]);
5168 }
5169
5170 hddLog(VOS_TRACE_LEVEL_INFO,
5171 "Channel-List: %s ", chList);
Jeff Johnson295189b2012-06-20 16:38:30 -07005172 }
5173
5174 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
5175 scanRequest.ChannelInfo.ChannelList = channelList;
5176
5177 /* set requestType to full scan */
5178 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305179
5180 /* Flush the scan results(only p2p beacons) for STA scan and P2P
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005181 * search (Flush on both full scan and social scan but not on single
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305182 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005183 */
5184
5185 /* Supplicant does single channel scan after 8-way handshake
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305186 * and in that case driver shoudnt flush scan results. If
5187 * driver flushes the scan results here and unfortunately if
5188 * the AP doesnt respond to our probe req then association
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005189 * fails which is not desired
5190 */
5191
5192 if( request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN )
5193 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305194 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
Madan Mohan Koyyalamudi8d50f312012-11-27 15:48:57 -08005195 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
5196 pAdapter->sessionId );
5197 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005198
5199 if( request->ie_len )
5200 {
5201 /* save this for future association (join requires this) */
Agarwal Ashish4f616132013-12-30 23:32:50 +05305202 /*TODO: Array needs to be converted to dynamic allocation,
5203 * as multiple ie.s can be sent in cfg80211_scan_request structure
5204 * CR 597966
5205 */
Jeff Johnson295189b2012-06-20 16:38:30 -07005206 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
5207 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
5208 pScanInfo->scanAddIE.length = request->ie_len;
5209
Agarwal Ashish4f616132013-12-30 23:32:50 +05305210 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Jeff Johnsone7245742012-09-05 17:12:55 -07005211 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
Agarwal Ashish4f616132013-12-30 23:32:50 +05305212 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -07005213 {
Agarwal Ashish4f616132013-12-30 23:32:50 +05305214 if ( request->ie_len <= SIR_MAC_MAX_IE_LENGTH)
5215 {
5216 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
5217 memcpy( pwextBuf->roamProfile.addIEScan,
5218 request->ie, request->ie_len);
5219 }
5220 else
5221 {
5222 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
5223 "%d", request->ie_len);
5224 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005225
Agarwal Ashish4f616132013-12-30 23:32:50 +05305226 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005227 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
5228 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
5229
Jeff Johnson295189b2012-06-20 16:38:30 -07005230 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
5231 request->ie_len);
5232 if (pP2pIe != NULL)
5233 {
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07005234#ifdef WLAN_FEATURE_P2P_DEBUG
5235 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
5236 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
5237 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5238 {
5239 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
5240 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5241 "Go nego completed to Connection is started");
5242 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5243 "for 8way Handshake");
5244 }
5245 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
5246 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5247 {
5248 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
5249 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
5250 "Disconnected state to Connection is started");
5251 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
5252 "for 4way Handshake");
5253 }
5254#endif
5255
Jeff Johnsone7245742012-09-05 17:12:55 -07005256 /* no_cck will be set during p2p find to disable 11b rates */
5257 if(TRUE == request->no_cck)
Jeff Johnson295189b2012-06-20 16:38:30 -07005258 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005259 hddLog(VOS_TRACE_LEVEL_INFO,
5260 "%s: This is a P2P Search", __func__);
5261 scanRequest.p2pSearch = 1;
Jeff Johnsone7245742012-09-05 17:12:55 -07005262
Jeff Johnsone7245742012-09-05 17:12:55 -07005263 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
5264 {
Madan Mohan Koyyalamudi1b1d9e82012-10-21 11:38:33 -07005265 /* set requestType to P2P Discovery */
5266 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
Jeff Johnsone7245742012-09-05 17:12:55 -07005267 }
5268
5269 /*
5270 Skip Dfs Channel in case of P2P Search
5271 if it is set in ini file
5272 */
5273 if(cfg_param->skipDfsChnlInP2pSearch)
5274 {
5275 scanRequest.skipDfsChnlInP2pSearch = 1;
5276 }
5277 else
5278 {
5279 scanRequest.skipDfsChnlInP2pSearch = 0;
5280 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005281
Jeff Johnson295189b2012-06-20 16:38:30 -07005282 }
5283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005284 }
5285 }
5286
5287 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
5288
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005289 /* acquire the wakelock to avoid the apps suspend during the scan. To
5290 * address the following issues.
5291 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
5292 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
5293 * for long time, this result in apps running at full power for long time.
5294 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
5295 * be stuck in full power because of resume BMPS
5296 */
5297 hdd_prevent_suspend();
Jeff Johnsone7245742012-09-05 17:12:55 -07005298
Nirav Shah20ac06f2013-12-12 18:14:06 +05305299 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
5300 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
5301 "p2pSearch %d, skipDfsChnlInP2pSearch %d", scanRequest.requestType,
5302 scanRequest.scanType, scanRequest.minChnTime, scanRequest.maxChnTime,
5303 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
5304
Jeff Johnsone7245742012-09-05 17:12:55 -07005305 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005306 pAdapter->sessionId, &scanRequest, &scanId,
5307 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -07005308
Jeff Johnson295189b2012-06-20 16:38:30 -07005309 if (eHAL_STATUS_SUCCESS != status)
5310 {
5311 hddLog(VOS_TRACE_LEVEL_ERROR,
5312 "%s: sme_ScanRequest returned error %d", __func__, status);
5313 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005314 if(eHAL_STATUS_RESOURCES == status)
5315 {
Nirav Shah20ac06f2013-12-12 18:14:06 +05305316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
5317 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -07005318 status = -EBUSY;
5319 } else {
5320 status = -EIO;
5321 }
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -07005322 hdd_allow_suspend();
Jeff Johnson295189b2012-06-20 16:38:30 -07005323 goto free_mem;
5324 }
5325
5326 pScanInfo->mScanPending = TRUE;
5327 pAdapter->request = request;
5328 pScanInfo->scanId = scanId;
5329
5330 complete(&pScanInfo->scan_req_completion_event);
5331
5332free_mem:
5333 if( scanRequest.SSIDs.SSIDList )
5334 {
5335 vos_mem_free(scanRequest.SSIDs.SSIDList);
5336 }
5337
5338 if( channelList )
5339 vos_mem_free( channelList );
5340
5341 EXIT();
5342
5343 return status;
5344}
5345
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005346
5347void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
5348{
5349 v_U8_t iniDot11Mode =
5350 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
5351 eHddDot11Mode hddDot11Mode = iniDot11Mode;
5352
5353 switch ( iniDot11Mode )
5354 {
5355 case eHDD_DOT11_MODE_AUTO:
5356 case eHDD_DOT11_MODE_11ac:
5357 case eHDD_DOT11_MODE_11ac_ONLY:
5358#ifdef WLAN_FEATURE_11AC
5359 hddDot11Mode = eHDD_DOT11_MODE_11ac;
5360#else
5361 hddDot11Mode = eHDD_DOT11_MODE_11n;
5362#endif
5363 break;
5364 case eHDD_DOT11_MODE_11n:
5365 case eHDD_DOT11_MODE_11n_ONLY:
5366 hddDot11Mode = eHDD_DOT11_MODE_11n;
5367 break;
5368 default:
5369 hddDot11Mode = iniDot11Mode;
5370 break;
5371 }
5372 /* This call decides required channel bonding mode */
5373 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
5374 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
5375 operationChannel);
5376}
5377
Jeff Johnson295189b2012-06-20 16:38:30 -07005378/*
5379 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305380 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -07005381 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305382int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -07005383 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07005384{
5385 int status = 0;
5386 hdd_wext_state_t *pWextState;
5387 v_U32_t roamId;
5388 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -07005389 eCsrAuthType RSNAuthType;
5390
5391 ENTER();
5392
5393 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305394
Jeff Johnson295189b2012-06-20 16:38:30 -07005395 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
5396 {
5397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
5398 return -EINVAL;
5399 }
5400
5401 pRoamProfile = &pWextState->roamProfile;
5402
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305403 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -07005404 {
Jeff Johnsone7245742012-09-05 17:12:55 -07005405 hdd_station_ctx_t *pHddStaCtx;
5406 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005407
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305408 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -07005409 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
5410 {
5411 /*QoS not enabled in cfg file*/
5412 pRoamProfile->uapsd_mask = 0;
5413 }
5414 else
5415 {
5416 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305417 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -07005418 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
5419 }
5420
5421 pRoamProfile->SSIDs.numOfSSIDs = 1;
5422 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
5423 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305424 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -07005425 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
5426 ssid, ssid_len);
5427
5428 if (bssid)
5429 {
5430 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
5431 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
5432 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305433 /* Save BSSID in seperate variable as well, as RoamProfile
5434 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -07005435 case of join failure we should send valid BSSID to supplicant
5436 */
5437 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
5438 WNI_CFG_BSSID_LEN);
5439 }
Dhanashri Atre51981c62013-06-13 11:47:57 -07005440 else
5441 {
5442 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
5443 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005444
5445 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
5446 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305447 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005448 /*set gen ie*/
5449 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
5450 /*set auth*/
5451 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5452 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005453#ifdef FEATURE_WLAN_WAPI
5454 if (pAdapter->wapi_info.nWapiMode)
5455 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005456 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005457 switch (pAdapter->wapi_info.wapiAuthMode)
5458 {
5459 case WAPI_AUTH_MODE_PSK:
5460 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005461 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005462 pAdapter->wapi_info.wapiAuthMode);
5463 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5464 break;
5465 }
5466 case WAPI_AUTH_MODE_CERT:
5467 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005468 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005469 pAdapter->wapi_info.wapiAuthMode);
5470 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5471 break;
5472 }
5473 } // End of switch
5474 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5475 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
5476 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07005477 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07005478 pRoamProfile->AuthType.numEntries = 1;
5479 pRoamProfile->EncryptionType.numEntries = 1;
5480 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5481 pRoamProfile->mcEncryptionType.numEntries = 1;
5482 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
5483 }
5484 }
5485#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305486#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305487 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305488 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
5489 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
5490 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05305491 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
5492 sizeof (tSirGtkOffloadParams));
5493 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05305494 }
5495#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005496 pRoamProfile->csrPersona = pAdapter->device_mode;
5497
Jeff Johnson32d95a32012-09-10 13:15:23 -07005498 if( operatingChannel )
5499 {
5500 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
5501 pRoamProfile->ChannelInfo.numOfChannels = 1;
5502 }
Chet Lanctot186b5732013-03-18 10:26:30 -07005503 else
5504 {
5505 pRoamProfile->ChannelInfo.ChannelList = NULL;
5506 pRoamProfile->ChannelInfo.numOfChannels = 0;
5507 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07005508 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
5509 {
5510 hdd_select_cbmode(pAdapter,operatingChannel);
5511 }
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005512 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
5513 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305514 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005515 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005516 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
5517 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305518 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5519 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005520 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
5521 eConnectionState_Connecting);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305522
5523 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07005524 pAdapter->sessionId, pRoamProfile, &roamId);
5525
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +05305526 if ((eHAL_STATUS_SUCCESS != status) &&
5527 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
5528 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305529
5530 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
5532 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
5533 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305534 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -08005535 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +05305536 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -08005537
5538 pRoamProfile->ChannelInfo.ChannelList = NULL;
5539 pRoamProfile->ChannelInfo.numOfChannels = 0;
5540
Jeff Johnson295189b2012-06-20 16:38:30 -07005541 }
5542 else
5543 {
5544 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
5545 return -EINVAL;
5546 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -08005547 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07005548 return status;
5549}
5550
5551/*
5552 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
5553 * This function is used to set the authentication type (OPEN/SHARED).
5554 *
5555 */
5556static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
5557 enum nl80211_auth_type auth_type)
5558{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305559 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005560 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5561
5562 ENTER();
5563
5564 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305565 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -07005566 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005567 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305568 hddLog(VOS_TRACE_LEVEL_INFO,
5569 "%s: set authentication type to AUTOSWITCH", __func__);
5570 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
5571 break;
5572
5573 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07005574#ifdef WLAN_FEATURE_VOWIFI_11R
5575 case NL80211_AUTHTYPE_FT:
5576#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305577 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005578 "%s: set authentication type to OPEN", __func__);
5579 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
5580 break;
5581
5582 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305583 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005584 "%s: set authentication type to SHARED", __func__);
5585 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
5586 break;
5587#ifdef FEATURE_WLAN_CCX
5588 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305589 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -07005590 "%s: set authentication type to CCKM WPA", __func__);
5591 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
5592 break;
5593#endif
5594
5595
5596 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305597 hddLog(VOS_TRACE_LEVEL_ERROR,
5598 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07005599 auth_type);
5600 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
5601 return -EINVAL;
5602 }
5603
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305604 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005605 pHddStaCtx->conn_info.authType;
5606 return 0;
5607}
5608
5609/*
5610 * FUNCTION: wlan_hdd_set_akm_suite
5611 * This function is used to set the key mgmt type(PSK/8021x).
5612 *
5613 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305614static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07005615 u32 key_mgmt
5616 )
5617{
5618 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5619 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305620
Jeff Johnson295189b2012-06-20 16:38:30 -07005621 /*set key mgmt type*/
5622 switch(key_mgmt)
5623 {
5624 case WLAN_AKM_SUITE_PSK:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305625#ifdef WLAN_FEATURE_VOWIFI_11R
5626 case WLAN_AKM_SUITE_FT_PSK:
5627#endif
5628 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -07005629 __func__);
5630 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5631 break;
5632
5633 case WLAN_AKM_SUITE_8021X:
Gopichand Nakkala356fb102013-03-06 12:34:04 +05305634#ifdef WLAN_FEATURE_VOWIFI_11R
5635 case WLAN_AKM_SUITE_FT_8021X:
5636#endif
5637 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -07005638 __func__);
5639 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
5640 break;
5641#ifdef FEATURE_WLAN_CCX
5642#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
5643#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5644 case WLAN_AKM_SUITE_CCKM:
5645 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
5646 __func__);
5647 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
5648 break;
5649#endif
5650
5651 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305652 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005653 __func__, key_mgmt);
5654 return -EINVAL;
5655
5656 }
5657 return 0;
5658}
5659
5660/*
5661 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305662 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -07005663 * (NONE/WEP40/WEP104/TKIP/CCMP).
5664 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305665static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
5666 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -07005667 bool ucast
5668 )
5669{
5670 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305671 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07005672 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5673
5674 ENTER();
5675
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305676 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005677 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305678 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -07005679 __func__, cipher);
5680 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5681 }
5682 else
5683 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305684
Jeff Johnson295189b2012-06-20 16:38:30 -07005685 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305686 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07005687 {
5688 case IW_AUTH_CIPHER_NONE:
5689 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
5690 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305691
Jeff Johnson295189b2012-06-20 16:38:30 -07005692 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305693 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -07005694 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305695
Jeff Johnson295189b2012-06-20 16:38:30 -07005696 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +05305697 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -07005698 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305699
Jeff Johnson295189b2012-06-20 16:38:30 -07005700 case WLAN_CIPHER_SUITE_TKIP:
5701 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5702 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305703
Jeff Johnson295189b2012-06-20 16:38:30 -07005704 case WLAN_CIPHER_SUITE_CCMP:
5705 encryptionType = eCSR_ENCRYPT_TYPE_AES;
5706 break;
5707#ifdef FEATURE_WLAN_WAPI
5708 case WLAN_CIPHER_SUITE_SMS4:
5709 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
5710 break;
5711#endif
5712
5713#ifdef FEATURE_WLAN_CCX
5714 case WLAN_CIPHER_SUITE_KRK:
5715 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
5716 break;
5717#endif
5718 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005720 __func__, cipher);
5721 return -EOPNOTSUPP;
5722 }
5723 }
5724
5725 if (ucast)
5726 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 __func__, encryptionType);
5729 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
5730 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305731 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -07005732 encryptionType;
5733 }
5734 else
5735 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305736 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07005737 __func__, encryptionType);
5738 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
5739 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
5740 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
5741 }
5742
5743 return 0;
5744}
5745
5746
5747/*
5748 * FUNCTION: wlan_hdd_cfg80211_set_ie
5749 * This function is used to parse WPA/RSN IE's.
5750 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
5752 u8 *ie,
Jeff Johnson295189b2012-06-20 16:38:30 -07005753 size_t ie_len
5754 )
5755{
5756 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5757 u8 *genie = ie;
5758 v_U16_t remLen = ie_len;
5759#ifdef FEATURE_WLAN_WAPI
5760 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
5761 u16 *tmp;
5762 v_U16_t akmsuiteCount;
5763 int *akmlist;
5764#endif
5765 ENTER();
5766
5767 /* clear previous assocAddIE */
5768 pWextState->assocAddIE.length = 0;
5769 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
5770
5771 while (remLen >= 2)
5772 {
5773 v_U16_t eLen = 0;
5774 v_U8_t elementId;
5775 elementId = *genie++;
5776 eLen = *genie++;
5777 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305778
Arif Hussain6d2a3322013-11-17 19:50:10 -08005779 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -07005780 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305781
5782 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -07005783 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305784 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005785 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 -07005786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305787 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07005788 "%s: Invalid WPA IE", __func__);
5789 return -EINVAL;
5790 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305791 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -07005792 {
5793 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305794 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005795 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305796
Jeff Johnson295189b2012-06-20 16:38:30 -07005797 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5798 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005799 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
5800 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005801 VOS_ASSERT(0);
5802 return -ENOMEM;
5803 }
5804 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5805 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5806 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305807
Jeff Johnson295189b2012-06-20 16:38:30 -07005808 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
5809 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5810 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5811 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305812 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
5813 {
Jeff Johnson295189b2012-06-20 16:38:30 -07005814 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
5815 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
5816 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
5817 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
5818 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
5819 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305820 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +05305821 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -07005822 {
5823 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305824 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005825 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826
Jeff Johnson295189b2012-06-20 16:38:30 -07005827 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5828 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005829 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5830 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 VOS_ASSERT(0);
5832 return -ENOMEM;
5833 }
5834 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
5835 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5836 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305837
Jeff Johnson295189b2012-06-20 16:38:30 -07005838 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5839 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5840 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005841#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305842 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
5843 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07005844 /*Consider WFD IE, only for P2P Client */
5845 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
5846 {
5847 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305848 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -07005849 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305850
Jeff Johnson295189b2012-06-20 16:38:30 -07005851 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5852 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005853 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5854 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -07005855 VOS_ASSERT(0);
5856 return -ENOMEM;
5857 }
5858 // WFD IE is saved to Additional IE ; it should be accumulated to handle
5859 // WPS IE + P2P IE + WFD IE
5860 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5861 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305862
Jeff Johnson295189b2012-06-20 16:38:30 -07005863 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5864 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5865 }
5866#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005867 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305868 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005869 HS20_OUI_TYPE_SIZE)) )
5870 {
5871 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305872 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005873 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005874
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005875 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
5876 {
Jeff Johnson902c9832012-12-10 14:28:09 -08005877 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
5878 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005879 VOS_ASSERT(0);
5880 return -ENOMEM;
5881 }
5882 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
5883 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005884
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -07005885 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
5886 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
5887 }
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07005888
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -07005889 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
5890
5891 /* populating as ADDIE in beacon frames */
5892 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5893 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2,
5894 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
5895 {
5896 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5897 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
5898 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5899 {
5900 hddLog(LOGE,
5901 "Coldn't pass "
5902 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
5903 }
5904 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
5905 else
5906 hddLog(LOGE,
5907 "Could not pass on "
5908 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
5909
5910 /* IBSS mode doesn't contain params->proberesp_ies still
5911 beaconIE's need to be populated in probe response frames */
5912 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
5913 {
5914 u16 rem_probe_resp_ie_len = eLen + 2;
5915 u8 probe_rsp_ie_len[3] = {0};
5916 u8 counter = 0;
5917
5918 /* Check Probe Resp Length if it is greater then 255 then
5919 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
5920 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
5921 not able Store More then 255 bytes into One Variable */
5922
5923 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
5924 {
5925 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
5926 {
5927 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
5928 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
5929 }
5930 else
5931 {
5932 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
5933 rem_probe_resp_ie_len = 0;
5934 }
5935 }
5936
5937 rem_probe_resp_ie_len = 0;
5938
5939 if (probe_rsp_ie_len[0] > 0)
5940 {
5941 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5942 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
5943 (tANI_U8*)(genie - 2),
5944 probe_rsp_ie_len[0], NULL,
5945 eANI_BOOLEAN_FALSE)
5946 == eHAL_STATUS_FAILURE)
5947 {
5948 hddLog(LOGE,
5949 "Could not pass"
5950 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
5951 }
5952 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
5953 }
5954
5955 if (probe_rsp_ie_len[1] > 0)
5956 {
5957 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5958 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
5959 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
5960 probe_rsp_ie_len[1], NULL,
5961 eANI_BOOLEAN_FALSE)
5962 == eHAL_STATUS_FAILURE)
5963 {
5964 hddLog(LOGE,
5965 "Could not pass"
5966 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
5967 }
5968 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
5969 }
5970
5971 if (probe_rsp_ie_len[2] > 0)
5972 {
5973 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
5974 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
5975 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
5976 probe_rsp_ie_len[2], NULL,
5977 eANI_BOOLEAN_FALSE)
5978 == eHAL_STATUS_FAILURE)
5979 {
5980 hddLog(LOGE,
5981 "Could not pass"
5982 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
5983 }
5984 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
5985 }
5986
5987 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
5988 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
5989 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
5990 {
5991 hddLog(LOGE,
5992 "Could not pass"
5993 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
5994 }
5995 }
5996 else
5997 {
5998 // Reset WNI_CFG_PROBE_RSP Flags
5999 wlan_hdd_reset_prob_rspies(pAdapter);
6000
6001 hddLog(VOS_TRACE_LEVEL_INFO,
6002 "%s: No Probe Response IE received in set beacon",
6003 __func__);
6004 }
6005 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -07006006 break;
6007 case DOT11F_EID_RSN:
6008 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
6009 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
6010 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
6011 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
6012 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
6013 break;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006014 /* Appending Extended Capabilities with Interworking bit set in Assoc Req */
6015 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306016 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006017 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306018 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006019 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306020
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006021 if( SIR_MAC_MAX_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
6022 {
Jeff Johnson902c9832012-12-10 14:28:09 -08006023 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
6024 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006025 VOS_ASSERT(0);
6026 return -ENOMEM;
6027 }
6028 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
6029 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306030
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006031 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
6032 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
6033 break;
6034 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006035#ifdef FEATURE_WLAN_WAPI
6036 case WLAN_EID_WAPI:
6037 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006038 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07006039 pAdapter->wapi_info.nWapiMode);
6040 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306041 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -07006042 akmsuiteCount = WPA_GET_LE16(tmp);
6043 tmp = tmp + 1;
6044 akmlist = (int *)(tmp);
6045 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
6046 {
6047 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
6048 }
6049 else
6050 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006051 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -07006052 VOS_ASSERT(0);
6053 return -EINVAL;
6054 }
6055
6056 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
6057 {
6058 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006059 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006060 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306061 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006062 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306063 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006064 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07006065 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006066 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
6067 }
6068 break;
6069#endif
6070 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -07006073 /* when Unknown IE is received we should break and continue
6074 * to the next IE in the buffer instead we were returning
6075 * so changing this to break */
6076 break;
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 }
6078 genie += eLen;
6079 remLen -= eLen;
6080 }
6081 EXIT();
6082 return 0;
6083}
6084
6085/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +05306086 * FUNCTION: hdd_isWPAIEPresent
6087 * Parse the received IE to find the WPA IE
6088 *
6089 */
6090static bool hdd_isWPAIEPresent(u8 *ie, u8 ie_len)
6091{
6092 v_U8_t eLen = 0;
6093 v_U16_t remLen = ie_len;
6094 v_U8_t elementId = 0;
6095
6096 while (remLen >= 2)
6097 {
6098 elementId = *ie++;
6099 eLen = *ie++;
6100 remLen -= 2;
6101 if (eLen > remLen)
6102 {
6103 hddLog(VOS_TRACE_LEVEL_ERROR,
6104 "%s: IE length is wrong %d", __func__, eLen);
6105 return FALSE;
6106 }
6107 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
6108 {
6109 /* OUI - 0x00 0X50 0XF2
6110 WPA Information Element - 0x01
6111 WPA version - 0x01*/
6112 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
6113 return TRUE;
6114 }
6115 ie += eLen;
6116 remLen -= eLen;
6117 }
6118 return FALSE;
6119}
6120
6121/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006122 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306123 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006124 * parameters during connect operation.
6125 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126int wlan_hdd_cfg80211_set_privacy( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 struct cfg80211_connect_params *req
6128 )
6129{
6130 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306131 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006132 ENTER();
6133
6134 /*set wpa version*/
6135 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
6136
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306137 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +05306139 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -07006140 {
6141 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6142 }
6143 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
6144 {
6145 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6146 }
6147 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306148
6149 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006150 pWextState->wpaVersion);
6151
6152 /*set authentication type*/
6153 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
6154
6155 if (0 > status)
6156 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306157 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006158 "%s: failed to set authentication type ", __func__);
6159 return status;
6160 }
6161
6162 /*set key mgmt type*/
6163 if (req->crypto.n_akm_suites)
6164 {
6165 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
6166 if (0 > status)
6167 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -07006169 __func__);
6170 return status;
6171 }
6172 }
6173
6174 /*set pairwise cipher type*/
6175 if (req->crypto.n_ciphers_pairwise)
6176 {
6177 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
6178 req->crypto.ciphers_pairwise[0], true);
6179 if (0 > status)
6180 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306181 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006182 "%s: failed to set unicast cipher type", __func__);
6183 return status;
6184 }
6185 }
6186 else
6187 {
6188 /*Reset previous cipher suite to none*/
6189 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
6190 if (0 > status)
6191 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306192 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006193 "%s: failed to set unicast cipher type", __func__);
6194 return status;
6195 }
6196 }
6197
6198 /*set group cipher type*/
6199 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
6200 false);
6201
6202 if (0 > status)
6203 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -07006205 __func__);
6206 return status;
6207 }
6208
Chet Lanctot186b5732013-03-18 10:26:30 -07006209#ifdef WLAN_FEATURE_11W
6210 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
6211#endif
6212
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
6214 if (req->ie_len)
6215 {
6216 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
6217 if ( 0 > status)
6218 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306219 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006220 __func__);
6221 return status;
6222 }
6223 }
6224
6225 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306226 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006227 {
6228 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
6229 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
6230 )
6231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306232 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -07006233 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
6234 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306235 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 __func__);
6237 return -EOPNOTSUPP;
6238 }
6239 else
6240 {
6241 u8 key_len = req->key_len;
6242 u8 key_idx = req->key_idx;
6243
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306244 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006245 && (CSR_MAX_NUM_KEY > key_idx)
6246 )
6247 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306248 hddLog(VOS_TRACE_LEVEL_INFO,
6249 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006250 __func__, key_idx, key_len);
6251 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306252 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306254 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -07006255 (u8)key_len;
6256 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
6257 }
6258 }
6259 }
6260 }
6261
6262 return status;
6263}
6264
6265/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306266 * FUNCTION: wlan_hdd_try_disconnect
6267 * This function is used to disconnect from previous
6268 * connection
6269 */
6270static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
6271{
6272 long ret = 0;
6273 hdd_station_ctx_t *pHddStaCtx;
6274 eMib_dot11DesiredBssType connectedBssType;
6275
6276 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6277
6278 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
6279
6280 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
6281 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
6282 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
6283 {
6284 /* Issue disconnect to CSR */
6285 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6286 if( eHAL_STATUS_SUCCESS ==
6287 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6288 pAdapter->sessionId,
6289 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
6290 {
6291 ret = wait_for_completion_interruptible_timeout(
6292 &pAdapter->disconnect_comp_var,
6293 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6294 if (0 >= ret)
6295 {
6296 hddLog(LOGE, FL("Failed to receive disconnect event"));
6297 return -EALREADY;
6298 }
6299 }
6300 }
6301 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
6302 {
6303 ret = wait_for_completion_interruptible_timeout(
6304 &pAdapter->disconnect_comp_var,
6305 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
6306 if (0 >= ret)
6307 {
6308 hddLog(LOGE, FL("Failed to receive disconnect event"));
6309 return -EALREADY;
6310 }
6311 }
6312
6313 return 0;
6314}
6315
6316/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006317 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306318 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006319 * parameters during connect operation.
6320 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306321static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006322 struct net_device *ndev,
6323 struct cfg80211_connect_params *req
6324 )
6325{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306326 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306327 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006328 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006329 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006330
6331 ENTER();
6332
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006333 if (!pAdapter)
6334 {
6335 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6336 "%s: Adapter context is null", __func__);
6337 return VOS_STATUS_E_FAILURE;
6338 }
6339
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306340 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006341 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006342
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306343 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08006344 if (!pHddCtx)
6345 {
6346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6347 "%s: HDD context is null", __func__);
6348 return VOS_STATUS_E_FAILURE;
6349 }
6350
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306351 status = wlan_hdd_validate_context(pHddCtx);
6352
6353 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306355 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6356 "%s: HDD context is not valid", __func__);
6357 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006358 }
6359
6360#ifdef WLAN_BTAMP_FEATURE
6361 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306362 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306364 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -08006366 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -07006367 }
6368#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306369
6370 //If Device Mode is Station Concurrent Sessions Exit BMps
6371 //P2P Mode will be taken care in Open/close adapter
6372 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
6373 (vos_concurrent_sessions_running()))
6374 {
6375 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
6376 }
6377
6378 /*Try disconnecting if already in connected state*/
6379 status = wlan_hdd_try_disconnect(pAdapter);
6380 if ( 0 > status)
6381 {
6382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6383 " connection"));
6384 return -EALREADY;
6385 }
6386
Jeff Johnson295189b2012-06-20 16:38:30 -07006387 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306388 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -07006389
6390 if ( 0 > status)
6391 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306392 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -07006393 __func__);
6394 return status;
6395 }
6396
Mohit Khanna765234a2012-09-11 15:08:35 -07006397 if ( req->channel )
6398 {
6399 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
6400 req->ssid_len, req->bssid,
6401 req->channel->hw_value);
6402 }
6403 else
6404 {
6405 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306406 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -07006407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006408
6409 if (0 > status)
6410 {
6411 //ReEnable BMPS if disabled
6412 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
6413 (NULL != pHddCtx))
6414 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05306415 if (pHddCtx->hdd_wlan_suspended)
6416 {
6417 hdd_set_pwrparams(pHddCtx);
6418 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006419 //ReEnable Bmps and Imps back
6420 hdd_enable_bmps_imps(pHddCtx);
6421 }
6422
6423 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6424 return status;
6425 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306426 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006427 EXIT();
6428 return status;
6429}
6430
6431
6432/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306433 * FUNCTION: wlan_hdd_disconnect
6434 * This function is used to issue a disconnect request to SME
6435 */
6436int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
6437{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306438 int status;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306440 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306441 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306442
6443 status = wlan_hdd_validate_context(pHddCtx);
6444
6445 if (0 != status)
6446 {
6447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6448 "%s: HDD context is not valid", __func__);
6449 return status;
6450 }
6451
6452 pHddCtx->isAmpAllowed = VOS_TRUE;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306453 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306454 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306455
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306456 /*issue disconnect*/
6457 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
6458 pAdapter->sessionId, reason);
6459
6460 if ( 0 != status )
6461 {
6462 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006463 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306464 __func__, (int)status );
6465 return -EINVAL;
6466 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306467 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306468 &pAdapter->disconnect_comp_var,
6469 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306470 if (ret <= 0)
6471 {
6472 hddLog(VOS_TRACE_LEVEL_ERROR,
6473 FL("wait on disconnect_comp_var failed %ld"), ret);
6474 }
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306475 /*stop tx queues*/
6476 netif_tx_disable(pAdapter->dev);
6477 netif_carrier_off(pAdapter->dev);
6478 return status;
6479}
6480
6481
6482/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006483 * FUNCTION: wlan_hdd_cfg80211_disconnect
6484 * This function is used to issue a disconnect request to SME
6485 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306486static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006487 struct net_device *dev,
6488 u16 reason
6489 )
6490{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
6492 tCsrRoamProfile *pRoamProfile =
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306494 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006495 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006496 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306497#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006498 tANI_U8 staIdx;
6499#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306500
Jeff Johnson295189b2012-06-20 16:38:30 -07006501 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306502
Arif Hussain6d2a3322013-11-17 19:50:10 -08006503 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006504 __func__,pAdapter->device_mode);
6505
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306506 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
6507 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -07006508
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306509 status = wlan_hdd_validate_context(pHddCtx);
6510
6511 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006512 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306513 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6514 "%s: HDD context is not valid", __func__);
6515 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006516 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306517
Jeff Johnson295189b2012-06-20 16:38:30 -07006518 if (NULL != pRoamProfile)
6519 {
6520 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306521 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
6522 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -07006523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306524 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -07006525 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306526 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -07006527 switch(reason)
6528 {
6529 case WLAN_REASON_MIC_FAILURE:
6530 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
6531 break;
6532
6533 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
6534 case WLAN_REASON_DISASSOC_AP_BUSY:
6535 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
6536 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
6537 break;
6538
6539 case WLAN_REASON_PREV_AUTH_NOT_VALID:
6540 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
6541 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
6542 break;
6543
6544 case WLAN_REASON_DEAUTH_LEAVING:
6545 default:
6546 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
6547 break;
6548 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306549 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
6550 pScanInfo = &pHddCtx->scan_info;
6551 if (pScanInfo->mScanPending)
6552 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306553 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306554 "Aborting Scan");
Srinivas, Dasari138af4f2014-02-07 11:13:45 +05306555 hdd_abort_mac_scan(pHddCtx, pAdapter->sessionId,
6556 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +05306557 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006558
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006559#ifdef FEATURE_WLAN_TDLS
6560 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006561 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006562 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006563 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
6564 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006565 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006566 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006567 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08006568 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006569 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006570 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07006571 MAC_ADDR_ARRAY(mac));
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006572 sme_DeleteTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala4327a152013-03-04 23:22:42 -08006573 pAdapter->sessionId,
6574 mac);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -08006575 }
6576 }
6577#endif
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306578 status = wlan_hdd_disconnect(pAdapter, reasonCode);
6579 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -07006580 {
6581 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006582 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006583 __func__, (int)status );
6584 return -EINVAL;
6585 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006586 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +05306587 else
6588 {
6589 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
6590 "called while in %d state", __func__,
6591 pHddStaCtx->conn_info.connState);
6592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006593 }
6594 else
6595 {
6596 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
6597 }
6598
6599 return status;
6600}
6601
Gopichand Nakkala78a6c812013-05-13 16:39:49 +05306602
Jeff Johnson295189b2012-06-20 16:38:30 -07006603/*
6604 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306605 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -07006606 * settings in IBSS mode.
6607 */
6608static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306609 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 struct cfg80211_ibss_params *params
6611 )
6612{
6613 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306614 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006615 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
6616 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306617
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 ENTER();
6619
6620 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -07006621 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006622
6623 if (params->ie_len && ( NULL != params->ie) )
6624 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006625 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6626 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006627 {
6628 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
6629 encryptionType = eCSR_ENCRYPT_TYPE_AES;
6630 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006631 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -07006632 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006633 tDot11fIEWPA dot11WPAIE;
6634 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006635 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006636
Wilson Yang00256342013-10-10 23:13:38 -07006637 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006638 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
6639 params->ie_len, DOT11F_EID_WPA);
6640 if ( NULL != ie )
6641 {
6642 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
6643 // Unpack the WPA IE
6644 //Skip past the EID byte and length byte - and four byte WiFi OUI
6645 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
6646 &ie[2+4],
6647 ie[1] - 4,
6648 &dot11WPAIE);
6649 /*Extract the multicast cipher, the encType for unicast
6650 cipher for wpa-none is none*/
6651 encryptionType =
6652 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
6653 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006654 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -07006655
Jeff Johnson295189b2012-06-20 16:38:30 -07006656 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
6657
6658 if (0 > status)
6659 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306660 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -07006661 __func__);
6662 return status;
6663 }
6664 }
6665
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306666 pWextState->roamProfile.AuthType.authType[0] =
6667 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -07006668 eCSR_AUTH_TYPE_OPEN_SYSTEM;
6669
6670 if (params->privacy)
6671 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306672 /* Security enabled IBSS, At this time there is no information available
6673 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -07006674 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306675 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -07006676 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306677 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -07006678 *enable privacy bit in beacons */
6679
6680 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
6681 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -07006682 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
6683 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -07006684 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
6685 pWextState->roamProfile.EncryptionType.numEntries = 1;
6686 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -07006687 return status;
6688}
6689
6690/*
6691 * FUNCTION: wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306692 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306694static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 struct net_device *dev,
6696 struct cfg80211_ibss_params *params
6697 )
6698{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006700 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6701 tCsrRoamProfile *pRoamProfile;
6702 int status;
krunal sonie9002db2013-11-25 14:24:17 -08006703 bool alloc_bssid = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006704 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306705 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07006706
6707 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306708
6709 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006710 "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006711
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306712 status = wlan_hdd_validate_context(pHddCtx);
6713
6714 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07006715 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6717 "%s: HDD context is not valid", __func__);
6718 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 }
6720
6721 if (NULL == pWextState)
6722 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006723 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006724 __func__);
6725 return -EIO;
6726 }
6727
Vinay Krishna Eranna21042322014-01-08 19:21:39 +05306728 /*Try disconnecting if already in connected state*/
6729 status = wlan_hdd_try_disconnect(pAdapter);
6730 if ( 0 > status)
6731 {
6732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
6733 " IBSS connection"));
6734 return -EALREADY;
6735 }
6736
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 pRoamProfile = &pWextState->roamProfile;
6738
6739 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
6740 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306741 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006742 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 return -EINVAL;
6744 }
6745
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006746 /* BSSID is provided by upper layers hence no need to AUTO generate */
6747 if (NULL != params->bssid) {
6748 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6749 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
6750 hddLog (VOS_TRACE_LEVEL_ERROR,
6751 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6752 return -EIO;
6753 }
6754 }
krunal sonie9002db2013-11-25 14:24:17 -08006755 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
6756 {
6757 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
6758 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6759 {
6760 hddLog (VOS_TRACE_LEVEL_ERROR,
6761 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
6762 return -EIO;
6763 }
6764 params->bssid = vos_mem_malloc(sizeof(VOS_MAC_ADDR_SIZE));
6765 if (!params->bssid)
6766 {
6767 hddLog (VOS_TRACE_LEVEL_ERROR,
6768 "%s:Failed memory allocation", __func__);
6769 return -EIO;
6770 }
6771 vos_mem_copy((v_U8_t *)params->bssid,
6772 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
6773 VOS_MAC_ADDR_SIZE);
6774 alloc_bssid = VOS_TRUE;
6775 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -07006776
Jeff Johnson295189b2012-06-20 16:38:30 -07006777 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -07006778 if (NULL !=
6779#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6780 params->chandef.chan)
6781#else
6782 params->channel)
6783#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 {
6785 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006786 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6787 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6788 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6789 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -07006790
6791 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306792 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -07006793 ieee80211_frequency_to_channel(
6794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
6795 params->chandef.chan->center_freq);
6796#else
6797 params->channel->center_freq);
6798#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006799
6800 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6801 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -07006802 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
6804 __func__);
6805 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -07006806 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006807
6808 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006809 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006810 if (channelNum == validChan[indx])
6811 {
6812 break;
6813 }
6814 }
6815 if (indx >= numChans)
6816 {
6817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 __func__, channelNum);
6819 return -EINVAL;
6820 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006821 /* Set the Operational Channel */
6822 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
6823 channelNum);
6824 pRoamProfile->ChannelInfo.numOfChannels = 1;
6825 pHddStaCtx->conn_info.operationChannel = channelNum;
6826 pRoamProfile->ChannelInfo.ChannelList =
6827 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 }
6829
6830 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306831 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -07006832 if (status < 0)
6833 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306834 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -07006835 __func__);
6836 return status;
6837 }
6838
6839 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306840 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -07006841 params->ssid_len, params->bssid,
6842 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -07006843
6844 if (0 > status)
6845 {
6846 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
6847 return status;
6848 }
6849
krunal sonie9002db2013-11-25 14:24:17 -08006850 if (NULL != params->bssid &&
6851 pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0 &&
6852 alloc_bssid == VOS_TRUE)
6853 {
6854 vos_mem_free(params->bssid);
6855 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006856 return 0;
6857}
6858
6859/*
6860 * FUNCTION: wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306861 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -07006862 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306863static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006864 struct net_device *dev
6865 )
6866{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306867 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -07006868 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6869 tCsrRoamProfile *pRoamProfile;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306870 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6871 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006872
6873 ENTER();
6874
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306875 status = wlan_hdd_validate_context(pHddCtx);
6876
6877 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006878 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306879 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6880 "%s: HDD context is not valid", __func__);
6881 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006882 }
6883
Arif Hussain6d2a3322013-11-17 19:50:10 -08006884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",__func__,pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006885 if (NULL == pWextState)
6886 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08006887 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -07006888 __func__);
6889 return -EIO;
6890 }
6891
6892 pRoamProfile = &pWextState->roamProfile;
6893
6894 /* Issue disconnect only if interface type is set to IBSS */
6895 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
6896 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306897 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -07006898 __func__);
6899 return -EINVAL;
6900 }
6901
6902 /* Issue Disconnect request */
6903 INIT_COMPLETION(pAdapter->disconnect_comp_var);
6904 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
6905 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
6906
6907 return 0;
6908}
6909
6910/*
6911 * FUNCTION: wlan_hdd_cfg80211_set_wiphy_params
6912 * This function is used to set the phy parameters
6913 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
6914 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306915static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07006916 u32 changed)
6917{
6918 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6919 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306920 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07006921
6922 ENTER();
6923
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306924 status = wlan_hdd_validate_context(pHddCtx);
6925
6926 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006927 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6929 "%s: HDD context is not valid", __func__);
6930 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006931 }
6932
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
6934 {
6935 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
6936 WNI_CFG_RTS_THRESHOLD_STAMAX :
6937 wiphy->rts_threshold;
6938
6939 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306940 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -07006941 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306942 hddLog(VOS_TRACE_LEVEL_ERROR,
6943 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006944 __func__, rts_threshold);
6945 return -EINVAL;
6946 }
6947
6948 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
6949 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306952 hddLog(VOS_TRACE_LEVEL_ERROR,
6953 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 __func__, rts_threshold);
6955 return -EIO;
6956 }
6957
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306958 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006959 rts_threshold);
6960 }
6961
6962 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
6963 {
6964 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
6965 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
6966 wiphy->frag_threshold;
6967
6968 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306969 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -07006970 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306971 hddLog(VOS_TRACE_LEVEL_ERROR,
6972 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 frag_threshold);
6974 return -EINVAL;
6975 }
6976
6977 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
6978 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306979 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006980 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306981 hddLog(VOS_TRACE_LEVEL_ERROR,
6982 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07006983 __func__, frag_threshold);
6984 return -EIO;
6985 }
6986
6987 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
6988 frag_threshold);
6989 }
6990
6991 if ((changed & WIPHY_PARAM_RETRY_SHORT)
6992 || (changed & WIPHY_PARAM_RETRY_LONG))
6993 {
6994 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
6995 wiphy->retry_short :
6996 wiphy->retry_long;
6997
6998 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
6999 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
7000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 __func__, retry_value);
7003 return -EINVAL;
7004 }
7005
7006 if (changed & WIPHY_PARAM_RETRY_SHORT)
7007 {
7008 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
7009 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307010 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307012 hddLog(VOS_TRACE_LEVEL_ERROR,
7013 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 __func__, retry_value);
7015 return -EIO;
7016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307017 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 __func__, retry_value);
7019 }
7020 else if (changed & WIPHY_PARAM_RETRY_SHORT)
7021 {
7022 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
7023 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307024 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007025 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307026 hddLog(VOS_TRACE_LEVEL_ERROR,
7027 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007028 __func__, retry_value);
7029 return -EIO;
7030 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307031 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 __func__, retry_value);
7033 }
7034 }
7035
7036 return 0;
7037}
7038
7039/*
7040 * FUNCTION: wlan_hdd_cfg80211_set_txpower
7041 * This function is used to set the txpower
7042 */
7043static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -07007044#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7045 struct wireless_dev *wdev,
7046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007047#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307048 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007049#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307050 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -07007051#endif
7052 int dbm)
7053{
7054 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307055 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07007056 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
7057 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307058 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007059
7060 ENTER();
7061
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307062 status = wlan_hdd_validate_context(pHddCtx);
7063
7064 if (0 != status)
7065 {
7066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7067 "%s: HDD context is not valid", __func__);
7068 return status;
7069 }
7070
7071 hHal = pHddCtx->hHal;
7072
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307073 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
7074 dbm, ccmCfgSetCallback,
7075 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307077 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
7079 return -EIO;
7080 }
7081
7082 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
7083 dbm);
7084
7085 switch(type)
7086 {
7087 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
7088 /* Fall through */
7089 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
7090 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
7091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307092 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
7093 __func__);
7094 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -07007095 }
7096 break;
7097 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307098 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -07007099 __func__);
7100 return -EOPNOTSUPP;
7101 break;
7102 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
7104 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -07007105 return -EIO;
7106 }
7107
7108 return 0;
7109}
7110
7111/*
7112 * FUNCTION: wlan_hdd_cfg80211_get_txpower
7113 * This function is used to read the txpower
7114 */
Yue Maf49ba872013-08-19 12:04:25 -07007115static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
7116#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
7117 struct wireless_dev *wdev,
7118#endif
7119 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -07007120{
7121
7122 hdd_adapter_t *pAdapter;
7123 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307124 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007125
Jeff Johnsone7245742012-09-05 17:12:55 -07007126 ENTER();
7127
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307128 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007129
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307130 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007131 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7133 "%s: HDD context is not valid", __func__);
7134 *dbm = 0;
7135 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007136 }
7137
Jeff Johnson295189b2012-06-20 16:38:30 -07007138 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
7139 if (NULL == pAdapter)
7140 {
7141 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
7142 return -ENOENT;
7143 }
7144
7145 wlan_hdd_get_classAstats(pAdapter);
7146 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
7147
Jeff Johnsone7245742012-09-05 17:12:55 -07007148 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007149 return 0;
7150}
7151
7152static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
7153 u8* mac, struct station_info *sinfo)
7154{
7155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
7156 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7157 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
7158 tANI_U8 rate_flags;
7159
7160 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
7161 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07007162
7163 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
7164 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
7165 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
7166 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
7167 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
7168 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
7169 tANI_U16 maxRate = 0;
7170 tANI_U16 myRate;
7171 tANI_U16 currentRate = 0;
7172 tANI_U8 maxSpeedMCS = 0;
7173 tANI_U8 maxMCSIdx = 0;
7174 tANI_U8 rateFlag = 1;
7175 tANI_U8 i, j, rssidx;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -07007176 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307177 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007178
Leo Chang6f8870f2013-03-26 18:11:36 -07007179#ifdef WLAN_FEATURE_11AC
7180 tANI_U32 vht_mcs_map;
7181 eDataRate11ACMaxMcs vhtMaxMcs;
7182#endif /* WLAN_FEATURE_11AC */
7183
Jeff Johnsone7245742012-09-05 17:12:55 -07007184 ENTER();
7185
Jeff Johnson295189b2012-06-20 16:38:30 -07007186 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
7187 (0 == ssidlen))
7188 {
7189 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
7190 " Invalid ssidlen, %d", __func__, ssidlen);
7191 /*To keep GUI happy*/
7192 return 0;
7193 }
7194
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307195 status = wlan_hdd_validate_context(pHddCtx);
7196
7197 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007198 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307199 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7200 "%s: HDD context is not valid", __func__);
7201 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007202 }
7203
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007204 wlan_hdd_get_station_stats(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007205 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
7206
Kiet Lam3b17fc82013-09-27 05:24:08 +05307207 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
7208 sinfo->filled |= STATION_INFO_SIGNAL;
7209
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 //convert to the UI units of 100kbps
7211 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
7212
7213#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -07007214 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 -07007215 sinfo->signal,
7216 pCfg->reportMaxLinkSpeed,
7217 myRate,
7218 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007219 (int) pCfg->linkSpeedRssiMid,
7220 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -07007221 (int) rate_flags,
7222 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07007223#endif //LINKSPEED_DEBUG_ENABLED
7224
7225 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
7226 {
7227 // we do not want to necessarily report the current speed
7228 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
7229 {
7230 // report the max possible speed
7231 rssidx = 0;
7232 }
7233 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
7234 {
7235 // report the max possible speed with RSSI scaling
7236 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
7237 {
7238 // report the max possible speed
7239 rssidx = 0;
7240 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007241 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007242 {
7243 // report middle speed
7244 rssidx = 1;
7245 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007246 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
7247 {
7248 // report middle speed
7249 rssidx = 2;
7250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007251 else
7252 {
7253 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007254 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -07007255 }
7256 }
7257 else
7258 {
7259 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
7260 hddLog(VOS_TRACE_LEVEL_ERROR,
7261 "%s: Invalid value for reportMaxLinkSpeed: %u",
7262 __func__, pCfg->reportMaxLinkSpeed);
7263 rssidx = 0;
7264 }
7265
7266 maxRate = 0;
7267
7268 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307269 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
7270 OperationalRates, &ORLeng))
7271 {
7272 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7273 /*To keep GUI happy*/
7274 return 0;
7275 }
7276
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 for (i = 0; i < ORLeng; i++)
7278 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007279 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 {
7281 /* Validate Rate Set */
7282 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
7283 {
7284 currentRate = supported_data_rate[j].supported_rate[rssidx];
7285 break;
7286 }
7287 }
7288 /* Update MAX rate */
7289 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7290 }
7291
7292 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307293 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
7294 ExtendedRates, &ERLeng))
7295 {
7296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7297 /*To keep GUI happy*/
7298 return 0;
7299 }
7300
Jeff Johnson295189b2012-06-20 16:38:30 -07007301 for (i = 0; i < ERLeng; i++)
7302 {
Jeff Johnsone7245742012-09-05 17:12:55 -07007303 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007304 {
7305 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
7306 {
7307 currentRate = supported_data_rate[j].supported_rate[rssidx];
7308 break;
7309 }
7310 }
7311 /* Update MAX rate */
7312 maxRate = (currentRate > maxRate)?currentRate:maxRate;
7313 }
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307314 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307315 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307316 if we have good rssi */
Kaushik, Sushantdc304d82014-01-22 10:58:37 +05307317 if ((0 == rssidx) ||
Kiet Lamb69f8dc2013-11-15 15:34:27 +05307318 (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed))
Jeff Johnson295189b2012-06-20 16:38:30 -07007319 {
Gopichand Nakkala05ab1322013-02-15 11:28:38 +05307320 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
7321 MCSRates, &MCSLeng))
7322 {
7323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
7324 /*To keep GUI happy*/
7325 return 0;
7326 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007327 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -07007328#ifdef WLAN_FEATURE_11AC
7329 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307330 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007332 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307333 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -07007334 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -07007335 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007336 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -07007337 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007338 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 {
Leo Chang6f8870f2013-03-26 18:11:36 -07007340 maxMCSIdx = 7;
7341 }
7342 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
7343 {
7344 maxMCSIdx = 8;
7345 }
7346 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
7347 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307348 //VHT20 is supporting 0~8
7349 if (rate_flags & eHAL_TX_RATE_VHT20)
7350 maxMCSIdx = 8;
7351 else
7352 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -07007353 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307354
7355 if (rate_flags & eHAL_TX_RATE_VHT80)
7356 {
7357 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
7358 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
7359 }
7360 else if (rate_flags & eHAL_TX_RATE_VHT40)
7361 {
7362 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
7363 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
7364 }
7365 else if (rate_flags & eHAL_TX_RATE_VHT20)
7366 {
7367 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
7368 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
7369 }
7370
Leo Chang6f8870f2013-03-26 18:11:36 -07007371 maxSpeedMCS = 1;
7372 if (currentRate > maxRate)
7373 {
7374 maxRate = currentRate;
7375 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307376
Leo Chang6f8870f2013-03-26 18:11:36 -07007377 }
7378 else
7379#endif /* WLAN_FEATURE_11AC */
7380 {
7381 if (rate_flags & eHAL_TX_RATE_HT40)
7382 {
7383 rateFlag |= 1;
7384 }
7385 if (rate_flags & eHAL_TX_RATE_SGI)
7386 {
7387 rateFlag |= 2;
7388 }
7389
7390 for (i = 0; i < MCSLeng; i++)
7391 {
7392 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
7393 for (j = 0; j < temp; j++)
7394 {
7395 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
7396 {
7397 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
7398 break;
7399 }
7400 }
7401 if ((j < temp) && (currentRate > maxRate))
7402 {
7403 maxRate = currentRate;
7404 maxSpeedMCS = 1;
7405 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
7406 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007407 }
7408 }
7409 }
7410
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307411 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
7412 {
7413 maxRate = myRate;
7414 maxSpeedMCS = 1;
7415 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7416 }
7417
Jeff Johnson295189b2012-06-20 16:38:30 -07007418 // make sure we report a value at least as big as our current rate
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -07007419 if (((maxRate < myRate) && (0 == rssidx)) ||
7420 (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -07007421 {
7422 maxRate = myRate;
7423 if (rate_flags & eHAL_TX_RATE_LEGACY)
7424 {
7425 maxSpeedMCS = 0;
7426 }
7427 else
7428 {
7429 maxSpeedMCS = 1;
7430 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
7431 }
7432 }
7433
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307434 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 {
7436 sinfo->txrate.legacy = maxRate;
7437#ifdef LINKSPEED_DEBUG_ENABLED
7438 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
7439#endif //LINKSPEED_DEBUG_ENABLED
7440 }
7441 else
7442 {
7443 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -07007444#ifdef WLAN_FEATURE_11AC
7445 sinfo->txrate.nss = 1;
7446 if (rate_flags & eHAL_TX_RATE_VHT80)
7447 {
7448 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307449 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -07007450 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307451 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -07007452 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307453 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7454 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7455 }
7456 else if (rate_flags & eHAL_TX_RATE_VHT20)
7457 {
7458 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7459 }
7460#endif /* WLAN_FEATURE_11AC */
7461 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
7462 {
7463 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7464 if (rate_flags & eHAL_TX_RATE_HT40)
7465 {
7466 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7467 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007468 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 if (rate_flags & eHAL_TX_RATE_SGI)
7470 {
7471 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7472 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +05307473
Jeff Johnson295189b2012-06-20 16:38:30 -07007474#ifdef LINKSPEED_DEBUG_ENABLED
7475 pr_info("Reporting MCS rate %d flags %x\n",
7476 sinfo->txrate.mcs,
7477 sinfo->txrate.flags );
7478#endif //LINKSPEED_DEBUG_ENABLED
7479 }
7480 }
7481 else
7482 {
7483 // report current rate instead of max rate
7484
7485 if (rate_flags & eHAL_TX_RATE_LEGACY)
7486 {
7487 //provide to the UI in units of 100kbps
7488 sinfo->txrate.legacy = myRate;
7489#ifdef LINKSPEED_DEBUG_ENABLED
7490 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
7491#endif //LINKSPEED_DEBUG_ENABLED
7492 }
7493 else
7494 {
7495 //must be MCS
7496 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -07007497#ifdef WLAN_FEATURE_11AC
7498 sinfo->txrate.nss = 1;
7499 if (rate_flags & eHAL_TX_RATE_VHT80)
7500 {
7501 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
7502 }
7503 else
7504#endif /* WLAN_FEATURE_11AC */
7505 {
7506 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
7507 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007508 if (rate_flags & eHAL_TX_RATE_SGI)
7509 {
7510 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
7511 }
7512 if (rate_flags & eHAL_TX_RATE_HT40)
7513 {
7514 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7515 }
Leo Chang6f8870f2013-03-26 18:11:36 -07007516#ifdef WLAN_FEATURE_11AC
7517 else if (rate_flags & eHAL_TX_RATE_VHT80)
7518 {
7519 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7520 }
7521#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -07007522#ifdef LINKSPEED_DEBUG_ENABLED
7523 pr_info("Reporting actual MCS rate %d flags %x\n",
7524 sinfo->txrate.mcs,
7525 sinfo->txrate.flags );
7526#endif //LINKSPEED_DEBUG_ENABLED
7527 }
7528 }
7529 sinfo->filled |= STATION_INFO_TX_BITRATE;
7530
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -07007531 sinfo->tx_packets =
7532 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
7533 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
7534 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
7535 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
7536
7537 sinfo->tx_retries =
7538 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
7539 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
7540 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
7541 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
7542
7543 sinfo->tx_failed =
7544 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
7545 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
7546 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
7547 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
7548
7549 sinfo->filled |=
7550 STATION_INFO_TX_PACKETS |
7551 STATION_INFO_TX_RETRIES |
7552 STATION_INFO_TX_FAILED;
7553
7554 EXIT();
7555 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007556}
7557
7558static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -07007559 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -07007560{
7561 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307562 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307564 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007565
Jeff Johnsone7245742012-09-05 17:12:55 -07007566 ENTER();
7567
Jeff Johnson295189b2012-06-20 16:38:30 -07007568 if (NULL == pAdapter)
7569 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007571 return -ENODEV;
7572 }
7573
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307574 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307575 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307576
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307577 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307578 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307579 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7580 "%s: HDD context is not valid", __func__);
7581 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307582 }
7583
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307584 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
7585 (TRUE == pHddCtx->hdd_wlan_suspended) &&
7586 (pHddCtx->cfg_ini->fhostArpOffload) &&
7587 (eConnectionState_Associated ==
7588 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
7589 {
Amar Singhald53568e2013-09-26 11:03:45 -07007590
7591 hddLog(VOS_TRACE_LEVEL_INFO,
7592 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +05307593 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307594 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7595 {
7596 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007597 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +05307598 __func__, vos_status);
7599 }
7600 }
7601
Jeff Johnson295189b2012-06-20 16:38:30 -07007602 /**The get power cmd from the supplicant gets updated by the nl only
7603 *on successful execution of the function call
7604 *we are oppositely mapped w.r.t mode in the driver
7605 **/
7606 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
7607
Jeff Johnsone7245742012-09-05 17:12:55 -07007608 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07007609 if (VOS_STATUS_E_FAILURE == vos_status)
7610 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307611 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7612 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007613 return -EINVAL;
7614 }
7615 return 0;
7616}
7617
7618
7619#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7620static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
7621 struct net_device *netdev,
7622 u8 key_index)
7623{
Jeff Johnsone7245742012-09-05 17:12:55 -07007624 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 return 0;
7626}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307627#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -07007628
7629#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7630static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7631 struct net_device *dev,
7632 struct ieee80211_txq_params *params)
7633{
Jeff Johnsone7245742012-09-05 17:12:55 -07007634 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 return 0;
7636}
7637#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
7638static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
7639 struct ieee80211_txq_params *params)
7640{
Jeff Johnsone7245742012-09-05 17:12:55 -07007641 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 return 0;
7643}
7644#endif //LINUX_VERSION_CODE
7645
7646static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
7647 struct net_device *dev, u8 *mac)
7648{
7649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307650 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007651 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307652 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007653 v_U8_t staId;
Jeff Johnson295189b2012-06-20 16:38:30 -07007654
Jeff Johnsone7245742012-09-05 17:12:55 -07007655 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307656 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -07007657 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307658 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 return -EINVAL;
7660 }
7661
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307662 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7663 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07007664
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307665 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007666 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7668 "%s: HDD context is not valid", __func__);
7669 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007670 }
7671
Jeff Johnson295189b2012-06-20 16:38:30 -07007672 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007673 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -07007674 )
7675 {
7676 if( NULL == mac )
7677 {
7678 v_U16_t i;
7679 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
7680 {
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007681 if ((pAdapter->aStaInfo[i].isUsed) &&
7682 (!pAdapter->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -07007683 {
7684 u8 *macAddr = pAdapter->aStaInfo[i].macAddrSTA.bytes;
7685 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007686 "%s: Delete STA with MAC::"
7687 MAC_ADDRESS_STR,
7688 __func__, MAC_ADDR_ARRAY(macAddr));
Rajesh Chauhan18488fc2013-08-22 10:15:03 -07007689 vos_status = hdd_softap_sta_deauth(pAdapter, macAddr);
7690 if (VOS_IS_STATUS_SUCCESS(vos_status))
7691 pAdapter->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007692 }
7693 }
7694 }
7695 else
7696 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007697
7698 vos_status = hdd_softap_GetStaId(pAdapter,(v_MACADDR_t *)mac, &staId);
7699 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7700 {
7701 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007702 "%s: Skip this DEL STA as this is not used::"
7703 MAC_ADDRESS_STR,
7704 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007705 return -ENOENT;
7706 }
7707
7708 if( pAdapter->aStaInfo[staId].isDeauthInProgress == TRUE)
7709 {
7710 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -08007711 "%s: Skip this DEL STA as deauth is in progress::"
7712 MAC_ADDRESS_STR,
7713 __func__, MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007714 return -ENOENT;
7715 }
7716
7717 pAdapter->aStaInfo[staId].isDeauthInProgress = TRUE;
7718
Jeff Johnson295189b2012-06-20 16:38:30 -07007719 hddLog(VOS_TRACE_LEVEL_INFO,
7720 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007721 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -07007722 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007723 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007724
7725 vos_status = hdd_softap_sta_deauth(pAdapter, mac);
7726 if (!VOS_IS_STATUS_SUCCESS(vos_status))
7727 {
7728 pAdapter->aStaInfo[staId].isDeauthInProgress = FALSE;
7729 hddLog(VOS_TRACE_LEVEL_INFO,
7730 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -08007731 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007732 __func__,
Arif Hussain24bafea2013-11-15 15:10:03 -08007733 MAC_ADDR_ARRAY(mac));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -08007734 return -ENOENT;
7735 }
7736
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 }
7738 }
7739
7740 EXIT();
7741
7742 return 0;
7743}
7744
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007745static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
7746 struct net_device *dev, u8 *mac, struct station_parameters *params)
7747{
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007748 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007749#ifdef FEATURE_WLAN_TDLS
7750 u32 mask, set;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08007751 ENTER();
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007752 mask = params->sta_flags_mask;
7753
7754 set = params->sta_flags_set;
7755
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07007756#ifdef WLAN_FEATURE_TDLS_DEBUG
7757 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7758 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
7759 __func__, mask, set, MAC_ADDR_ARRAY(mac));
7760#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007761
7762 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
7763 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08007764 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007765 }
7766 }
7767#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -08007768 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007769}
7770
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007771
7772#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -07007773#define MAX_PMKSAIDS_IN_CACHE 8
7774
7775static tPmkidCacheInfo PMKIDCache[MAX_PMKSAIDS_IN_CACHE]; // HDD local cache
7776static tANI_U32 PMKIDCacheIndex; // HDD local Cache index
7777
7778
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007779static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -07007780 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007781{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307782 tANI_U32 j=0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7784 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307785 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307786 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007787 tANI_U8 BSSIDMatched = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307788 hdd_context_t *pHddCtx;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007790 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
7791 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Jeff Johnsone7245742012-09-05 17:12:55 -07007792
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307793 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307794 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307796 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007797 return -EINVAL;
7798 }
7799
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307800 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7801 status = wlan_hdd_validate_context(pHddCtx);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007802
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307803 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007804 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307805 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7806 "%s: HDD context is not valid", __func__);
7807 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007808 }
7809
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307810 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007811 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7812
Wilson Yang6507c4e2013-10-01 20:11:19 -07007813 for (j = 0; j < PMKIDCacheIndex; j++)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007814 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307815 if(vos_mem_compare(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007816 pmksa->bssid, WNI_CFG_BSSID_LEN))
7817 {
7818 /* BSSID matched previous entry. Overwrite it. */
7819 BSSIDMatched = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307820 vos_mem_copy(PMKIDCache[j].BSSID,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007821 pmksa->bssid, WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307822 vos_mem_copy(PMKIDCache[j].PMKID,
7823 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007824 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307825 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Reusing cache entry %d.",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007826 __func__, j );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007827 dump_bssid(pmksa->bssid);
7828 dump_pmkid(halHandle, pmksa->pmkid);
7829 break;
7830 }
7831 }
7832
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007833 /* Check we compared all entries,if then take the first slot now */
Wilson Yang6507c4e2013-10-01 20:11:19 -07007834 if(j == MAX_PMKSAIDS_IN_CACHE) PMKIDCacheIndex=0;
Madan Mohan Koyyalamudic4b317d2012-10-18 19:43:08 -07007835
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007836 if (!BSSIDMatched)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307837 {
7838 // Now, we DON'T have a BSSID match, so take a new entry in the cache.
Wilson Yang6507c4e2013-10-01 20:11:19 -07007839 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].BSSID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307840 pmksa->bssid, ETHER_ADDR_LEN);
Wilson Yang6507c4e2013-10-01 20:11:19 -07007841 vos_mem_copy(PMKIDCache[PMKIDCacheIndex].PMKID,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307842 pmksa->pmkid,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007843 CSR_RSN_PMKID_SIZE);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307844 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Adding a new cache entry %d.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007845 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007846 dump_bssid(pmksa->bssid);
7847 dump_pmkid(halHandle, pmksa->pmkid);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307848 // Increment the HDD Local Cache index
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007849 // The "i=0" doesn't work for the call to sme_RoamSetPMKIDCache() - LFR FIXME
Wilson Yang6507c4e2013-10-01 20:11:19 -07007850 if (PMKIDCacheIndex <= (MAX_PMKSAIDS_IN_CACHE-1)) PMKIDCacheIndex++; else PMKIDCacheIndex = 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007851 }
7852
7853
7854 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307855 //hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with %d cache entries."),
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007856 // __func__, i );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307857 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Calling csrRoamSetPMKIDCache with %d cache entries.",
Wilson Yang6507c4e2013-10-01 20:11:19 -07007858 __func__, PMKIDCacheIndex );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007859 // Finally set the PMKSA ID Cache in CSR
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307860 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
7861 PMKIDCache,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007862 PMKIDCacheIndex);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007863 return 0;
7864}
7865
7866
Wilson Yang6507c4e2013-10-01 20:11:19 -07007867
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007868static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -07007869 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007870{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007871 tANI_U32 j=0;
7872 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7873 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007874 tANI_U8 BSSIDMatched = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007875 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -08007876 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007877
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007878 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
7879 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007880
7881 /* Validate pAdapter */
7882 if (NULL == pAdapter)
7883 {
7884 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
7885 return -EINVAL;
7886 }
7887
7888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7889 status = wlan_hdd_validate_context(pHddCtx);
7890
7891 if (0 != status)
7892 {
7893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7894 "%s: HDD context is not valid", __func__);
7895 return status;
7896 }
7897
7898 /*Retrieve halHandle*/
7899 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
7900
7901 /*in case index is 0,no entry to delete*/
7902 if (0 == PMKIDCacheIndex)
7903 {
7904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
7905 __func__);
7906 return -EINVAL;
7907 }
7908
7909 /*find the matching PMKSA entry from j=0 to (index-1),
7910 * and delete the matched one
7911 */
7912 for (j = 0; j<PMKIDCacheIndex; j++)
7913 {
7914 if (vos_mem_compare(PMKIDCache[j].BSSID,
7915 pmksa->bssid,
7916 WNI_CFG_BSSID_LEN))
7917 {
7918 /* BSSID matched entry */
7919 BSSIDMatched = 1;
7920
7921 if (j<PMKIDCacheIndex-1)
7922 {
7923 /*replace the matching entry with the last entry in HDD local cache*/
7924 vos_mem_copy(PMKIDCache[j].BSSID,
7925 PMKIDCache[PMKIDCacheIndex-1].BSSID,
7926 WNI_CFG_BSSID_LEN);
7927 vos_mem_copy(PMKIDCache[j].PMKID,
7928 PMKIDCache[PMKIDCacheIndex-1].PMKID,
7929 CSR_RSN_PMKID_SIZE);
7930 }
7931
7932 /*clear the last entry in HDD cache ---[index-1]*/
Wilson Yang6507c4e2013-10-01 20:11:19 -07007933 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].BSSID, WNI_CFG_BSSID_LEN);
7934 vos_mem_zero(PMKIDCache[PMKIDCacheIndex-1].PMKID, CSR_RSN_PMKID_SIZE);
7935
7936 /*reduce the PMKID array index*/
7937 PMKIDCacheIndex--;
7938
7939 /*delete the last PMKID cache in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08007940 if (eHAL_STATUS_SUCCESS !=
7941 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pmksa->bssid))
Wilson Yang6507c4e2013-10-01 20:11:19 -07007942 {
7943 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: cannot delete PMKSA %d CONTENT.",
7944 __func__,PMKIDCacheIndex);
Wilson Yangef657d32014-01-15 19:19:23 -08007945 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007946 }
7947
7948 dump_bssid(pmksa->bssid);
7949 dump_pmkid(halHandle,pmksa->pmkid);
7950
7951 break;
7952 }
7953 }
7954
7955 /* we compare all entries,but cannot find matching entry */
7956 if (j == MAX_PMKSAIDS_IN_CACHE && !BSSIDMatched)
7957 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07007958 hddLog(VOS_TRACE_LEVEL_FATAL,
7959 "%s: No such PMKSA entry existed " MAC_ADDRESS_STR,
7960 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
Wilson Yang6507c4e2013-10-01 20:11:19 -07007961 dump_bssid(pmksa->bssid);
7962 dump_pmkid(halHandle, pmksa->pmkid);
7963 return -EINVAL;
7964 }
Wilson Yangef657d32014-01-15 19:19:23 -08007965 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007966}
7967
Wilson Yang6507c4e2013-10-01 20:11:19 -07007968
7969
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007970static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
7971{
Wilson Yang6507c4e2013-10-01 20:11:19 -07007972 tANI_U32 j=0;
7973 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7974 tHalHandle halHandle;
7975 hdd_context_t *pHddCtx;
7976 tANI_U8 *pBSSId;
Wilson Yangef657d32014-01-15 19:19:23 -08007977 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -07007978
7979 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: flushing PMKSA ",__func__);
7980
7981 /* Validate pAdapter */
7982 if (NULL == pAdapter)
7983 {
7984 hddLog(VOS_TRACE_LEVEL_ERROR,
7985 "%s: Invalid Adapter" ,__func__);
7986 return -EINVAL;
7987 }
7988
7989 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7990 status = wlan_hdd_validate_context(pHddCtx);
7991
7992 if (0 != status)
7993 {
7994 hddLog(VOS_TRACE_LEVEL_ERROR,
7995 "%s: HDD context is not valid", __func__);
7996 return status;
7997 }
7998
7999 /*Retrieve halHandle*/
8000 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
8001
8002 /*in case index is 0,no entry to delete*/
8003 if (0 == PMKIDCacheIndex)
8004 {
8005 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid entry to delete" ,
8006 __func__);
8007 return -EINVAL;
8008 }
8009
8010 /*delete all the PMKSA one by one */
8011 for (j = 0; j<PMKIDCacheIndex; j++)
8012 {
Wilson Yang6507c4e2013-10-01 20:11:19 -07008013 pBSSId =(tANI_U8 *)(PMKIDCache[j].BSSID);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008014
8015 /*delete the PMKID in CSR*/
Wilson Yangef657d32014-01-15 19:19:23 -08008016 if (eHAL_STATUS_SUCCESS !=
8017 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, pBSSId))
Wilson Yang6507c4e2013-10-01 20:11:19 -07008018 {
8019 hddLog(VOS_TRACE_LEVEL_ERROR ,"%s cannot flush PMKIDCache %d.",
8020 __func__,j);
Wilson Yangef657d32014-01-15 19:19:23 -08008021 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -07008022 }
Kiet Lam8d21d5b2013-10-31 17:18:29 +05308023 /*clear the entry in HDD cache 0--index-1 */
8024 vos_mem_zero(PMKIDCache[j].BSSID, WNI_CFG_BSSID_LEN);
8025 vos_mem_zero(PMKIDCache[j].PMKID, CSR_RSN_PMKID_SIZE);
Wilson Yang6507c4e2013-10-01 20:11:19 -07008026 }
8027
8028 PMKIDCacheIndex = 0;
Wilson Yangef657d32014-01-15 19:19:23 -08008029 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008030}
8031#endif
8032
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008033#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308034static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008035 struct net_device *dev, struct cfg80211_update_ft_ies_params *ftie)
8036{
8037 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8038 hdd_station_ctx_t *pHddStaCtx;
8039
8040 if (NULL == pAdapter)
8041 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008042 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008043 return -ENODEV;
8044 }
8045
8046 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8047
8048 // Added for debug on reception of Re-assoc Req.
8049 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
8050 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008051 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008052 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -08008053 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008054 }
8055
8056#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -08008057 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008058 ftie->ie_len);
8059#endif
8060
8061 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +05308062 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
8063 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07008064 ftie->ie_len);
8065 return 0;
8066}
8067#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008068
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308069#ifdef FEATURE_WLAN_SCAN_PNO
8070
8071void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
8072 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
8073{
8074 int ret;
8075 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
8076 hdd_context_t *pHddCtx;
8077
Nirav Shah80830bf2013-12-31 16:35:12 +05308078 ENTER();
8079
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308080 if (NULL == pAdapter)
8081 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308083 "%s: HDD adapter is Null", __func__);
8084 return ;
8085 }
8086
8087 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8088 if (NULL == pHddCtx)
8089 {
8090 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8091 "%s: HDD context is Null!!!", __func__);
8092 return ;
8093 }
8094
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308095 spin_lock(&pHddCtx->schedScan_lock);
8096 if (TRUE == pHddCtx->isWiphySuspended)
8097 {
8098 pHddCtx->isSchedScanUpdatePending = TRUE;
8099 spin_unlock(&pHddCtx->schedScan_lock);
8100 hddLog(VOS_TRACE_LEVEL_INFO,
8101 "%s: Update cfg80211 scan database after it resume", __func__);
8102 return ;
8103 }
8104 spin_unlock(&pHddCtx->schedScan_lock);
8105
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308106 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
8107
8108 if (0 > ret)
8109 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
8110
8111 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8113 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308114}
8115
8116/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308117 * FUNCTION: wlan_hdd_is_pno_allowed
8118 * To check is there any P2P GO/SAP or P2P Client/STA
8119 * session is active
8120 */
8121static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
8122{
8123 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
8124 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308125 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308126 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8127 int status = 0;
8128 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
8129
8130 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
8131 {
8132 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308133 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308134
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308135 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
8136 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
8137 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
8138 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
8139 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
8140 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308141 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308142 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308143 }
8144 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
8145 pAdapterNode = pNext;
8146 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308147 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308148}
8149
8150/*
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308151 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
8152 * NL interface to enable PNO
8153 */
8154static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
8155 struct net_device *dev, struct cfg80211_sched_scan_request *request)
8156{
8157 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8158 tpSirPNOScanReq pPnoRequest = NULL;
8159 hdd_context_t *pHddCtx;
8160 tHalHandle hHal;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308161 v_U32_t i, indx, num_ch, tempInterval;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308162 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8163 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8164 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8165 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308166 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308167
8168 if (NULL == pAdapter)
8169 {
8170 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8171 "%s: HDD adapter is Null", __func__);
8172 return -ENODEV;
8173 }
8174
8175 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308176 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308177
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308178 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308179 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8181 "%s: HDD context is not valid", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308182 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308183 }
8184
8185 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8186 if (NULL == hHal)
8187 {
8188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8189 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308190 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308191 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308192
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308193 /* The current firmware design for PNO does not consider concurrent
8194 * active sessions.Hence , determine the concurrent active sessions
8195 * and return a failure to the framework on a request for schedule
8196 * scan.
8197 */
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308198 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308199 {
8200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +05308201 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +05308202 return -EBUSY;
8203 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308204
8205 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8206 if (NULL == pPnoRequest)
8207 {
8208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8209 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308210 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308211 }
8212
Madan Mohan Koyyalamudic3f04352013-09-26 19:21:48 +05308213 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308214 pPnoRequest->enable = 1; /*Enable PNO */
8215 pPnoRequest->ucNetworksCount = request->n_match_sets;
8216
8217 if (( !pPnoRequest->ucNetworksCount ) ||
8218 ( pPnoRequest->ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
8219 {
8220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308221 "%s: Network input is not correct %d",
8222 __func__, pPnoRequest->ucNetworksCount);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308223 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308224 goto error;
8225 }
8226
8227 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
8228 {
8229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308230 "%s: Incorrect number of channels %d",
8231 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308232 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308233 goto error;
8234 }
8235
8236 /* Framework provides one set of channels(all)
8237 * common for all saved profile */
8238 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8239 channels_allowed, &num_channels_allowed))
8240 {
8241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8242 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308243 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308244 goto error;
8245 }
8246 /* Checking each channel against allowed channel list */
8247 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +05308248 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308249 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308250 char chList [(request->n_channels*5)+1];
8251 int len;
8252 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308253 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308254 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308255 {
Nirav Shah80830bf2013-12-31 16:35:12 +05308256 if (request->channels[i]->hw_value == channels_allowed[indx])
8257 {
8258 valid_ch[num_ch++] = request->channels[i]->hw_value;
8259 len += snprintf(chList+len, 5, "%d ",
8260 request->channels[i]->hw_value);
8261 break ;
8262 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308263 }
8264 }
Nirav Shah80830bf2013-12-31 16:35:12 +05308265 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
8266 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308267
8268 /* Filling per profile params */
8269 for (i = 0; i < pPnoRequest->ucNetworksCount; i++)
8270 {
8271 pPnoRequest->aNetworks[i].ssId.length =
8272 request->match_sets[i].ssid.ssid_len;
8273
8274 if (( 0 == pPnoRequest->aNetworks[i].ssId.length ) ||
8275 ( pPnoRequest->aNetworks[i].ssId.length > 32 ) )
8276 {
8277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308278 "%s: SSID Len %d is not correct for network %d",
8279 __func__, pPnoRequest->aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308280 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308281 goto error;
8282 }
8283
8284 memcpy(pPnoRequest->aNetworks[i].ssId.ssId,
8285 request->match_sets[i].ssid.ssid,
8286 request->match_sets[i].ssid.ssid_len);
8287 pPnoRequest->aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
8288 pPnoRequest->aNetworks[i].encryption = 0; /*eED_ANY*/
8289 pPnoRequest->aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
8290
8291 /*Copying list of valid channel into request */
8292 memcpy(pPnoRequest->aNetworks[i].aChannels, valid_ch, num_ch);
8293 pPnoRequest->aNetworks[i].ucChannelCount = num_ch;
8294
8295 pPnoRequest->aNetworks[i].rssiThreshold = 0; //Default value
8296 }
8297
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308298 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -08008299 "request->ie_len = %zu", request->ie_len);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +05308300 if ((0 < request->ie_len) && (NULL != request->ie))
8301 {
8302 pPnoRequest->us24GProbeTemplateLen = request->ie_len;
8303 memcpy(&pPnoRequest->p24GProbeTemplate, request->ie,
8304 pPnoRequest->us24GProbeTemplateLen);
8305
8306 pPnoRequest->us5GProbeTemplateLen = request->ie_len;
8307 memcpy(&pPnoRequest->p5GProbeTemplate, request->ie,
8308 pPnoRequest->us5GProbeTemplateLen);
8309 }
8310
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +05308311 /* Driver gets only one time interval which is hardcoded in
8312 * supplicant for 10000ms. Taking power consumption into account 6 timers
8313 * will be used, Timervalue is increased exponentially i.e 10,20,40,
8314 * 80,160,320 secs. And number of scan cycle for each timer
8315 * is configurable through INI param gPNOScanTimerRepeatValue.
8316 * If it is set to 0 only one timer will be used and PNO scan cycle
8317 * will be repeated after each interval specified by supplicant
8318 * till PNO is disabled.
8319 */
8320 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
8321 pPnoRequest->scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
8322 else
8323 pPnoRequest->scanTimers.ucScanTimersCount =
8324 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
8325
8326 tempInterval = (request->interval)/1000;
8327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8328 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
8329 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
8330 for ( i = 0; i < pPnoRequest->scanTimers.ucScanTimersCount; i++)
8331 {
8332 pPnoRequest->scanTimers.aTimerValues[i].uTimerRepeat =
8333 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
8334 pPnoRequest->scanTimers.aTimerValues[i].uTimerValue = tempInterval;
8335 tempInterval *= 2;
8336 }
8337 //Repeat last timer until pno disabled.
8338 pPnoRequest->scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
8339
Madan Mohan Koyyalamudid206c7b2013-09-26 22:54:51 +05308340 pPnoRequest->modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308341
Nirav Shah80830bf2013-12-31 16:35:12 +05308342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8343 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
8344 pAdapter->sessionId, pPnoRequest->enable, pPnoRequest->modePNO,
8345 pPnoRequest->scanTimers.ucScanTimersCount);
8346
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308347 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
8348 pPnoRequest, pAdapter->sessionId,
8349 hdd_cfg80211_sched_scan_done_callback, pAdapter);
8350 if (eHAL_STATUS_SUCCESS != status)
8351 {
8352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +05308353 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308354 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308355 goto error;
8356 }
8357
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8359 "PNO scanRequest offloaded");
8360
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308361error:
8362 vos_mem_free(pPnoRequest);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308363 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308364}
8365
8366/*
8367 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
8368 * NL interface to disable PNO
8369 */
8370static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
8371 struct net_device *dev)
8372{
8373 eHalStatus status = eHAL_STATUS_FAILURE;
8374 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8375 hdd_context_t *pHddCtx;
8376 tHalHandle hHal;
8377 tpSirPNOScanReq pPnoRequest = NULL;
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308378 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308379
8380 ENTER();
8381
8382 if (NULL == pAdapter)
8383 {
8384 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8385 "%s: HDD adapter is Null", __func__);
8386 return -ENODEV;
8387 }
8388
8389 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308390
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308391 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308392 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308393 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308394 "%s: HDD context is Null", __func__);
8395 return -ENODEV;
8396 }
8397
8398 /* The return 0 is intentional when isLogpInProgress and
8399 * isLoadUnloadInProgress. We did observe a crash due to a return of
8400 * failure in sched_scan_stop , especially for a case where the unload
8401 * of the happens at the same time. The function __cfg80211_stop_sched_scan
8402 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
8403 * success. If it returns a failure , then its next invocation due to the
8404 * clean up of the second interface will have the dev pointer corresponding
8405 * to the first one leading to a crash.
8406 */
8407 if (pHddCtx->isLogpInProgress)
8408 {
8409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8410 "%s: LOGP in Progress. Ignore!!!", __func__);
8411 return ret;
8412 }
8413
8414 if (pHddCtx->isLoadUnloadInProgress)
8415 {
8416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8417 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
8418 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308419 }
8420
8421 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8422 if (NULL == hHal)
8423 {
8424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8425 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308426 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308427 }
8428
8429 pPnoRequest = (tpSirPNOScanReq) vos_mem_malloc(sizeof (tSirPNOScanReq));
8430 if (NULL == pPnoRequest)
8431 {
8432 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8433 "%s: vos_mem_malloc failed", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308434 return -ENOMEM;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308435 }
8436
8437 memset(pPnoRequest, 0, sizeof (tSirPNOScanReq));
8438 pPnoRequest->enable = 0; /* Disable PNO */
8439 pPnoRequest->ucNetworksCount = 0;
8440
8441 status = sme_SetPreferredNetworkList(hHal, pPnoRequest,
8442 pAdapter->sessionId,
8443 NULL, pAdapter);
8444 if (eHAL_STATUS_SUCCESS != status)
8445 {
8446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8447 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308448 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308449 }
8450
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05308451 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8452 "%s: PNO scan disabled", __func__);
8453
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308454 vos_mem_free(pPnoRequest);
8455
8456 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +05308457 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05308458}
8459
8460#endif /*FEATURE_WLAN_SCAN_PNO*/
8461
8462
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008463#ifdef FEATURE_WLAN_TDLS
8464static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
8465 u8 *peer, u8 action_code, u8 dialog_token,
8466 u16 status_code, const u8 *buf, size_t len)
8467{
8468
8469 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8470 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008471 u8 peerMac[6];
8472 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008473 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -08008474 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -07008475 long rc;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008476
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008477 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308479 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008480 "Invalid arguments");
8481 return -EINVAL;
8482 }
8483
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008484 if (pHddCtx->isLogpInProgress)
8485 {
8486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8487 "%s:LOGP in Progress. Ignore!!!", __func__);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008488 wlan_hdd_tdls_set_link_status(pAdapter, peer, eTDLS_LINK_IDLE);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008489 return -EBUSY;
8490 }
8491
Hoonki Lee27511902013-03-14 18:19:06 -07008492 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008493 {
Hoonki Lee27511902013-03-14 18:19:06 -07008494 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8495 "%s: TDLS mode is disabled OR not enabled in FW."
8496 MAC_ADDRESS_STR " action %d declined.",
8497 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008498 return -ENOTSUPP;
8499 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008500
Hoonki Lee27511902013-03-14 18:19:06 -07008501 /* other than teardown frame, other mgmt frames are not sent if disabled */
8502 if (SIR_MAC_TDLS_TEARDOWN != action_code)
8503 {
8504 /* if tdls_mode is disabled to respond to peer's request */
8505 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
8506 {
8507 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
8508 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008509 " TDLS mode is disabled. action %d declined.",
8510 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -07008511
8512 return -ENOTSUPP;
8513 }
8514 }
8515
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008516 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
8517 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308518 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008519 {
8520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008521 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008522 " TDLS setup is ongoing. action %d declined.",
8523 __func__, MAC_ADDR_ARRAY(peer), action_code);
8524 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008525 }
8526 }
8527
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008528 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
8529 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -08008530 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008531 if (HDD_MAX_NUM_TDLS_STA <= wlan_hdd_tdlsConnectedPeers(pAdapter))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008532 {
8533 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
8534 we return error code at 'add_station()'. Hence we have this
8535 check again in addtion to add_station().
8536 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008537 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -08008538 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008539 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8540 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008541 " TDLS Max peer already connected. action %d declined.",
8542 __func__, MAC_ADDR_ARRAY(peer), action_code);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308543 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -08008544 }
8545 else
8546 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008547 /* maximum reached. tweak to send error code to peer and return
8548 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008549 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8551 "%s: " MAC_ADDRESS_STR
8552 " TDLS Max peer already connected send response status %d",
8553 __func__, MAC_ADDR_ARRAY(peer), status_code);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008554 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008555 /* fall through to send setup resp with failure status
8556 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -08008557 }
8558 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008559 else
8560 {
8561 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308562 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008563 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008564 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008565 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008566 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
8567 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008568 return -EPERM;
8569 }
8570 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008571 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008572 vos_mem_copy(peerMac, peer, 6);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008573
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008574#ifdef WLAN_FEATURE_TDLS_DEBUG
8575 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008576 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %d",
8577 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
8578 action_code, dialog_token, status_code, len);
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008579#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008580
Hoonki Leea34dd892013-02-05 22:56:02 -08008581 /*Except teardown responder will not be used so just make 0*/
8582 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -08008583 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -08008584 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008585
8586 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308587 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peerMac, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008588
8589 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
8590 responder = pTdlsPeer->is_responder;
8591 else
Hoonki Leea34dd892013-02-05 22:56:02 -08008592 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -07008593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8594 "%s: " MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, len = %d",
8595 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
8596 dialog_token, status_code, len);
8597 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -08008598 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008599 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008600
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308601 /* For explicit trigger of DIS_REQ come out of BMPS for
8602 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -07008603 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308604 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
8605 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -07008606 {
8607 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8608 {
8609 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308610 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Hoonki Lee14621352013-04-16 17:51:19 -07008611 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8612 }
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +05308613 if (SIR_MAC_TDLS_DIS_REQ != action_code)
8614 wlan_hdd_tdls_set_cap(pAdapter, peerMac, eTDLS_CAP_SUPPORTED);
Hoonki Lee14621352013-04-16 17:51:19 -07008615 }
8616
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008617 /* make sure doesn't call send_mgmt() while it is pending */
8618 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
8619 {
8620 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008621 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008622 __func__, MAC_ADDR_ARRAY(peer), action_code);
8623 return -EBUSY;
8624 }
8625
8626 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008627 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
8628
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008629 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Hoonki Leea34dd892013-02-05 22:56:02 -08008630 peerMac, action_code, dialog_token, status_code, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008631
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008632 if (VOS_STATUS_SUCCESS != status)
8633 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8635 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008636 pAdapter->mgmtTxCompletionStatus = FALSE;
Hoonki Lee14621352013-04-16 17:51:19 -07008637 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308638 return -EINVAL;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008639 }
8640
Hoonki Leed37cbb32013-04-20 00:31:14 -07008641 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
8642 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
8643
8644 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008645 {
Hoonki Leed37cbb32013-04-20 00:31:14 -07008646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008647 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -07008648 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008649 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -08008650
8651 if (pHddCtx->isLogpInProgress)
8652 {
8653 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8654 "%s: LOGP in Progress. Ignore!!!", __func__);
8655 return -EAGAIN;
8656 }
8657
Hoonki Leed37cbb32013-04-20 00:31:14 -07008658 wlan_hdd_tdls_check_bmps(pAdapter);
Sunil Dutt388ac8f2013-11-28 18:06:52 +05308659 return -EINVAL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008660 }
8661
Gopichand Nakkala05922802013-03-14 12:23:19 -07008662 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -07008663 {
8664 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008665 return max_sta_failed;
Hoonki Lee14621352013-04-16 17:51:19 -07008666 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008667
Hoonki Leea34dd892013-02-05 22:56:02 -08008668 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
8669 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008670 wlan_hdd_tdls_set_responder(pAdapter, peerMac, TRUE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008671 }
8672 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
8673 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08008674 wlan_hdd_tdls_set_responder(pAdapter, peerMac, FALSE);
Hoonki Leea34dd892013-02-05 22:56:02 -08008675 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008676
8677 return 0;
8678}
8679
8680static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
8681 u8 *peer, enum nl80211_tdls_operation oper)
8682{
8683 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8684 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308685 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008686 hddTdlsPeer_t *pTdlsPeer;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008687
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308688 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008689 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -08008690 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008691 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008692 return -EINVAL;
8693 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008694
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308695 status = wlan_hdd_validate_context(pHddCtx);
8696
8697 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008698 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8700 "%s: HDD context is not valid", __func__);
8701 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -08008702 }
8703
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008704
8705 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008706 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008707 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -08008708 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -07008709 "TDLS Disabled in INI OR not enabled in FW. "
8710 "Cannot process TDLS commands");
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008711 return -ENOTSUPP;
8712 }
8713
8714 switch (oper) {
8715 case NL80211_TDLS_ENABLE_LINK:
8716 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008717 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308718 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308719 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008720
Sunil Dutt41de4e22013-11-14 18:09:02 +05308721 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8722
8723 if ( NULL == pTdlsPeer ) {
8724 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8725 " (oper %d) not exsting. ignored",
8726 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8727 return -EINVAL;
8728 }
8729
8730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8731 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8732 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8733 "NL80211_TDLS_ENABLE_LINK");
8734
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -07008735 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
8736 {
8737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
8738 MAC_ADDRESS_STR " failed",
8739 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
8740 return -EINVAL;
8741 }
8742
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008743 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008744 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308745 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +05308746
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308747 if (0 != wlan_hdd_tdls_get_link_establish_params(
8748 pAdapter, peer,&tdlsLinkEstablishParams)) {
8749 return -EINVAL;
8750 }
8751 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308752
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +05308753 sme_SendTdlsLinkEstablishParams(WLAN_HDD_GET_HAL_CTX(pAdapter),
8754 pAdapter->sessionId, peer, &tdlsLinkEstablishParams);
8755 /* Send TDLS peer UAPSD capabilities to the firmware and
8756 * register with the TL on after the response for this operation
8757 * is received .
8758 */
8759 ret = wait_for_completion_interruptible_timeout(
8760 &pAdapter->tdls_link_establish_req_comp,
8761 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
8762 if (ret <= 0)
8763 {
8764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8765 "%s: Link Establish Request Faled Status %ld",
8766 __func__, ret);
8767 return -EINVAL;
8768 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308769 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008770 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_CONNECTED);
Gopichand Nakkala471708b2013-06-04 20:03:01 +05308771 /* Mark TDLS client Authenticated .*/
8772 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
8773 pTdlsPeer->staId,
8774 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008775 if (VOS_STATUS_SUCCESS == status)
8776 {
Hoonki Lee14621352013-04-16 17:51:19 -07008777 if (pTdlsPeer->is_responder == 0)
8778 {
8779 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
8780
8781 wlan_hdd_tdls_timer_restart(pAdapter,
8782 &pTdlsPeer->initiatorWaitTimeoutTimer,
8783 WAIT_TIME_TDLS_INITIATOR);
8784 /* suspend initiator TX until it receives direct packet from the
8785 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
8786 WLANTL_SuspendDataTx( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8787 &staId, NULL);
8788 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07008789 wlan_hdd_tdls_increment_peer_count(pAdapter);
8790 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008791 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308792
8793 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308794 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
8795 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308796 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +05308797 int ac;
8798 uint8 ucAc[4] = { WLANTL_AC_VO,
8799 WLANTL_AC_VI,
8800 WLANTL_AC_BK,
8801 WLANTL_AC_BE };
8802 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
8803 for(ac=0; ac < 4; ac++)
8804 {
8805 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
8806 pTdlsPeer->staId, ucAc[ac],
8807 tlTid[ac], tlTid[ac], 0, 0,
8808 WLANTL_BI_DIR );
8809 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308810 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008811 }
8812
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008813 }
8814 break;
8815 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -08008816 {
Sunil Dutt41de4e22013-11-14 18:09:02 +05308817 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8818
8819 if ( NULL == pTdlsPeer ) {
8820 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
8821 " (oper %d) not exsting. ignored",
8822 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
8823 return -EINVAL;
8824 }
8825
8826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8827 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
8828 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
8829 "NL80211_TDLS_DISABLE_LINK");
8830
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008831 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -08008832 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008833 long status;
8834
8835 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
8836
Lee Hoonkic1262f22013-01-24 21:59:00 -08008837 sme_DeleteTdlsPeerSta( WLAN_HDD_GET_HAL_CTX(pAdapter),
8838 pAdapter->sessionId, peer );
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008839
8840 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
8841 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
8842 if (status <= 0)
8843 {
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008844 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8846 "%s: Del station failed status %ld",
8847 __func__, status);
8848 return -EPERM;
8849 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008850 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer, eTDLS_LINK_IDLE);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008851 }
8852 else
8853 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8855 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -08008856 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08008857 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008858 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008859 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308860 {
8861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8862 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
8863 __func__, MAC_ADDR_ARRAY(peer));
8864
8865 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8866 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8867
8868 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8869 " %s TDLS External control and Implicit Trigger not enabled ",
8870 __func__);
8871 return -ENOTSUPP;
8872 }
8873
Sunil Dutt41de4e22013-11-14 18:09:02 +05308874
8875 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
8876
8877 if ( NULL == pTdlsPeer ) {
8878 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
8879 " peer not exsting",
8880 __func__, MAC_ADDR_ARRAY(peer));
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308881 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308882 }
8883 else {
8884 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
8885 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
8886 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308887
8888 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) )
8889 return -EINVAL;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308890 break;
8891 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008892 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +05308893 {
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308894 hddTdlsPeer_t *pTdlsPeer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308895 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8896 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
8897 __func__, MAC_ADDR_ARRAY(peer));
8898
8899 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
8900 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
8901
8902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8903 " %s TDLS External control and Implicit Trigger not enabled ",
8904 __func__);
8905 return -ENOTSUPP;
8906 }
8907
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308908 /* To cater the requirement of establishing the TDLS link
8909 * irrespective of the data traffic , get an entry of TDLS peer.
8910 */
8911 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
8912 if (pTdlsPeer == NULL) {
8913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8914 "%s: peer " MAC_ADDRESS_STR " not existing",
8915 __func__, MAC_ADDR_ARRAY(peer));
8916 return -EINVAL;
8917 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05308918
8919 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
8920
8921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8922 " %s TDLS Add Force Peer Failed",
8923 __func__);
8924 return -EINVAL;
8925 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +05308926 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +05308927 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008928 case NL80211_TDLS_DISCOVERY_REQ:
8929 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8931 "%s: We don't support in-driver setup/teardown/discovery "
8932 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008933 return -ENOTSUPP;
8934 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8936 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008937 return -ENOTSUPP;
8938 }
8939 return 0;
8940}
Chilam NG571c65a2013-01-19 12:27:36 +05308941
8942int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
8943 struct net_device *dev, u8 *peer)
8944{
Arif Hussaina7c8e412013-11-20 11:06:42 -08008945 hddLog(VOS_TRACE_LEVEL_INFO,
8946 "tdls send discover req: "MAC_ADDRESS_STR,
8947 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +05308948
8949 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
8950 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
8951}
Mohit Khanna698ba2a2012-12-04 15:08:18 -08008952#endif
8953
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308954#ifdef WLAN_FEATURE_GTK_OFFLOAD
8955/*
8956 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
8957 * Callback rountine called upon receiving response for
8958 * get offload info
8959 */
8960void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
8961 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
8962{
8963
8964 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308965 tANI_U8 tempReplayCounter[8];
8966 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308967
8968 ENTER();
8969
8970 if (NULL == pAdapter)
8971 {
Agarwal Ashish971c2882013-10-30 20:11:12 +05308972 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05308973 "%s: HDD adapter is Null", __func__);
8974 return ;
8975 }
8976
8977 if (NULL == pGtkOffloadGetInfoRsp)
8978 {
8979 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8980 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
8981 return ;
8982 }
8983
8984 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
8985 {
8986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8987 "%s: wlan Failed to get replay counter value",
8988 __func__);
8989 return ;
8990 }
8991
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05308992 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8993 /* Update replay counter */
8994 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
8995 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
8996
8997 {
8998 /* changing from little to big endian since supplicant
8999 * works on big endian format
9000 */
9001 int i;
9002 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
9003
9004 for (i = 0; i < 8; i++)
9005 {
9006 tempReplayCounter[7-i] = (tANI_U8)p[i];
9007 }
9008 }
9009
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309010 /* Update replay counter to NL */
9011 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309012 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309013}
9014
9015/*
9016 * FUNCTION: wlan_hdd_cfg80211_set_rekey_data
9017 * This function is used to offload GTK rekeying job to the firmware.
9018 */
9019int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
9020 struct cfg80211_gtk_rekey_data *data)
9021{
9022 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9023 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9024 hdd_station_ctx_t *pHddStaCtx;
9025 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309026 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309027 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309028 eHalStatus status = eHAL_STATUS_FAILURE;
9029
9030 ENTER();
9031
9032 if (NULL == pAdapter)
9033 {
9034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9035 "%s: HDD adapter is Null", __func__);
9036 return -ENODEV;
9037 }
9038
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309039 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309040
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309041 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309042 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309043 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9044 "%s: HDD context is not valid", __func__);
9045 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309046 }
9047
9048 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9049 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
9050 if (NULL == hHal)
9051 {
9052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9053 "%s: HAL context is Null!!!", __func__);
9054 return -EAGAIN;
9055 }
9056
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309057 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
9058 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
9059 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
9060 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309061 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309062 {
9063 /* changing from big to little endian since driver
9064 * works on little endian format
9065 */
9066 tANI_U8 *p =
9067 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
9068 int i;
9069
9070 for (i = 0; i < 8; i++)
9071 {
9072 p[7-i] = data->replay_ctr[i];
9073 }
9074 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309075
9076 if (TRUE == pHddCtx->hdd_wlan_suspended)
9077 {
9078 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309079 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
9080 sizeof (tSirGtkOffloadParams));
9081 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309082 pAdapter->sessionId);
9083
9084 if (eHAL_STATUS_SUCCESS != status)
9085 {
9086 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9087 "%s: sme_SetGTKOffload failed, returned %d",
9088 __func__, status);
9089 return status;
9090 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309091 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9092 "%s: sme_SetGTKOffload successfull", __func__);
9093 }
9094 else
9095 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9097 "%s: wlan not suspended GTKOffload request is stored",
9098 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309099 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +05309100
9101 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309102}
9103#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
9104
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309105/*
9106 * FUNCTION: wlan_hdd_cfg80211_set_mac_acl
9107 * This function is used to set access control policy
9108 */
9109static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
9110 struct net_device *dev, const struct cfg80211_acl_data *params)
9111{
9112 int i;
9113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9114 hdd_hostapd_state_t *pHostapdState;
9115 tsap_Config_t *pConfig;
9116 v_CONTEXT_t pVosContext = NULL;
9117 hdd_context_t *pHddCtx;
9118 int status;
9119
9120 ENTER();
9121
9122 if (NULL == pAdapter)
9123 {
9124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9125 "%s: HDD adapter is Null", __func__);
9126 return -ENODEV;
9127 }
9128
9129 if (NULL == params)
9130 {
9131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9132 "%s: params is Null", __func__);
9133 return -EINVAL;
9134 }
9135
9136 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9137 status = wlan_hdd_validate_context(pHddCtx);
9138
9139 if (0 != status)
9140 {
9141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9142 "%s: HDD context is not valid", __func__);
9143 return status;
9144 }
9145
9146 pVosContext = pHddCtx->pvosContext;
9147 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9148
9149 if (NULL == pHostapdState)
9150 {
9151 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9152 "%s: pHostapdState is Null", __func__);
9153 return -EINVAL;
9154 }
9155
9156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
9157 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
9158
9159 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
9160 {
9161 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
9162
9163 /* default value */
9164 pConfig->num_accept_mac = 0;
9165 pConfig->num_deny_mac = 0;
9166
9167 /**
9168 * access control policy
9169 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
9170 * listed in hostapd.deny file.
9171 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
9172 * listed in hostapd.accept file.
9173 */
9174 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
9175 {
9176 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
9177 }
9178 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
9179 {
9180 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9181 }
9182 else
9183 {
9184 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9185 "%s:Acl Policy : %d is not supported",
9186 __func__, params->acl_policy);
9187 return -ENOTSUPP;
9188 }
9189
9190 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
9191 {
9192 pConfig->num_accept_mac = params->n_acl_entries;
9193 for (i = 0; i < params->n_acl_entries; i++)
9194 {
9195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9196 "** Add ACL MAC entry %i in WhiletList :"
9197 MAC_ADDRESS_STR, i,
9198 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9199
9200 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
9201 sizeof(qcmacaddr));
9202 }
9203 }
9204 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
9205 {
9206 pConfig->num_deny_mac = params->n_acl_entries;
9207 for (i = 0; i < params->n_acl_entries; i++)
9208 {
9209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9210 "** Add ACL MAC entry %i in BlackList :"
9211 MAC_ADDRESS_STR, i,
9212 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
9213
9214 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
9215 sizeof(qcmacaddr));
9216 }
9217 }
9218
9219 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
9220 {
9221 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9222 "%s: SAP Set Mac Acl fail", __func__);
9223 return -EINVAL;
9224 }
9225 }
9226 else
9227 {
9228 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9229 "%s: Invalid device_mode = %d",
9230 __func__, pAdapter->device_mode);
9231 return -EINVAL;
9232 }
9233
9234 return 0;
9235}
9236
Leo Chang9056f462013-08-01 19:21:11 -07009237#ifdef WLAN_NL80211_TESTMODE
9238#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -07009239void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -07009240(
9241 void *pAdapter,
9242 void *indCont
9243)
9244{
Leo Changd9df8aa2013-09-26 13:32:26 -07009245 tSirLPHBInd *lphbInd;
9246 struct sk_buff *skb;
Leo Chang9056f462013-08-01 19:21:11 -07009247
9248 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009249 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -07009250
9251 if (NULL == indCont)
9252 {
9253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -07009254 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -07009255 return;
9256 }
9257
Leo Changd9df8aa2013-09-26 13:32:26 -07009258 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -07009259 skb = cfg80211_testmode_alloc_event_skb(
9260 ((hdd_adapter_t *)pAdapter)->wdev.wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -07009261 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -07009262 GFP_ATOMIC);
9263 if (!skb)
9264 {
9265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9266 "LPHB timeout, NL buffer alloc fail");
9267 return;
9268 }
9269
Leo Changac3ba772013-10-07 09:47:04 -07009270 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -07009271 {
9272 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9273 "WLAN_HDD_TM_ATTR_CMD put fail");
9274 goto nla_put_failure;
9275 }
Leo Changac3ba772013-10-07 09:47:04 -07009276 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -07009277 {
9278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9279 "WLAN_HDD_TM_ATTR_TYPE put fail");
9280 goto nla_put_failure;
9281 }
Leo Changac3ba772013-10-07 09:47:04 -07009282 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -07009283 sizeof(tSirLPHBInd), lphbInd))
9284 {
9285 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9286 "WLAN_HDD_TM_ATTR_DATA put fail");
9287 goto nla_put_failure;
9288 }
Leo Chang9056f462013-08-01 19:21:11 -07009289 cfg80211_testmode_event(skb, GFP_ATOMIC);
9290 return;
9291
9292nla_put_failure:
9293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9294 "NLA Put fail");
9295 kfree_skb(skb);
9296
9297 return;
9298}
9299#endif /* FEATURE_WLAN_LPHB */
9300
9301static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
9302{
9303 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
9304 int err = 0;
9305#ifdef FEATURE_WLAN_LPHB
9306 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -07009307 eHalStatus smeStatus;
Leo Chang9056f462013-08-01 19:21:11 -07009308#endif /* FEATURE_WLAN_LPHB */
9309
9310 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
9311 if (err)
9312 {
9313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9314 "%s Testmode INV ATTR", __func__);
9315 return err;
9316 }
9317
9318 if (!tb[WLAN_HDD_TM_ATTR_CMD])
9319 {
9320 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9321 "%s Testmode INV CMD", __func__);
9322 return -EINVAL;
9323 }
9324
9325 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
9326 {
9327#ifdef FEATURE_WLAN_LPHB
9328 /* Low Power Heartbeat configuration request */
9329 case WLAN_HDD_TM_CMD_WLAN_HB:
9330 {
9331 int buf_len;
9332 void *buf;
9333 tSirLPHBReq *hb_params = NULL;
9334
9335 if (!tb[WLAN_HDD_TM_ATTR_DATA])
9336 {
9337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9338 "%s Testmode INV DATA", __func__);
9339 return -EINVAL;
9340 }
9341
9342 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
9343 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
9344 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
9345 if (NULL == hb_params)
9346 {
9347 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9348 "%s Request Buffer Alloc Fail", __func__);
9349 return -EINVAL;
9350 }
9351
9352 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -07009353 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
9354 hb_params,
9355 wlan_hdd_cfg80211_lphb_ind_handler);
9356 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -07009357 {
Leo Changd9df8aa2013-09-26 13:32:26 -07009358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9359 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -07009360 vos_mem_free(hb_params);
9361 }
Leo Chang9056f462013-08-01 19:21:11 -07009362 return 0;
9363 }
9364#endif /* FEATURE_WLAN_LPHB */
9365 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9367 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -07009368 return -EOPNOTSUPP;
9369 }
9370
9371 return err;
9372}
9373#endif /* CONFIG_NL80211_TESTMODE */
9374
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309375static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
9376 struct net_device *dev,
9377 int idx, struct survey_info *survey)
9378{
9379 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9380 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +05309381 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309382 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +05309383 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309384 v_S7_t snr,rssi;
9385 int status, i, j, filled = 0;
9386
9387 ENTER();
9388
9389
9390 if (NULL == pAdapter)
9391 {
9392 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9393 "%s: HDD adapter is Null", __func__);
9394 return -ENODEV;
9395 }
9396
9397 if (NULL == wiphy)
9398 {
9399 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9400 "%s: wiphy is Null", __func__);
9401 return -ENODEV;
9402 }
9403
9404 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9405 status = wlan_hdd_validate_context(pHddCtx);
9406
9407 if (0 != status)
9408 {
9409 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9410 "%s: HDD context is not valid", __func__);
9411 return status;
9412 }
9413
Mihir Sheted9072e02013-08-21 17:02:29 +05309414 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9415
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309416 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +05309417 0 != pAdapter->survey_idx ||
9418 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309419 {
9420 /* The survey dump ops when implemented completely is expected to
9421 * return a survey of all channels and the ops is called by the
9422 * kernel with incremental values of the argument 'idx' till it
9423 * returns -ENONET. But we can only support the survey for the
9424 * operating channel for now. survey_idx is used to track
9425 * that the ops is called only once and then return -ENONET for
9426 * the next iteration
9427 */
9428 pAdapter->survey_idx = 0;
9429 return -ENONET;
9430 }
9431
9432 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
9433
9434 wlan_hdd_get_snr(pAdapter, &snr);
9435 wlan_hdd_get_rssi(pAdapter, &rssi);
9436
9437 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
9438 hdd_wlan_get_freq(channel, &freq);
9439
9440
9441 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
9442 {
9443 if (NULL == wiphy->bands[i])
9444 {
9445 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
9446 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
9447 continue;
9448 }
9449
9450 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
9451 {
9452 struct ieee80211_supported_band *band = wiphy->bands[i];
9453
9454 if (band->channels[j].center_freq == (v_U16_t)freq)
9455 {
9456 survey->channel = &band->channels[j];
9457 /* The Rx BDs contain SNR values in dB for the received frames
9458 * while the supplicant expects noise. So we calculate and
9459 * return the value of noise (dBm)
9460 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
9461 */
9462 survey->noise = rssi - snr;
9463 survey->filled = SURVEY_INFO_NOISE_DBM;
9464 filled = 1;
9465 }
9466 }
9467 }
9468
9469 if (filled)
9470 pAdapter->survey_idx = 1;
9471 else
9472 {
9473 pAdapter->survey_idx = 0;
9474 return -ENONET;
9475 }
9476
9477 return 0;
9478}
9479
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309480/*
9481 * FUNCTION: wlan_hdd_cfg80211_resume_wlan
9482 * this is called when cfg80211 driver resume
9483 * driver updates latest sched_scan scan result(if any) to cfg80211 database
9484 */
9485int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
9486{
9487 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9488 hdd_adapter_t *pAdapter;
9489 hdd_adapter_list_node_t *pAdapterNode, *pNext;
9490 VOS_STATUS status = VOS_STATUS_SUCCESS;
9491
9492 ENTER();
9493
9494 if ( NULL == pHddCtx )
9495 {
9496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9497 "%s: HddCtx validation failed", __func__);
9498 return 0;
9499 }
9500
9501 if (pHddCtx->isLogpInProgress)
9502 {
9503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9504 "%s: LOGP in Progress. Ignore!!!", __func__);
9505 return 0;
9506 }
9507
9508 if (pHddCtx->isLoadUnloadInProgress)
9509 {
9510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9511 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
9512 return 0;
9513 }
9514
9515 spin_lock(&pHddCtx->schedScan_lock);
9516 pHddCtx->isWiphySuspended = FALSE;
9517 if (TRUE != pHddCtx->isSchedScanUpdatePending)
9518 {
9519 spin_unlock(&pHddCtx->schedScan_lock);
9520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9521 "%s: Return resume is not due to PNO indication", __func__);
9522 return 0;
9523 }
9524 // Reset flag to avoid updatating cfg80211 data old results again
9525 pHddCtx->isSchedScanUpdatePending = FALSE;
9526 spin_unlock(&pHddCtx->schedScan_lock);
9527
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309528
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309529 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
9530
9531 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
9532 {
9533 pAdapter = pAdapterNode->pAdapter;
9534 if ( (NULL != pAdapter) &&
9535 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
9536 {
9537 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309538 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9540 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309541 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309542 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309543 {
9544 /* Acquire wakelock to handle the case where APP's tries to
9545 * suspend immediately after updating the scan results. Whis
9546 * results in app's is in suspended state and not able to
9547 * process the connect request to AP
9548 */
9549 hdd_prevent_suspend_timeout(2000);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309550 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +05309551 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309552
9553 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9554 "%s : cfg80211 scan result database updated", __func__);
9555
9556 return 0;
9557
9558 }
9559 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
9560 pAdapterNode = pNext;
9561 }
9562
9563 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9564 "%s: Failed to find Adapter", __func__);
9565 return 0;
9566}
9567
9568/*
9569 * FUNCTION: wlan_hdd_cfg80211_suspend_wlan
9570 * this is called when cfg80211 driver suspends
9571 */
9572int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
9573 struct cfg80211_wowlan *wow)
9574{
9575 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
9576
9577 ENTER();
9578 if (NULL == pHddCtx)
9579 {
9580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9581 "%s: HddCtx validation failed", __func__);
9582 return 0;
9583 }
9584
9585 pHddCtx->isWiphySuspended = TRUE;
9586
9587 EXIT();
9588
9589 return 0;
9590}
9591
Jeff Johnson295189b2012-06-20 16:38:30 -07009592/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309593static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -07009594{
9595 .add_virtual_intf = wlan_hdd_add_virtual_intf,
9596 .del_virtual_intf = wlan_hdd_del_virtual_intf,
9597 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
9598 .change_station = wlan_hdd_change_station,
9599#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9600 .add_beacon = wlan_hdd_cfg80211_add_beacon,
9601 .del_beacon = wlan_hdd_cfg80211_del_beacon,
9602 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009603#else
9604 .start_ap = wlan_hdd_cfg80211_start_ap,
9605 .change_beacon = wlan_hdd_cfg80211_change_beacon,
9606 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -07009607#endif
9608 .change_bss = wlan_hdd_cfg80211_change_bss,
9609 .add_key = wlan_hdd_cfg80211_add_key,
9610 .get_key = wlan_hdd_cfg80211_get_key,
9611 .del_key = wlan_hdd_cfg80211_del_key,
9612 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009614 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -08009615#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009616 .scan = wlan_hdd_cfg80211_scan,
9617 .connect = wlan_hdd_cfg80211_connect,
9618 .disconnect = wlan_hdd_cfg80211_disconnect,
9619 .join_ibss = wlan_hdd_cfg80211_join_ibss,
9620 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
9621 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
9622 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
9623 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
9625 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
9626 .mgmt_tx = wlan_hdd_action,
9627#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9628 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
9629 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
9630 .set_txq_params = wlan_hdd_set_txq_params,
9631#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 .get_station = wlan_hdd_cfg80211_get_station,
9633 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
9634 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009635 .add_station = wlan_hdd_cfg80211_add_station,
9636#ifdef FEATURE_WLAN_LFR
9637 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
9638 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
9639 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
9640#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009641#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
9642 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
9643#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08009644#ifdef FEATURE_WLAN_TDLS
9645 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
9646 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
9647#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +05309648#ifdef WLAN_FEATURE_GTK_OFFLOAD
9649 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
9650#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05309651#ifdef FEATURE_WLAN_SCAN_PNO
9652 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
9653 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
9654#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +05309655 .resume = wlan_hdd_cfg80211_resume_wlan,
9656 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309657 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -07009658#ifdef WLAN_NL80211_TESTMODE
9659 .testmode_cmd = wlan_hdd_cfg80211_testmode,
9660#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +05309661 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009662};
9663