blob: 731c6109c10c223537655d8924be412e85ca5a05 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002 * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/**
29 * DOC: wlan_hdd_assoc.c
30 *
31 * WLAN Host Device Driver implementation
32 *
33 */
34
35#include "wlan_hdd_includes.h"
36#include <ani_global.h>
37#include "dot11f.h"
38#include "wlan_hdd_power.h"
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +053039#include "wlan_hdd_trace.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080040#include <linux/ieee80211.h>
41#include <linux/wireless.h>
42#include <linux/etherdevice.h>
43#include <net/cfg80211.h>
44#include "wlan_hdd_cfg80211.h"
45#include "csr_inside_api.h"
46#include "wlan_hdd_p2p.h"
47#ifdef FEATURE_WLAN_TDLS
48#include "wlan_hdd_tdls.h"
49#endif
50#include "sme_api.h"
51#include "wlan_hdd_hostapd.h"
52#include <wlan_hdd_ipa.h>
Jeff Johnson2b0a7b82016-05-18 15:08:02 -070053#include "wlan_hdd_lpass.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080054#include <cds_sched.h>
55#include "cds_concurrency.h"
56#include "sme_power_save_api.h"
57#include "ol_txrx_ctrl_api.h"
58#include "ol_txrx_types.h"
Dhanashri Atre182b0272016-02-17 15:35:07 -080059#include "ol_txrx.h"
Himanshu Agarwal11c874a2016-05-06 18:35:29 +053060#include "ol_rx_fwd.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080061#include "cdp_txrx_flow_ctrl_legacy.h"
62#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080063
64/* These are needed to recognize WPA and RSN suite types */
65#define HDD_WPA_OUI_SIZE 4
66#define HDD_RSN_OUI_SIZE 4
67uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
68uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
69uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
70uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
71uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
72uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
73
74#ifdef FEATURE_WLAN_ESE
75/* CCKM */
76uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
77/* CCKM */
78uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
79#endif /* FEATURE_WLAN_ESE */
80
81/* group cipher */
82uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
83
84/* WEP-40 or RSN */
85uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
86
87/* TKIP or RSN-PSK */
88uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
89
90/* Reserved */
91uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
92
93/* AES-CCMP */
94uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
95
96/* WEP-104 */
97uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
98
99#ifdef WLAN_FEATURE_11W
100/* RSN-PSK-SHA256 */
101uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
102
103/* RSN-8021X-SHA256 */
104uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
105#endif
106
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800107/* Offset where the EID-Len-IE, start. */
108#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
109#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800110
111#define BEACON_FRAME_IES_OFFSET 12
112#define HDD_PEER_AUTHORIZE_WAIT 10
113
114/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700115 * beacon_filter_table - table of IEs used for beacon filtering
116 */
117static const int beacon_filter_table[] = {
118 SIR_MAC_DS_PARAM_SET_EID,
119 SIR_MAC_ERP_INFO_EID,
120 SIR_MAC_EDCA_PARAM_SET_EID,
121 SIR_MAC_QOS_CAPABILITY_EID,
122 SIR_MAC_HT_INFO_EID,
123 SIR_MAC_VHT_OPMODE_EID,
124 SIR_MAC_VHT_OPERATION_EID,
125};
126
127/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800128 * hdd_conn_set_authenticated() - set authentication state
129 * @pAdapter: pointer to the adapter
130 * @authState: authentication state
131 *
132 * This function updates the global HDD station context
133 * authentication state.
134 *
135 * Return: none
136 */
137static void
138hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
139{
140 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
141 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
142
143 /* save the new connection state */
144 hddLog(LOG1,
145 FL("Authenticated state Changed from oldState:%d to State:%d"),
146 pHddStaCtx->conn_info.uIsAuthenticated, authState);
147 pHddStaCtx->conn_info.uIsAuthenticated = authState;
148
149 /* Check is pending ROC request or not when auth state changed */
150 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
151}
152
153/**
154 * hdd_conn_set_connection_state() - set connection state
155 * @pAdapter: pointer to the adapter
156 * @connState: connection state
157 *
158 * This function updates the global HDD station context connection state.
159 *
160 * Return: none
161 */
162void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
163 eConnectionState connState)
164{
165 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
166 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
167
168 /* save the new connection state */
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530169 hdd_info("%pS Changed connectionState Changed from oldState:%d to State:%d",
170 (void *)_RET_IP_, pHddStaCtx->conn_info.connState,
171 connState);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800172 pHddStaCtx->conn_info.connState = connState;
173
174 /* Check is pending ROC request or not when connection state changed */
175 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
176}
177
178/**
179 * hdd_conn_get_connection_state() - get connection state
180 * @pAdapter: pointer to the adapter
181 * @pConnState: pointer to connection state
182 *
183 * This function updates the global HDD station context connection state.
184 *
185 * Return: true if (Infra Associated or IBSS Connected)
186 * and sets output parameter pConnState;
187 * false otherwise
188 */
189static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
190 eConnectionState *pConnState)
191{
192 bool fConnected = false;
193 eConnectionState connState;
194
195 /* get the connection state. */
196 connState = pHddStaCtx->conn_info.connState;
197
198 if (eConnectionState_Associated == connState ||
199 eConnectionState_IbssConnected == connState ||
200 eConnectionState_IbssDisconnected == connState) {
201 fConnected = true;
202 }
203
204 if (pConnState)
205 *pConnState = connState;
206
207 return fConnected;
208}
209
210/**
211 * hdd_is_connecting() - Function to check connection progress
212 * @hdd_sta_ctx: pointer to global HDD Station context
213 *
214 * Return: true if connecting, false otherwise
215 */
216bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
217{
218 return hdd_sta_ctx->conn_info.connState ==
219 eConnectionState_Connecting;
220}
221
222/**
223 * hdd_conn_is_connected() - Function to check connection status
224 * @pHddStaCtx: pointer to global HDD Station context
225 *
226 * Return: false if any errors encountered, true otherwise
227 */
228bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
229{
230 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
231}
232
233/**
234 * hdd_conn_get_connected_band() - get current connection radio band
235 * @pHddStaCtx: pointer to global HDD Station context
236 *
237 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
238 * eCSR_BAND_ALL if not connected
239 */
240eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
241{
242 uint8_t staChannel = 0;
243
244 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
245 staChannel = pHddStaCtx->conn_info.operationChannel;
246
247 if (staChannel > 0 && staChannel < 14)
248 return eCSR_BAND_24;
249 else if (staChannel >= 36 && staChannel <= 184)
250 return eCSR_BAND_5G;
251 else /* If station is not connected return as eCSR_BAND_ALL */
252 return eCSR_BAND_ALL;
253}
254
255/**
256 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
257 * @pHddStaCtx: pointer to global HDD Station context
258 * @pConnectedCipherAlgo: pointer to connected cipher algo
259 *
260 * Return: false if any errors encountered, true otherwise
261 */
262static inline bool
263hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
264 eCsrEncryptionType *pConnectedCipherAlgo)
265{
266 bool fConnected = false;
267
268 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
269
270 if (pConnectedCipherAlgo)
271 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
272
273 return fConnected;
274}
275
276/**
277 * hdd_conn_get_connected_bss_type() - get current bss type
278 * @pHddStaCtx: pointer to global HDD Station context
279 * @pConnectedBssType: pointer to connected bss type
280 *
281 * Return: false if any errors encountered, true otherwise
282 */
283inline bool
284hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
285 eMib_dot11DesiredBssType *pConnectedBssType)
286{
287 bool fConnected = false;
288
289 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
290
291 if (pConnectedBssType) {
292 *pConnectedBssType =
293 pHddStaCtx->conn_info.connDot11DesiredBssType;
294 }
295
296 return fConnected;
297}
298
299/**
300 * hdd_conn_save_connected_bss_type() - set connected bss type
301 * @pHddStaCtx: pointer to global HDD Station context
302 * @csr_roamBssType: bss type
303 *
304 * Return: none
305 */
306static inline void
307hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
308 eCsrRoamBssType csr_roamBssType)
309{
310 switch (csr_roamBssType) {
311 case eCSR_BSS_TYPE_INFRASTRUCTURE:
312 pHddStaCtx->conn_info.connDot11DesiredBssType =
313 eMib_dot11DesiredBssType_infrastructure;
314 break;
315
316 case eCSR_BSS_TYPE_IBSS:
317 case eCSR_BSS_TYPE_START_IBSS:
318 pHddStaCtx->conn_info.connDot11DesiredBssType =
319 eMib_dot11DesiredBssType_independent;
320 break;
321
322 /** We will never set the BssType to 'any' when attempting a connection
323 so CSR should never send this back to us.*/
324 case eCSR_BSS_TYPE_ANY:
325 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530326 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800327 break;
328 }
329}
330
331/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700332 * hdd_remove_beacon_filter() - remove beacon filter
333 * @adapter: Pointer to the hdd adapter
334 *
335 * Return: 0 on success and errno on failure
336 */
337static int hdd_remove_beacon_filter(hdd_adapter_t *adapter)
338{
339 QDF_STATUS status;
340 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
341
342 status = sme_remove_beacon_filter(hdd_ctx->hHal,
343 adapter->sessionId);
344 if (!QDF_IS_STATUS_SUCCESS(status)) {
345 hdd_err("sme_remove_beacon_filter() failed");
346 return -EFAULT;
347 }
348
349 return 0;
350}
351
352/**
353 * hdd_add_beacon_filter() - add beacon filter
354 * @adapter: Pointer to the hdd adapter
355 *
356 * Return: 0 on success and errno on failure
357 */
358static int hdd_add_beacon_filter(hdd_adapter_t *adapter)
359{
360 int i;
361 uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0};
362 QDF_STATUS status;
363 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
364
365 for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
366 qdf_set_bit((beacon_filter_table[i] - 1),
367 (unsigned long int *)ie_map);
368
369 status = sme_add_beacon_filter(hdd_ctx->hHal,
370 adapter->sessionId, ie_map);
371 if (!QDF_IS_STATUS_SUCCESS(status)) {
372 hdd_err("sme_add_beacon_filter() failed");
373 return -EFAULT;
374 }
375 return 0;
376}
377
378/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800379 * hdd_conn_save_connect_info() - save current connection information
380 * @pAdapter: pointer to adapter
381 * @pRoamInfo: pointer to roam info
382 * @eBssType: bss type
383 *
384 * Return: none
385 */
386static void
387hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
388 eCsrRoamBssType eBssType)
389{
390 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
391 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
392
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530393 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800394
395 if (pRoamInfo) {
396 /* Save the BSSID for the connection */
397 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530398 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530399 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800400 &pRoamInfo->bssid);
401
402 /*
403 * Save the Station ID for this station from
404 * the 'Roam Info'. For IBSS mode, staId is
405 * assigned in NEW_PEER_IND. For reassoc,
406 * the staID doesn't change and it may be invalid
407 * in this structure so no change here.
408 */
409 if (!pRoamInfo->fReassocReq) {
410 pHddStaCtx->conn_info.staId[0] =
411 pRoamInfo->staId;
412 }
413 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530414 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800415 &pRoamInfo->bssid);
416 } else {
417 /*
418 * can't happen. We need a valid IBSS or Infra setting
419 * in the BSSDescription or we can't function.
420 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530421 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800422 }
423
424 /* notify WMM */
425 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
426
427 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530428 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800429 } else {
430 /* Get Multicast Encryption Type */
431 encryptType =
432 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
433 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
434 /* Get Unicast Encryption Type */
435 encryptType =
436 pRoamInfo->u.pConnectedProfile->EncryptionType;
437 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
438
439 pHddStaCtx->conn_info.authType =
440 pRoamInfo->u.pConnectedProfile->AuthType;
441
442 pHddStaCtx->conn_info.operationChannel =
443 pRoamInfo->u.pConnectedProfile->operationChannel;
444
445 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530446 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800447 &pRoamInfo->u.pConnectedProfile->SSID,
448 sizeof(tSirMacSSid));
449
450 /* Save dot11mode in which STA associated to AP */
451 pHddStaCtx->conn_info.dot11Mode =
452 pRoamInfo->u.pConnectedProfile->dot11Mode;
453
454 pHddStaCtx->conn_info.proxyARPService =
455 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530456
457 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
458
459 pHddStaCtx->conn_info.rate_flags =
460 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800461 }
462 }
463 /* save the connected BssType */
464 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
465}
466
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800467/**
468 * hdd_send_ft_assoc_response() - send fast transition assoc response
469 * @dev: pointer to net device
470 * @pAdapter: pointer to adapter
471 * @pCsrRoamInfo: pointer to roam info
472 *
473 * Send the 11R key information to the supplicant. Only then can the supplicant
474 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
475 * for the same purpose.)
476 *
477 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
478 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
479 * This is the Assoc Response.
480 *
481 * Return: none
482 */
483static void
484hdd_send_ft_assoc_response(struct net_device *dev,
485 hdd_adapter_t *pAdapter,
486 tCsrRoamInfo *pCsrRoamInfo)
487{
488 union iwreq_data wrqu;
489 char *buff;
490 unsigned int len = 0;
491 u8 *pFTAssocRsp = NULL;
492
493 if (pCsrRoamInfo->nAssocRspLength == 0) {
494 hddLog(LOGE,
495 FL("pCsrRoamInfo->nAssocRspLength=%d"),
496 (int)pCsrRoamInfo->nAssocRspLength);
497 return;
498 }
499
500 pFTAssocRsp =
501 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
502 pCsrRoamInfo->nAssocReqLength);
503 if (pFTAssocRsp == NULL) {
504 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
505 return;
506 }
507 /* pFTAssocRsp needs to point to the IEs */
508 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
509 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
510 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
511
512 /* We need to send the IEs to the supplicant. */
513 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
514 if (buff == NULL) {
515 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
516 return;
517 }
518 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
519 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
520 wrqu.data.length = len;
521 memset(buff, 0, IW_GENERIC_IE_MAX);
522 memcpy(buff, pFTAssocRsp, len);
523 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
524
525 kfree(buff);
526}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800528/**
529 * hdd_send_ft_event() - send fast transition event
530 * @pAdapter: pointer to adapter
531 *
532 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
533 * FT events to the supplicant. At the reception of Auth2 we send the RIC
534 * followed by the auth response IEs to the supplicant.
535 * Once both are received in the supplicant, an FT event is generated
536 * to the supplicant.
537 *
538 * Return: none
539 */
540static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
541{
542 uint16_t auth_resp_len = 0;
543 uint32_t ric_ies_length = 0;
544 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
545
546#if defined(KERNEL_SUPPORT_11R_CFG80211)
547 struct cfg80211_ft_event_params ftEvent;
548 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
549 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
550 struct net_device *dev = pAdapter->dev;
551#else
552 char *buff;
553 union iwreq_data wrqu;
554 uint16_t str_len;
555#endif
556
557#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530558 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
559 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800560
561 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
562 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
563 if (ric_ies_length == 0) {
564 hddLog(LOGW,
565 FL("RIC IEs is of length 0 not sending RIC Information for now"));
566 }
567
568 ftEvent.ric_ies = ricIe;
569 ftEvent.ric_ies_len = ric_ies_length;
570 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
571
572 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
573 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
574 &auth_resp_len);
575
576 if (auth_resp_len == 0) {
577 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
578 return;
579 }
580
581 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
582
583 ftEvent.target_ap = ftIe;
584
Anurag Chouhan6d760662016-02-20 16:05:43 +0530585 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
586 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800587
588 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
589 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
590 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
591 ftEvent.target_ap[0], ftEvent.target_ap[1],
592 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
593 ftEvent.target_ap[5]);
594
595 (void)cfg80211_ft_event(dev, &ftEvent);
596
597#else
598 /* We need to send the IEs to the supplicant */
599 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
600 if (buff == NULL) {
601 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
602 return;
603 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530604 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800605
606 /* Sme needs to send the RIC IEs first */
607 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
608 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
609 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
610 &ric_ies_length);
611 if (ric_ies_length == 0) {
612 hddLog(LOGW,
613 FL("RIC IEs is of length 0 not sending RIC Information for now"));
614 } else {
615 wrqu.data.length = str_len + ric_ies_length;
616 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
617 }
618
619 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530620 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800621 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
622 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
623 (u8 *) &buff[str_len],
624 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
625
626 if (auth_resp_len == 0) {
627 kfree(buff);
628 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
629 return;
630 }
631
632 wrqu.data.length = str_len + auth_resp_len;
633 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
634
635 kfree(buff);
636#endif
637}
638
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800639#ifdef FEATURE_WLAN_ESE
640/**
641 * hdd_send_new_ap_channel_info() - send new ap channel info
642 * @dev: pointer to net device
643 * @pAdapter: pointer to adapter
644 * @pCsrRoamInfo: pointer to roam info
645 *
646 * Send the ESE required "new AP Channel info" to the supplicant.
647 * (This keeps the supplicant "up to date" on the current channel.)
648 *
649 * The current (new AP) channel information is passed in.
650 *
651 * Return: none
652 */
653static void
654hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
655 tCsrRoamInfo *pCsrRoamInfo)
656{
657 union iwreq_data wrqu;
658 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
659
660 if (descriptor == NULL) {
661 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
662 return;
663 }
664 /*
665 * Send the Channel event, the supplicant needs this to generate
666 * the Adjacent AP report.
667 */
668 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
669 descriptor->channelId);
670 memset(&wrqu, '\0', sizeof(wrqu));
671 wrqu.freq.m = descriptor->channelId;
672 wrqu.freq.e = 0;
673 wrqu.freq.i = 0;
674 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
675}
676
677#endif /* FEATURE_WLAN_ESE */
678
679/**
680 * hdd_send_update_beacon_ies_event() - send update beacons ie event
681 * @pAdapter: pointer to adapter
682 * @pCsrRoamInfo: pointer to roam info
683 *
684 * Return: none
685 */
686static void
687hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
688 tCsrRoamInfo *pCsrRoamInfo)
689{
690 union iwreq_data wrqu;
691 u8 *pBeaconIes;
692 u8 currentLen = 0;
693 char *buff;
694 int totalIeLen = 0, currentOffset = 0, strLen;
695
696 memset(&wrqu, '\0', sizeof(wrqu));
697
698 if (0 == pCsrRoamInfo->nBeaconLength) {
699 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
700 return;
701 }
702 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
703 if (pBeaconIes == NULL) {
704 hddLog(LOGW, FL("Beacon IEs is NULL"));
705 return;
706 }
707 /* pBeaconIes needs to point to the IEs */
708 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
709 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
710 hddLog(LOG1, FL("Beacon IEs length = %d"),
711 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
712
713 /* We need to send the IEs to the supplicant. */
714 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
715 if (buff == NULL) {
716 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
717 return;
718 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530719 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800720
721 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
722 currentLen = strLen + 1;
723
724 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
725 do {
726 /*
727 * If the beacon size exceeds max CUSTOM event size, break it
728 * into chunks of CUSTOM event max size and send it to
729 * supplicant. Changes are done in supplicant to handle this.
730 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530731 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800732 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530733 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530734 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800735 currentLen);
736 currentOffset += currentLen;
737 totalIeLen -= currentLen;
738 wrqu.data.length = strLen + 1 + currentLen;
739 if (totalIeLen)
740 buff[strLen] = 1; /* more chunks pending */
741 else
742 buff[strLen] = 0; /* last chunk */
743
744 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
745 currentLen);
746 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
747 } while (totalIeLen > 0);
748
749 kfree(buff);
750}
751
752/**
753 * hdd_send_association_event() - send association event
754 * @dev: pointer to net device
755 * @pCsrRoamInfo: pointer to roam info
756 *
757 * Return: none
758 */
759static void hdd_send_association_event(struct net_device *dev,
760 tCsrRoamInfo *pCsrRoamInfo)
761{
762 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
763 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
764 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
765 union iwreq_data wrqu;
766 int we_event;
767 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530768 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800770 /* Added to find the auth type on the fly at run time */
771 /* rather than with cfg to see if FT is enabled */
772 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
773 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800774
775 memset(&wrqu, '\0', sizeof(wrqu));
776 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
777 we_event = SIOCGIWAP;
778#ifdef WLAN_FEATURE_ROAM_OFFLOAD
779 if (NULL != pCsrRoamInfo)
780 if (pCsrRoamInfo->roamSynchInProgress)
781 /* change logging before release */
782 hddLog(LOG4, "LFR3:hdd_send_association_event");
783#endif
784 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
Abhishek Singh1c676222016-05-09 14:20:28 +0530785 tSirSmeChanInfo chan_info;
786
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800787 if (!pCsrRoamInfo) {
788 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
789 return;
790 }
791
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800792 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
793 cds_incr_active_session(pAdapter->device_mode,
794 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800795 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
796 sizeof(pCsrRoamInfo->pBssDesc->bssId));
797
798#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -0800799 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800800 if (global_p2p_connection_status ==
801 P2P_CLIENT_CONNECTING_STATE_1) {
802 global_p2p_connection_status =
803 P2P_CLIENT_CONNECTED_STATE_1;
804 hddLog(LOGE,
805 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
806 } else if (global_p2p_connection_status ==
807 P2P_CLIENT_CONNECTING_STATE_2) {
808 global_p2p_connection_status =
809 P2P_CLIENT_COMPLETED_STATE;
810 hddLog(LOGE,
811 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
812 }
813 }
814#endif
815 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
816 MAC_ADDRESS_STR "\n",
817 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
818 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
819 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
820
821 /*
822 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
823 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800824 * fFTEnable is true.
825 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800826 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800827 if ((pRoamProfile->AuthType.authType[0] ==
828 eCSR_AUTH_TYPE_FT_RSN_PSK)
829 || (pRoamProfile->AuthType.authType[0] ==
830 eCSR_AUTH_TYPE_FT_RSN)
831#ifdef FEATURE_WLAN_ESE
832 || (pRoamProfile->AuthType.authType[0] ==
833 eCSR_AUTH_TYPE_CCKM_RSN)
834 || (pRoamProfile->AuthType.authType[0] ==
835 eCSR_AUTH_TYPE_CCKM_WPA)
836#endif
837 ) {
838 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
839 }
Abhishek Singh1c676222016-05-09 14:20:28 +0530840 qdf_copy_macaddr(&peerMacAddr,
841 &pHddStaCtx->conn_info.bssId);
842 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
843 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
844 chan_info.info = pCsrRoamInfo->chan_info.info;
845 chan_info.band_center_freq1 =
846 pCsrRoamInfo->chan_info.band_center_freq1;
847 chan_info.band_center_freq2 =
848 pCsrRoamInfo->chan_info.band_center_freq2;
849 chan_info.reg_info_1 =
850 pCsrRoamInfo->chan_info.reg_info_1;
851 chan_info.reg_info_2 =
852 pCsrRoamInfo->chan_info.reg_info_2;
853 /* send peer status indication to oem app */
854 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
855 ePeerConnected,
856 pCsrRoamInfo->
857 timingMeasCap,
858 pAdapter->sessionId,
859 &chan_info,
860 pAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800861
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800862#ifdef MSM_PLATFORM
863#ifdef CONFIG_CNSS
864 /* start timer in sta/p2p_cli */
865 spin_lock_bh(&pHddCtx->bus_bw_lock);
866 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
867 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530868 ol_get_intra_bss_fwd_pkts_count(pAdapter->sessionId,
869 &pAdapter->prev_fwd_tx_packets,
870 &pAdapter->prev_fwd_rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800871 spin_unlock_bh(&pHddCtx->bus_bw_lock);
872 hdd_start_bus_bw_compute_timer(pAdapter);
873#endif
874#endif
875 } else if (eConnectionState_IbssConnected == /* IBss Associated */
876 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800877 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800878 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
879 ETH_ALEN);
880 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
881 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
882 } else { /* Not Associated */
883
884 pr_info("wlan: disconnected\n");
885 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530886 cds_decr_session_set_pcl(pAdapter->device_mode,
887 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800889
890#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
891 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
892#endif
893
Abhishek Singh1c676222016-05-09 14:20:28 +0530894 if ((pAdapter->device_mode == QDF_STA_MODE) ||
895 (pAdapter->device_mode == QDF_P2P_CLIENT_MODE)) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530896 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800897 &pHddStaCtx->conn_info.bssId);
898
899 /* send peer status indication to oem app */
900 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
Abhishek Singh1c676222016-05-09 14:20:28 +0530901 ePeerDisconnected, 0,
902 pAdapter->sessionId,
903 NULL,
904 pAdapter->device_mode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800905 }
906#ifdef WLAN_FEATURE_LPSS
907 pAdapter->rssi_send = false;
908 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
909#endif
910#ifdef FEATURE_WLAN_TDLS
Krunal Sonibe766b02016-03-10 13:00:44 -0800911 if ((pAdapter->device_mode == QDF_STA_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800912 (pCsrRoamInfo)) {
913 hddLog(LOG4,
914 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
915 pCsrRoamInfo->tdls_prohibited,
916 pCsrRoamInfo->tdls_chan_swit_prohibited);
917
918 wlan_hdd_update_tdls_info(pAdapter,
919 pCsrRoamInfo->tdls_prohibited,
920 pCsrRoamInfo->tdls_chan_swit_prohibited);
921 }
922#endif
923#ifdef MSM_PLATFORM
924 /* stop timer in sta/p2p_cli */
925 spin_lock_bh(&pHddCtx->bus_bw_lock);
926 pAdapter->prev_tx_packets = 0;
927 pAdapter->prev_rx_packets = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530928 pAdapter->prev_fwd_tx_packets = 0;
929 pAdapter->prev_fwd_rx_packets = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800930 spin_unlock_bh(&pHddCtx->bus_bw_lock);
931 hdd_stop_bus_bw_compute_timer(pAdapter);
932#endif
933 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800934 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800935 /* Send SCC/MCC Switching event to IPA */
936 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
937
938 msg = NULL;
939 /*During the WLAN uninitialization,supplicant is stopped before the
940 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800941 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800942 wireless_send_event(dev, we_event, &wrqu, msg);
943#ifdef FEATURE_WLAN_ESE
944 if (eConnectionState_Associated ==
945 pHddStaCtx->conn_info.connState) {
946 if ((pRoamProfile->AuthType.authType[0] ==
947 eCSR_AUTH_TYPE_CCKM_RSN) ||
948 (pRoamProfile->AuthType.authType[0] ==
949 eCSR_AUTH_TYPE_CCKM_WPA))
950 hdd_send_new_ap_channel_info(dev, pAdapter,
951 pCsrRoamInfo);
952 }
953#endif
954 }
955}
956
957/**
958 * hdd_conn_remove_connect_info() - remove connection info
959 * @pHddStaCtx: pointer to global HDD station context
960 * @pCsrRoamInfo: pointer to roam info
961 *
962 * Return: none
963 */
964static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
965{
966 /* Remove staId, bssId and peerMacAddress */
967 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530968 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
969 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530970 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800971
972 /* Clear all security settings */
973 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
974 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
975 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
976
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530977 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
978 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800979
980 /* Set not-connected state */
981 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
982 pHddStaCtx->conn_info.proxyARPService = 0;
983
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530984 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800985}
986
987/**
988 * hdd_roam_deregister_sta() - deregister station
989 * @pAdapter: pointer to adapter
990 * @staId: station identifier
991 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530992 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800993 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530994static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
996{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530997 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800998 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
999
1000 if (eConnectionState_IbssDisconnected ==
1001 pHddStaCtx->conn_info.connState) {
1002 /*
1003 * Do not set the carrier off when the last peer leaves.
1004 * We will set the carrier off while stopping the IBSS.
1005 */
1006 }
1007
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301008 qdf_status = ol_txrx_clear_peer(staId);
1009 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010 hddLog(LOGE,
1011 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301012 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001013 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301014 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001015}
1016
1017/**
1018 * hdd_dis_connect_handler() - disconnect event handler
1019 * @pAdapter: pointer to adapter
1020 * @pRoamInfo: pointer to roam info
1021 * @roamId: roam identifier
1022 * @roamStatus: roam status
1023 * @roamResult: roam result
1024 *
1025 * This function handles disconnect event:
1026 * 1. Disable transmit queues;
1027 * 2. Clean up internal connection states and data structures;
1028 * 3. Send disconnect indication to supplicant.
1029 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301030 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001031 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301032static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001033 tCsrRoamInfo *pRoamInfo,
1034 uint32_t roamId,
1035 eRoamCmdStatus roamStatus,
1036 eCsrRoamResult roamResult)
1037{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301038 QDF_STATUS status = QDF_STATUS_SUCCESS;
1039 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001040 struct net_device *dev = pAdapter->dev;
1041 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1042 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1043 uint8_t sta_id;
1044 bool sendDisconInd = true;
1045
1046 if (dev == NULL) {
1047 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301048 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049 }
1050 /* notify apps that we can't pass traffic anymore */
1051 hddLog(LOG1, FL("Disabling queues"));
1052 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
1053 WLAN_CONTROL_PATH);
1054
1055 if (hdd_ipa_is_enabled(pHddCtx))
1056 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
1057 WLAN_STA_DISCONNECT,
1058 pHddStaCtx->conn_info.bssId.bytes);
1059
1060#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1061 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1062#endif
1063
Nirav Shah1da77682016-05-03 20:16:39 +05301064 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1065 pAdapter->sessionId,
1066 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_DISASSOC));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001067
1068 /* HDD has initiated disconnect, do not send disconnect indication
1069 * to kernel. Sending disconnected event to kernel for userspace
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05301070 * initiated disconnect will be handled by disconnect handler call
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001071 * to cfg80211_disconnected.
1072 */
1073 if ((eConnectionState_Disconnecting ==
1074 pHddStaCtx->conn_info.connState) ||
1075 (eConnectionState_NotConnected ==
1076 pHddStaCtx->conn_info.connState)) {
1077 hddLog(LOG1,
1078 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1079 sendDisconInd = false;
1080 }
1081
1082 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1083 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001084 hdd_conn_set_connection_state(pAdapter,
1085 eConnectionState_Disconnecting);
1086 }
1087
1088 hdd_clear_roam_profile_ie(pAdapter);
1089 hdd_wmm_init(pAdapter);
1090
1091 /* indicate 'disconnect' status to wpa_supplicant... */
1092 hdd_send_association_event(dev, pRoamInfo);
1093 /* indicate disconnected event to nl80211 */
1094 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1095 /*
1096 * Only send indication to kernel if not initiated
1097 * by kernel
1098 */
1099 if (sendDisconInd) {
1100 /*
1101 * To avoid wpa_supplicant sending "HANGED" CMD
1102 * to ICS UI.
1103 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001104 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1105 if (pRoamInfo->reasonCode ==
1106 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1107 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05301108 wlan_hdd_cfg80211_indicate_disconnect(
1109 dev, false,
1110 pRoamInfo->reasonCode);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001111 } else {
Mahesh A Saptasagarc35e8bf2016-06-17 20:03:46 +05301112 wlan_hdd_cfg80211_indicate_disconnect(
1113 dev, false,
1114 WLAN_REASON_UNSPECIFIED
1115 );
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001116 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001117
1118 hdd_info("sent disconnected event to nl80211, rssi: %d",
1119 pAdapter->rssi);
1120 }
1121 /*
1122 * During the WLAN uninitialization,supplicant is stopped
1123 * before the driver so not sending the status of the
1124 * connection to supplicant.
1125 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001126 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001127#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -08001128 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001129 if (global_p2p_connection_status ==
1130 P2P_CLIENT_CONNECTED_STATE_1) {
1131 global_p2p_connection_status =
1132 P2P_CLIENT_DISCONNECTED_STATE;
1133 hddLog(LOGE,
1134 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1135 } else if (global_p2p_connection_status ==
1136 P2P_CLIENT_COMPLETED_STATE) {
1137 global_p2p_connection_status =
1138 P2P_NOT_ACTIVE;
1139 hddLog(LOGE,
1140 "[P2P State] P2P Client is removed and moved to inactive state");
1141 }
1142 }
1143#endif
1144
1145 }
1146 }
1147
1148 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001149 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001150 if (hdd_remove_beacon_filter(pAdapter) != 0)
1151 hdd_err("hdd_remove_beacon_filter() failed");
1152
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001153 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301154 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301155 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001156 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301157 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301158 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1159 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301160 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001161 }
1162 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301163 /* Clear all the peer sta register with TL. */
1164 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1165 if (0 == pHddStaCtx->conn_info.staId[i])
1166 continue;
1167 sta_id = pHddStaCtx->conn_info.staId[i];
1168 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1169 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301170 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301171 hddLog(LOGE,
1172 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1173 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301174 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301175 }
1176 /* set the staid and peer mac as 0, all other
1177 * reset are done in hdd_connRemoveConnectInfo.
1178 */
1179 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301180 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301181 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301182 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1183 pHddCtx->sta_to_adapter[sta_id] = NULL;
1184 }
1185 } else {
1186 sta_id = pHddStaCtx->conn_info.staId[0];
1187 /* We should clear all sta register with TL,
1188 * for now, only one.
1189 */
1190 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301191 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301192 hddLog(LOGE,
1193 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1194 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301196 }
1197 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001198 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001199 /* Clear saved connection information in HDD */
1200 hdd_conn_remove_connect_info(pHddStaCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1202#ifdef WLAN_FEATURE_GTK_OFFLOAD
Krunal Sonibe766b02016-03-10 13:00:44 -08001203 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1204 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1206 sizeof(tSirGtkOffloadParams));
1207 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1208 }
1209#endif
1210
1211#ifdef FEATURE_WLAN_TDLS
1212 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1213 wlan_hdd_tdls_disconnection_callback(pAdapter);
1214#endif
1215
Krunal Sonibe766b02016-03-10 13:00:44 -08001216 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1217 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001218 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1219 (pAdapter),
1220 pAdapter->sessionId);
1221 }
1222 /* Unblock anyone waiting for disconnect to complete */
1223 complete(&pAdapter->disconnect_comp_var);
1224 return status;
1225}
1226
1227/**
1228 * hdd_set_peer_authorized_event() - set peer_authorized_event
1229 * @vdev_id: vdevid
1230 *
1231 * Return: None
1232 */
1233void hdd_set_peer_authorized_event(uint32_t vdev_id)
1234{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301235 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001236 hdd_adapter_t *adapter = NULL;
1237
1238 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1239 if (adapter == NULL) {
1240 hddLog(LOGE,
1241 "%s: Invalid vdev_id", __func__);
1242 }
1243 complete(&adapter->sta_authorized_event);
1244}
1245
1246/**
1247 * hdd_change_peer_state() - change peer state
1248 * @pAdapter: HDD adapter
1249 * @sta_state: peer state
1250 * @roam_synch_in_progress: roam synch in progress
1251 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301252 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001253 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301254QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001255 uint8_t sta_id,
1256 enum ol_txrx_peer_state sta_state,
1257 bool roam_synch_in_progress)
1258{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301259 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001260 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001261 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001262 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001263
1264 if (!pdev) {
1265 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301266 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267 }
1268
1269 if (sta_id >= WLAN_MAX_STA_COUNT) {
1270 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301271 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001272 }
1273
1274 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1275 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301276 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001277
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001278 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1279 if (peer_mac_addr == NULL) {
1280 hddLog(LOGE, "peer mac addr is NULL");
1281 return QDF_STATUS_E_FAULT;
1282 }
1283
1284 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301285 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001286 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301287 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288 }
1289#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1290 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301291 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292#endif
1293
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001294 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001295#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1296 /* make sure event is reset */
1297 INIT_COMPLETION(pAdapter->sta_authorized_event);
1298#endif
1299
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001300 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001301 hdd_set_peer_authorized_event,
1302 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301303 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001304 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301305 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001306 }
1307
Krunal Sonibe766b02016-03-10 13:00:44 -08001308 if (pAdapter->device_mode == QDF_STA_MODE ||
1309 pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Houston Hoffman52ec6692016-04-21 16:36:45 -07001311 ol_txrx_vdev_handle vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001312 unsigned long rc;
1313
1314 /* wait for event from firmware to set the event */
1315 rc = wait_for_completion_timeout(
1316 &pAdapter->sta_authorized_event,
1317 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1318 if (!rc) {
1319 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1320 __func__);
1321 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001322 vdev = ol_txrx_get_vdev_for_peer(peer);
1323 ol_txrx_vdev_unpause(vdev,
1324 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325#endif
1326 }
1327 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301328 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329}
1330
1331/**
1332 * hdd_roam_register_sta() - register station
1333 * @pAdapter: pointer to adapter
1334 * @pRoamInfo: pointer to roam info
1335 * @staId: station identifier
1336 * @pPeerMacAddress: peer MAC address
1337 * @pBssDesc: pointer to BSS description
1338 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301339 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001340 */
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07001341QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001342 tCsrRoamInfo *pRoamInfo,
1343 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301344 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001345 tSirBssDescription *pBssDesc)
1346{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301347 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 struct ol_txrx_desc_type staDesc = { 0 };
1349 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001350 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001351
1352 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301353 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001354
1355 /* Get the Station ID from the one saved during the association */
1356 staDesc.sta_id = staId;
1357
1358 /* set the QoS field appropriately */
1359 if (hdd_wmm_is_active(pAdapter))
1360 staDesc.is_qos_enabled = 1;
1361 else
1362 staDesc.is_qos_enabled = 0;
1363
1364#ifdef FEATURE_WLAN_WAPI
1365 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1366 pAdapter->wapi_info.fIsWapiSta);
1367 if (pAdapter->wapi_info.fIsWapiSta)
1368 staDesc.is_wapi_supported = 1;
1369 else
1370 staDesc.is_wapi_supported = 0;
1371#endif /* FEATURE_WLAN_WAPI */
1372
Dhanashri Atre50141c52016-04-07 13:15:29 -07001373 /* Register the vdev transmit and receive functions */
1374 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1375 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1376 ol_txrx_vdev_register(
1377 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1378 pAdapter, &txrx_ops);
1379 pAdapter->tx_fn = txrx_ops.tx.tx;
1380
Dhanashri Atre182b0272016-02-17 15:35:07 -08001381 qdf_status = ol_txrx_register_peer(&staDesc);
1382
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301383 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001384 hddLog(LOGW,
1385 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301386 qdf_status, qdf_status);
1387 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388 }
1389
1390 if (!pRoamInfo->fAuthRequired) {
1391 /*
1392 * Connections that do not need Upper layer auth, transition
1393 * TLSHIM directly to 'Authenticated' state
1394 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301395 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001396 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001397 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1399 pRoamInfo->roamSynchInProgress
1400#else
1401 false
1402#endif
1403 );
1404
1405 hdd_conn_set_authenticated(pAdapter, true);
1406 } else {
1407 hddLog(LOG3,
1408 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1409 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301410 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001411 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001412 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001413#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1414 pRoamInfo->roamSynchInProgress
1415#else
1416 false
1417#endif
1418 );
1419 hdd_conn_set_authenticated(pAdapter, false);
1420 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301421 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001422}
1423
1424/**
1425 * hdd_send_re_assoc_event() - send reassoc event
1426 * @dev: pointer to net device
1427 * @pAdapter: pointer to adapter
1428 * @pCsrRoamInfo: pointer to roam info
1429 * @reqRsnIe: pointer to RSN Information element
1430 * @reqRsnLength: length of RSN IE
1431 *
1432 * Return: none
1433 */
1434static void hdd_send_re_assoc_event(struct net_device *dev,
1435 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1436 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1437{
1438 unsigned int len = 0;
1439 u8 *pFTAssocRsp = NULL;
1440 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001441 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001442 uint32_t rspRsnLength = 0;
1443 struct ieee80211_channel *chan;
1444 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1445 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1446 uint8_t *buf_ptr, ssid_ie_len;
1447 struct cfg80211_bss *bss = NULL;
1448 uint8_t *final_req_ie = NULL;
1449 tCsrRoamConnectedProfile roam_profile;
1450 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1451
1452 if (!rspRsnIe) {
1453 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001454 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001455 }
1456
Naveen Rawat14298b92015-11-25 16:27:41 -08001457 if (!assoc_req_ies) {
1458 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001459 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001460 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001461 if (pCsrRoamInfo == NULL) {
1462 hddLog(LOGE, FL("Invalid CSR roam info"));
1463 goto done;
1464 }
1465
1466 if (pCsrRoamInfo->nAssocRspLength == 0) {
1467 hddLog(LOGE, FL("Invalid assoc response length"));
1468 goto done;
1469 }
1470
1471 pFTAssocRsp =
1472 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1473 pCsrRoamInfo->nAssocReqLength);
1474 if (pFTAssocRsp == NULL)
1475 goto done;
1476
1477 /* pFTAssocRsp needs to point to the IEs */
1478 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1479 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1480 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1481
1482 /*
1483 * Active session count is decremented upon disconnection, but during
1484 * roaming, there is no disconnect indication and hence active session
1485 * count is not decremented.
1486 * After roaming is completed, active session count is incremented
1487 * as a part of connect indication but effectively after roaming the
1488 * active session count should still be the same and hence upon
1489 * successful reassoc decrement the active session count here.
1490 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001491 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05301492 cds_decr_session_set_pcl(pAdapter->device_mode,
1493 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494
1495 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1496 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1497 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301498 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1499 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500
1501 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1502 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301503 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1505 &roam_profile);
1506 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1507 pCsrRoamInfo->bssid.bytes,
1508 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001509#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001510 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001511#else
1512 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1513#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514
1515 if (bss == NULL)
1516 hddLog(LOGE, FL("Get BSS returned NULL"));
1517 buf_ptr = buf_ssid_ie;
1518 *buf_ptr = SIR_MAC_SSID_EID;
1519 buf_ptr++;
1520 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1521 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301522 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001523 roam_profile.SSID.length);
1524 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001525 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301526 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001527 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001528 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1529 if (final_req_ie == NULL)
1530 goto done;
1531 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301532 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001533 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301534 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1535 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1536 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001538 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301539 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001540 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541 cfg80211_roamed_bss(dev, bss,
1542 final_req_ie, (ssid_ie_len + reqRsnLength),
1543 rspRsnIe, rspRsnLength, GFP_KERNEL);
1544
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301545 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001546 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1547 pCsrRoamInfo->nAssocReqLength);
1548
1549 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301550 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001551 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1552
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001553 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001554 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1555 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001556 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001557done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001558 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001559 if (final_req_ie)
1560 kfree(final_req_ie);
1561 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001562 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563}
1564
1565/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301566 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001567 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301568 *
1569 * Return: roam sync status if roaming offloaded else false
1570 */
1571#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001572bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301573{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001574 if (roaminfo)
1575 return roaminfo->roamSynchInProgress;
1576 else
1577 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301578}
1579#endif
1580
1581
1582/**
1583 * hdd_change_sta_state_authenticated()-
1584 * This function changes STA state to authenticated
1585 * @adapter: pointer to the adapter structure.
1586 * @roaminfo: pointer to the RoamInfo structure.
1587 *
1588 * This is called from hdd_RoamSetKeyCompleteHandler
1589 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1590 *
1591 * Return: 0 on success and errno on failure
1592 */
1593static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1594 tCsrRoamInfo *roaminfo)
1595{
1596 int ret;
1597 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1598
1599 hddLog(LOG1,
1600 "Changing TL state to AUTHENTICATED for StaId= %d",
1601 hddstactx->conn_info.staId[0]);
1602
1603 /* Connections that do not need Upper layer authentication,
1604 * transition TL to 'Authenticated' state after the keys are set
1605 */
1606 ret = hdd_change_peer_state(adapter,
1607 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001608 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301609 hdd_is_roam_sync_in_progress(roaminfo));
1610 hdd_conn_set_authenticated(adapter, true);
Krunal Sonibe766b02016-03-10 13:00:44 -08001611 if ((QDF_STA_MODE == adapter->device_mode) ||
1612 (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301613 sme_ps_enable_auto_ps_timer(
1614 WLAN_HDD_GET_HAL_CTX(adapter),
1615 adapter->sessionId,
1616 hddstactx->hdd_ReassocScenario);
1617 }
1618
1619 return ret;
1620}
1621
1622/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001623 * hdd_roam_set_key_complete_handler() - Update the security parameters
1624 * @pAdapter: pointer to adapter
1625 * @pRoamInfo: pointer to roam info
1626 * @roamId: roam id
1627 * @roamStatus: roam status
1628 * @roamResult: roam result
1629 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301630 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001631 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301632static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001633 tCsrRoamInfo *pRoamInfo,
1634 uint32_t roamId,
1635 eRoamCmdStatus roamStatus,
1636 eCsrRoamResult roamResult)
1637{
1638 eCsrEncryptionType connectedCipherAlgo;
1639 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301640 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001641 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301642 tHalHandle hal_ctx = WLAN_HDD_GET_HAL_CTX(pAdapter);
1643 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1644
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 ENTER();
1646
1647 if (NULL == pRoamInfo) {
1648 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301649 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001650 }
1651 /*
1652 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1653 * then go to 'authenticated'. For all other authentication types
1654 * (those that do not require upper layer authentication) we can put TL
1655 * directly into 'authenticated' state.
1656 */
1657 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1658 MAC_ADDRESS_STR, roamStatus, roamResult,
1659 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1660
1661 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1662 &connectedCipherAlgo);
1663 if (fConnected) {
Krunal Sonibe766b02016-03-10 13:00:44 -08001664 if (QDF_IBSS_MODE == pAdapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001665 uint8_t staId;
1666
Anurag Chouhanc5548422016-02-24 18:33:27 +05301667 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001668 pHddStaCtx->roam_info.roamingState =
1669 HDD_ROAM_STATE_NONE;
1670 } else {
Deepak Dhamdhere5872c8c2016-06-02 15:51:47 -07001671 qdf_status = hdd_get_peer_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672 pHddStaCtx,
1673 &pRoamInfo->peerMac,
1674 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301675 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 hddLog(LOG2,
1677 "WLAN TL STA Ptk Installed for STAID=%d",
1678 staId);
1679 pHddStaCtx->roam_info.roamingState =
1680 HDD_ROAM_STATE_NONE;
1681 }
1682 }
1683 } else {
1684 /*
1685 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301686 * HDD later.This routine is invoked twice.
1687 * 1)set PTK 2)set GTK.The following if
1688 * statement will be TRUE when setting GTK.
1689 * At this time we don't handle the state in detail.
1690 * Related CR: 174048 - TL not in authenticated state
1691 */
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301692 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301693 pHddStaCtx->conn_info.gtk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301694 /*
1695 * PTK exchange happens in preauthentication
1696 * itself if key_mgmt is FT-PSK, ptk_installed
1697 * was false as there is no set PTK after
1698 * roaming. STA TL state moves to authenticated
1699 * only if ptk_installed is true. So, make
1700 * ptk_installed to true in case of 11R roaming.
1701 */
1702 if (csr_neighbor_roam_is11r_assoc(mac_ctx,
1703 pAdapter->sessionId))
1704 pHddStaCtx->conn_info.ptk_installed =
1705 true;
1706 } else {
Govind Singhedc5cda2015-10-23 17:11:35 +05301707 pHddStaCtx->conn_info.ptk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301708 }
Govind Singhedc5cda2015-10-23 17:11:35 +05301709
1710 /* In WPA case move STA to authenticated when
1711 * ptk is installed.Earlier in WEP case STA
1712 * was moved to AUTHENTICATED prior to setting
1713 * the unicast key and it was resulting in sending
1714 * few un-encrypted packet. Now in WEP case
1715 * STA state will be moved to AUTHENTICATED
1716 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301718 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1719 eCSR_ENCRYPT_TYPE_WEP40) ||
1720 (pHddStaCtx->conn_info.ucEncryptionType ==
1721 eCSR_ENCRYPT_TYPE_WEP104) ||
1722 (pHddStaCtx->conn_info.ucEncryptionType ==
1723 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1724 (pHddStaCtx->conn_info.ucEncryptionType ==
1725 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1726 if (pHddStaCtx->conn_info.gtk_installed &&
1727 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301728 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301729 hdd_change_sta_state_authenticated(pAdapter,
1730 pRoamInfo);
1731 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301732 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301733 hdd_change_sta_state_authenticated(pAdapter,
1734 pRoamInfo);
1735 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001736
Govind Singhedc5cda2015-10-23 17:11:35 +05301737 if (pHddStaCtx->conn_info.gtk_installed &&
1738 pHddStaCtx->conn_info.ptk_installed) {
1739 pHddStaCtx->conn_info.gtk_installed = false;
1740 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001741 }
1742
1743 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301744 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001745 }
1746 } else {
1747 /*
1748 * possible disassoc after issuing set key and waiting
1749 * set key complete.
1750 */
1751 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1752 }
1753
1754 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301755 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001756}
1757
1758/**
1759 * hdd_perform_roam_set_key_complete() - perform set key complete
1760 * @pAdapter: pointer to adapter
1761 *
1762 * Return: none
1763 */
1764void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1765{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301766 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001767 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1768 tCsrRoamInfo roamInfo;
1769 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301770 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301771 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301772 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301773 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001774
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301775 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001776 hdd_roam_set_key_complete_handler(pAdapter,
1777 &roamInfo,
1778 pHddStaCtx->roam_info.roamId,
1779 pHddStaCtx->roam_info.roamStatus,
1780 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301781 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001782 hddLog(LOGE, FL("Set Key complete failure"));
1783
1784 pHddStaCtx->roam_info.deferKeyComplete = false;
1785}
1786
1787/**
1788 * hdd_association_completion_handler() - association completion handler
1789 * @pAdapter: pointer to adapter
1790 * @pRoamInfo: pointer to roam info
1791 * @roamId: roam id
1792 * @roamStatus: roam status
1793 * @roamResult: roam result
1794 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301795 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001796 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301797static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001798 tCsrRoamInfo *pRoamInfo,
1799 uint32_t roamId,
1800 eRoamCmdStatus roamStatus,
1801 eCsrRoamResult roamResult)
1802{
1803 struct net_device *dev = pAdapter->dev;
1804 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1805 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301806 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001807 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1808 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001809 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001810 bool hddDisconInProgress = false;
1811 unsigned long rc;
1812
1813 if (!pHddCtx) {
1814 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301815 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001816 }
1817
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001818 /* HDD has initiated disconnect, do not send connect result indication
1819 * to kernel as it will be handled by __cfg80211_disconnect.
1820 */
1821 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1822 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1823 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1824 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1825 hddDisconInProgress = true;
1826 }
1827
1828 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1829 if (NULL == pRoamInfo) {
1830 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301831 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001832 }
1833 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001834 hdd_conn_set_connection_state(pAdapter,
1835 eConnectionState_Associated);
1836 }
1837 /* Save the connection info from CSR... */
1838 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1839 eCSR_BSS_TYPE_INFRASTRUCTURE);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001840
1841 if (hdd_add_beacon_filter(pAdapter) != 0)
1842 hdd_err("hdd_add_beacon_filter() failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001843#ifdef FEATURE_WLAN_WAPI
1844 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1845 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1846 || pRoamInfo->u.pConnectedProfile->AuthType ==
1847 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1848 pAdapter->wapi_info.fIsWapiSta = 1;
1849 } else {
1850 pAdapter->wapi_info.fIsWapiSta = 0;
1851 }
1852#endif /* FEATURE_WLAN_WAPI */
1853
1854 /* Indicate 'connect' status to user space */
1855 hdd_send_association_event(dev, pRoamInfo);
1856
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001857 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001858 if (pHddCtx->miracast_value)
1859 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1860 }
1861
1862 /* Initialize the Linkup event completion variable */
1863 INIT_COMPLETION(pAdapter->linkup_event_var);
1864
1865 /*
1866 * Sometimes Switching ON the Carrier is taking time to activate
1867 * the device properly. Before allowing any packet to go up to
1868 * the application, device activation has to be ensured for
1869 * proper queue mapping by the kernel. we have registered net
1870 * device notifier for device change notification. With this we
1871 * will come to know that the device is getting
1872 * activated properly.
1873 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001874 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001875 /*
1876 * Enable Linkup Event Servicing which allows the net
1877 * device notifier to set the linkup event variable.
1878 */
1879 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001880
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001881 /* Switch on the Carrier to activate the device */
1882 wlan_hdd_netif_queue_control(pAdapter,
1883 WLAN_NETIF_CARRIER_ON,
1884 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001885
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001886 /*
1887 * Wait for the Link to up to ensure all the queues
1888 * are set properly by the kernel.
1889 */
1890 rc = wait_for_completion_timeout(
1891 &pAdapter->linkup_event_var,
1892 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1893 );
1894 if (!rc)
1895 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001896
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001897 /*
1898 * Disable Linkup Event Servicing - no more service
1899 * required from the net device notifier call.
1900 */
1901 pAdapter->isLinkUpSvcNeeded = false;
1902 } else {
1903 pHddStaCtx->ft_carrier_on = false;
1904 ft_carrier_on = true;
1905 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001906 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1907 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1908 else
1909 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1910 pRoamInfo->staId);
1911
1912 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1913
1914 if (hdd_ipa_is_enabled(pHddCtx))
1915 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1916 WLAN_STA_CONNECT,
1917 pRoamInfo->bssid.bytes);
1918
1919#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1920 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1921#endif
1922
Chandrasekaran Manishekar068e25e2016-03-07 11:51:07 +05301923 hdd_info("check for SAP restart");
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001924 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001925 pAdapter);
1926
1927#ifdef FEATURE_WLAN_TDLS
1928 wlan_hdd_tdls_connection_callback(pAdapter);
1929#endif
1930
Nirav Shah1da77682016-05-03 20:16:39 +05301931 DPTRACE(qdf_dp_trace_mgmt_pkt(QDF_DP_TRACE_MGMT_PACKET_RECORD,
1932 pAdapter->sessionId,
1933 QDF_PROTO_TYPE_MGMT, QDF_PROTO_MGMT_ASSOC));
1934
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001935 /*
1936 * For reassoc, the station is already registered, all we need
1937 * is to change the state of the STA in TL.
1938 * If authentication is required (WPA/WPA2/DWEP), change TL to
1939 * CONNECTED instead of AUTHENTICATED.
1940 */
1941 if (!pRoamInfo->fReassocReq) {
1942 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001943 u8 *pFTAssocRsp = NULL;
1944 unsigned int assocRsplen = 0;
1945 u8 *pFTAssocReq = NULL;
1946 unsigned int assocReqlen = 0;
1947 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001948 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1949 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1950
1951 /* add bss_id to cfg80211 data base */
1952 bss =
1953 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1954 pRoamInfo);
1955 if (NULL == bss) {
1956 pr_err("wlan: Not able to create BSS entry\n");
1957 wlan_hdd_netif_queue_control(pAdapter,
1958 WLAN_NETIF_CARRIER_OFF,
1959 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301960 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001962 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1963 eCSR_AUTH_TYPE_FT_RSN
1964 || pRoamInfo->u.pConnectedProfile->AuthType ==
1965 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1966
1967 /* Association Response */
1968 pFTAssocRsp =
1969 (u8 *) (pRoamInfo->pbFrames +
1970 pRoamInfo->nBeaconLength +
1971 pRoamInfo->nAssocReqLength);
1972 if (pFTAssocRsp != NULL) {
1973 /*
1974 * pFTAssocRsp needs to point to the IEs
1975 */
1976 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1977 hddLog(LOG1,
1978 FL("AssocRsp is now at %02x%02x"),
1979 (unsigned int)pFTAssocRsp[0],
1980 (unsigned int)pFTAssocRsp[1]);
1981 assocRsplen =
1982 pRoamInfo->nAssocRspLength -
1983 FT_ASSOC_RSP_IES_OFFSET;
1984 } else {
1985 hddLog(LOGE, FL("AssocRsp is NULL"));
1986 assocRsplen = 0;
1987 }
1988
1989 /* Association Request */
1990 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1991 pRoamInfo->nBeaconLength);
1992 if (pFTAssocReq != NULL) {
1993 if (!ft_carrier_on) {
1994 /*
1995 * pFTAssocReq needs to point to
1996 * the IEs
1997 */
1998 pFTAssocReq +=
1999 FT_ASSOC_REQ_IES_OFFSET;
2000 hddLog(LOG1,
2001 FL("pFTAssocReq is now at %02x%02x"),
2002 (unsigned int)
2003 pFTAssocReq[0],
2004 (unsigned int)
2005 pFTAssocReq[1]);
2006 assocReqlen =
2007 pRoamInfo->nAssocReqLength -
2008 FT_ASSOC_REQ_IES_OFFSET;
2009 } else {
2010 /*
2011 * This should contain only the
2012 * FTIEs
2013 */
2014 assocReqlen =
2015 pRoamInfo->nAssocReqLength;
2016 }
2017 } else {
2018 hddLog(LOGE, FL("AssocReq is NULL"));
2019 assocReqlen = 0;
2020 }
2021
2022 if (ft_carrier_on) {
2023 if (!hddDisconInProgress) {
2024 /*
2025 * After roaming is completed,
2026 * active session count is
2027 * incremented as a part of
2028 * connect indication but
2029 * effectively the active
2030 * session count should still
2031 * be the same and hence upon
2032 * successful reassoc
2033 * decrement the active session
2034 * count here.
2035 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002036 if (!hdd_is_roam_sync_in_progress
2037 (pRoamInfo))
2038 cds_decr_session_set_pcl
2039 (pAdapter->device_mode,
2040 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002041 hddLog(LOG1,
2042 FL("ft_carrier_on is %d, sending roamed indication"),
2043 ft_carrier_on);
2044 chan =
2045 ieee80211_get_channel
2046 (pAdapter->wdev.wiphy,
2047 (int)pRoamInfo->pBssDesc->
2048 channelId);
2049 hddLog(LOG1,
2050 "assocReqlen %d assocRsplen %d",
2051 assocReqlen,
2052 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08002053
2054 hdd_notice(
2055 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302056 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05302057 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302058 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002059 pFTAssocReq,
2060 assocReqlen);
2061
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002062 cfg80211_roamed(dev, chan,
2063 pRoamInfo->
2064 bssid.bytes,
2065 pFTAssocReq,
2066 assocReqlen,
2067 pFTAssocRsp,
2068 assocRsplen,
2069 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08002070 wlan_hdd_send_roam_auth_event(
2071 pHddCtx,
2072 pRoamInfo->bssid.bytes,
2073 pFTAssocReq,
2074 assocReqlen,
2075 pFTAssocRsp,
2076 assocRsplen,
2077 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002078 }
2079 if (sme_get_ftptk_state
2080 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2081 pAdapter->sessionId)) {
2082 sme_set_ftptk_state
2083 (WLAN_HDD_GET_HAL_CTX
2084 (pAdapter),
2085 pAdapter->sessionId,
2086 false);
2087 pRoamInfo->fAuthRequired =
2088 false;
2089
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302090 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002091 roam_info.bssid,
2092 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302093 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302094 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002095 roam_info.peerMac,
2096 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302097 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002098 pHddStaCtx->roam_info.roamId =
2099 roamId;
2100 pHddStaCtx->roam_info.
2101 roamStatus = roamStatus;
2102 pHddStaCtx->roam_info.
2103 deferKeyComplete = true;
2104 }
2105 } else if (!hddDisconInProgress) {
2106 hddLog(LOG1,
2107 FL("ft_carrier_on is %d, sending connect indication"),
2108 ft_carrier_on);
2109 cfg80211_connect_result(dev,
2110 pRoamInfo->
2111 bssid.bytes,
2112 pFTAssocReq,
2113 assocReqlen,
2114 pFTAssocRsp,
2115 assocRsplen,
2116 WLAN_STATUS_SUCCESS,
2117 GFP_KERNEL);
2118 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002119 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002120 /*
2121 * wpa supplicant expecting WPA/RSN IE in
2122 * connect result.
2123 */
2124 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2125 (pAdapter),
2126 pAdapter->sessionId,
2127 &reqRsnLength,
2128 reqRsnIe);
2129
2130 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2131 (pAdapter),
2132 pAdapter->sessionId,
2133 &rspRsnLength,
2134 rspRsnIe);
2135 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002136 if (ft_carrier_on)
2137 hdd_send_re_assoc_event(dev,
2138 pAdapter,
2139 pRoamInfo,
2140 reqRsnIe,
2141 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002142 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002143 hddLog(LOG1,
2144 FL("sending connect indication to nl80211:for bssid "
2145 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302146 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002147 MAC_ADDR_ARRAY
2148 (pRoamInfo->bssid.bytes),
2149 roamResult, roamStatus);
2150
2151 /* inform connect result to nl80211 */
2152 cfg80211_connect_result(dev,
2153 pRoamInfo->
2154 bssid.bytes,
2155 reqRsnIe,
2156 reqRsnLength,
2157 rspRsnIe,
2158 rspRsnLength,
2159 WLAN_STATUS_SUCCESS,
2160 GFP_KERNEL);
2161 }
2162 }
2163 }
2164 if (!hddDisconInProgress) {
2165 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002166 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002167 bss);
2168
2169 /*
2170 * Perform any WMM-related association
2171 * processing.
2172 */
2173 hdd_wmm_assoc(pAdapter, pRoamInfo,
2174 eCSR_BSS_TYPE_INFRASTRUCTURE);
2175
2176 /*
2177 * Start the Queue - Start tx queues before
2178 * hdd_roam_register_sta, since
2179 * hdd_roam_register_sta will flush any cached
2180 * data frames immediately.
2181 */
2182 hddLog(LOG1, FL("Enabling queues"));
2183 wlan_hdd_netif_queue_control(pAdapter,
2184 WLAN_WAKE_ALL_NETIF_QUEUE,
2185 WLAN_CONTROL_PATH);
2186
2187 /*
2188 * Register the Station with TL after associated
2189 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302190 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002191 pRoamInfo,
2192 pHddStaCtx->
2193 conn_info.
2194 staId[0],
2195 NULL,
2196 pRoamInfo->
2197 pBssDesc);
2198 }
2199 } else {
2200 /*
2201 * wpa supplicant expecting WPA/RSN IE in connect result
2202 * in case of reassociation also need to indicate it to
2203 * supplicant.
2204 */
2205 csr_roam_get_wpa_rsn_req_ie(
2206 WLAN_HDD_GET_HAL_CTX(pAdapter),
2207 pAdapter->sessionId,
2208 &reqRsnLength, reqRsnIe);
2209
2210 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2211 reqRsnIe, reqRsnLength);
2212 /* Reassoc successfully */
2213 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302214 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002215 hdd_change_peer_state(pAdapter,
2216 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002217 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002218#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2219 pRoamInfo->roamSynchInProgress
2220#else
2221 false
2222#endif
2223 );
2224 hdd_conn_set_authenticated(pAdapter, false);
2225 } else {
2226 hddLog(LOG2,
2227 FL("staId: %d Changing TL state to AUTHENTICATED"),
2228 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302229 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002230 hdd_change_peer_state(pAdapter,
2231 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002232 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002233#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2234 pRoamInfo->roamSynchInProgress
2235#else
2236 false
2237#endif
2238 );
2239 hdd_conn_set_authenticated(pAdapter, true);
2240 }
2241
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302242 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002243 /*
2244 * Perform any WMM-related association
2245 * processing
2246 */
2247 hdd_wmm_assoc(pAdapter, pRoamInfo,
2248 eCSR_BSS_TYPE_INFRASTRUCTURE);
2249 }
2250
2251 /* Start the tx queues */
2252#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2253 if (pRoamInfo->roamSynchInProgress)
2254 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2255#endif
2256 hddLog(LOG1, FL("Enabling queues"));
2257 wlan_hdd_netif_queue_control(pAdapter,
2258 WLAN_WAKE_ALL_NETIF_QUEUE,
2259 WLAN_CONTROL_PATH);
2260 }
2261
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302262 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002263 hddLog(LOGE,
2264 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302265 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002266 }
2267#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302268 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002269 sizeof(pAdapter->hdd_stats.hddPmfStats));
2270#endif
2271 } else {
2272 hdd_wext_state_t *pWextState =
2273 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2274 if (pRoamInfo)
2275 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302276 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002277 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2278 roamResult, roamStatus);
2279 else
2280 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302281 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002282 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2283 roamResult, roamStatus);
2284
2285 /*
2286 * CR465478: Only send up a connection failure result when CSR
2287 * has completed operation - with a ASSOCIATION_FAILURE status.
2288 */
2289 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2290 && !hddDisconInProgress) {
2291 if (pRoamInfo)
2292 hddLog(LOGE,
2293 FL("send connect failure to nl80211: for bssid "
2294 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302295 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002296 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302297 roamResult, roamStatus,
2298 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002299 else
2300 hddLog(LOGE,
2301 FL("connect failed: for bssid "
2302 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302303 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2305 roamResult, roamStatus);
2306
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002307 /* inform association failure event to nl80211 */
2308 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2309 roamResult) {
2310 if (pRoamInfo)
2311 cfg80211_connect_result(dev,
2312 pRoamInfo->bssid.bytes,
2313 NULL, 0, NULL, 0,
2314 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2315 GFP_KERNEL);
2316 else
2317 cfg80211_connect_result(dev,
2318 pWextState->req_bssId.bytes,
2319 NULL, 0, NULL, 0,
2320 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2321 GFP_KERNEL);
2322 } else {
2323 if (pRoamInfo) {
2324 eCsrAuthType authType =
2325 pWextState->roamProfile.AuthType.
2326 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302327 eCsrEncryptionType encryption_type =
2328 pWextState->roamProfile.
2329 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002330 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302331 (((authType ==
2332 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302334 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2335 ((encryption_type ==
2336 eCSR_ENCRYPT_TYPE_WEP40) ||
2337 (encryption_type ==
2338 eCSR_ENCRYPT_TYPE_WEP104) ||
2339 (encryption_type ==
2340 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2341 (encryption_type ==
2342 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002343 /*
2344 * In case of OPEN-WEP or SHARED-WEP
2345 * authentication, send exact protocol
2346 * reason code. This enables user
2347 * applications to reconnect the station
2348 * with correct configuration.
2349 */
2350 cfg80211_connect_result(dev,
2351 pRoamInfo->bssid.bytes, NULL, 0,
2352 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302353 (isWep &&
2354 pRoamInfo->reasonCode) ?
2355 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002356 WLAN_STATUS_UNSPECIFIED_FAILURE,
2357 GFP_KERNEL);
2358 } else
2359 cfg80211_connect_result(dev,
2360 pWextState->req_bssId.bytes,
2361 NULL, 0, NULL, 0,
2362 WLAN_STATUS_UNSPECIFIED_FAILURE,
2363 GFP_KERNEL);
2364 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302365 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002366 }
2367
2368 if (pRoamInfo) {
2369 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2370 pRoamInfo->statusCode)
2371 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2372 pRoamInfo->statusCode)
2373 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2374 pRoamInfo->statusCode)) {
2375 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2376 pRoamInfo);
2377 }
2378 }
2379
2380 /*
2381 * Set connection state to eConnectionState_NotConnected only
2382 * when CSR has completed operation - with a
2383 * ASSOCIATION_FAILURE status.
2384 */
2385 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2386 && !hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002387 hdd_conn_set_connection_state(pAdapter,
2388 eConnectionState_NotConnected);
2389 }
2390 hdd_wmm_init(pAdapter);
2391
2392 hddLog(LOG1, FL("Disabling queues"));
2393 wlan_hdd_netif_queue_control(pAdapter,
2394 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2395 WLAN_CONTROL_PATH);
2396 }
2397
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302398 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002399 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302400 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002401
Govind Singh24db1ed2015-12-18 15:54:59 +05302402 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2403 cds_force_sap_on_scc(roamResult,
2404 pRoamInfo->pBssDesc->channelId);
2405 } else {
2406 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302407 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302408 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002409
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302410 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002411}
2412
2413/**
2414 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2415 * @pAdapter: pointer to adapter
2416 * @pRoamInfo: pointer to roam info
2417 * @roamId: roam id
2418 * @roamStatus: roam status
2419 * @roamResult: roam result
2420 *
2421 * Here we update the status of the Ibss when we receive information that we
2422 * have started/joined an ibss session.
2423 *
2424 * Return: none
2425 */
2426static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2427 tCsrRoamInfo *pRoamInfo,
2428 uint32_t roamId,
2429 eRoamCmdStatus roamStatus,
2430 eCsrRoamResult roamResult)
2431{
2432 hddLog(LOG1, "%s: id %d, status %d, result %d",
2433 pAdapter->dev->name, roamId, roamStatus, roamResult);
2434
2435 switch (roamResult) {
2436 /* both IBSS Started and IBSS Join should come in here. */
2437 case eCSR_ROAM_RESULT_IBSS_STARTED:
2438 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2439 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2440 {
2441 hdd_context_t *pHddCtx =
2442 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302443 hdd_station_ctx_t *hdd_sta_ctx =
2444 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302445 struct qdf_mac_addr broadcastMacAddr =
2446 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002447
2448 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302449 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002450 return;
2451 }
2452
2453 /* When IBSS Started comes from CSR, we need to move
2454 * connection state to IBSS Disconnected (meaning no peers
2455 * are in the IBSS).
2456 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002457 hdd_conn_set_connection_state(pAdapter,
2458 eConnectionState_IbssDisconnected);
2459 /* notify wmm */
2460 hdd_wmm_connect(pAdapter, pRoamInfo,
2461 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302462
2463 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2464
2465 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002466 pAdapter;
2467 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302468 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002469 &broadcastMacAddr,
2470 pRoamInfo->pBssDesc);
2471
2472 if (pRoamInfo->pBssDesc) {
2473 struct cfg80211_bss *bss;
2474#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2475 struct ieee80211_channel *chan;
2476 int chan_no;
2477 unsigned int freq;
2478#endif
2479 /* we created the IBSS, notify supplicant */
2480 hddLog(LOG1,
2481 FL("%s: created ibss " MAC_ADDRESS_STR),
2482 pAdapter->dev->name,
2483 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2484
2485 /* we must first give cfg80211 the BSS information */
2486 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2487 pRoamInfo);
2488 if (NULL == bss) {
2489 hddLog(LOGE,
2490 FL("%s: unable to create IBSS entry"),
2491 pAdapter->dev->name);
2492 return;
2493 }
2494 hddLog(LOG1, FL("Enabling queues"));
2495 wlan_hdd_netif_queue_control(pAdapter,
2496 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2497 WLAN_CONTROL_PATH);
2498
2499#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2500 chan_no = pRoamInfo->pBssDesc->channelId;
2501
2502 if (chan_no <= 14)
2503 freq = ieee80211_channel_to_frequency(chan_no,
2504 IEEE80211_BAND_2GHZ);
2505 else
2506 freq = ieee80211_channel_to_frequency(chan_no,
2507 IEEE80211_BAND_5GHZ);
2508
2509 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2510
2511 if (chan)
2512 cfg80211_ibss_joined(pAdapter->dev,
2513 bss->bssid, chan,
2514 GFP_KERNEL);
2515 else
2516 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2517 pAdapter->dev->name,
2518 (int)pRoamInfo->pBssDesc->channelId);
2519#else
2520 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2521 GFP_KERNEL);
2522#endif
2523 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002524 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002525 bss);
2526 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002527 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002528 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002529 pAdapter->sessionId);
2530 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2531 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002532 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002533 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534 break;
2535 }
2536
2537 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2538 {
2539 hddLog(LOGE,
2540 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2541 break;
2542 }
2543
2544 default:
2545 hddLog(LOGE, FL("%s: unexpected result %d"),
2546 pAdapter->dev->name, (int)roamResult);
2547 break;
2548 }
2549
2550 return;
2551}
2552
2553/**
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002554 * hdd_save_peer() - Save peer MAC address in adapter peer table.
2555 * @sta_ctx: pointer to hdd station context
2556 * @sta_id: station ID
2557 * @peer_mac_addr: mac address of new peer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002558 *
2559 * This information is passed to iwconfig later. The peer that joined
2560 * last is passed as information to iwconfig.
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002561
2562 * Return: true if success, false otherwise
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002563 */
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002564bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id,
2565 struct qdf_mac_addr *peer_mac_addr)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002566{
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002567 int idx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002569 for (idx = 0; idx < SIR_MAX_NUM_STA_IN_IBSS; idx++) {
2570 if (0 == sta_ctx->conn_info.staId[idx]) {
Naveen Rawatf28315c2016-06-29 18:06:02 -07002571 hddLog(LOG1, FL("adding peer: %pM, sta_id: %d, at idx: %d"),
2572 peer_mac_addr, sta_id, idx);
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002573 sta_ctx->conn_info.staId[idx] = sta_id;
2574 qdf_copy_macaddr(
2575 &sta_ctx->conn_info.peerMacAddress[idx],
2576 peer_mac_addr);
2577 return true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002578 }
2579 }
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002580 return false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002581}
2582
2583/**
2584 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2585 * @pAdapter: pointer to adapter
2586 * @staId: station id
2587 *
2588 * Return:
2589 * true if we remove MAX_IBSS_PEERS or less STA
2590 * false otherwise.
2591 */
2592static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2593{
2594 bool fSuccess = false;
2595 int idx = 0;
2596 uint8_t valid_idx = 0;
2597 uint8_t del_idx = 0;
2598 uint8_t empty_slots = 0;
2599 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2600
2601 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2602 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2603 pHddStaCtx->conn_info.staId[idx] = 0;
2604
Anurag Chouhanc5548422016-02-24 18:33:27 +05302605 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002606 peerMacAddress[idx]);
2607
2608 fSuccess = true;
2609
2610 /*
2611 * Note the deleted Index, if its 0 we need special
2612 * handling.
2613 */
2614 del_idx = idx;
2615
2616 empty_slots++;
2617 } else {
2618 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2619 valid_idx = idx;
2620 } else {
2621 /* Found an empty slot */
2622 empty_slots++;
2623 }
2624 }
2625 }
2626
2627 if (MAX_IBSS_PEERS == empty_slots) {
2628 /* Last peer departed, set the IBSS state appropriately */
2629 pHddStaCtx->conn_info.connState =
2630 eConnectionState_IbssDisconnected;
2631 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2632 }
2633 /* Find next active staId, to have a valid sta trigger for TL. */
2634 if (fSuccess == true) {
2635 if (del_idx == 0) {
2636 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2637 pHddStaCtx->conn_info.staId[0] =
2638 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302639 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002640 peerMacAddress[0],
2641 &pHddStaCtx->conn_info.
2642 peerMacAddress[valid_idx]);
2643
2644 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302645 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002646 peerMacAddress[valid_idx]);
2647 }
2648 }
2649 }
2650 return fSuccess;
2651}
2652
2653/**
2654 * roam_ibss_connect_handler() - IBSS connection handler
2655 * @pAdapter: pointer to adapter
2656 * @pRoamInfo: pointer to roam info
2657 *
2658 * We update the status of the IBSS to connected in this function.
2659 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302660 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002661 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302662static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002663 tCsrRoamInfo *pRoamInfo)
2664{
2665 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002666 /*
2667 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2668 * a partner stations).
2669 */
2670 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2671
2672 /* Save the connection info from CSR... */
2673 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2674
2675 /* Send the bssid address to the wext. */
2676 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2677 /* add bss_id to cfg80211 data base */
2678 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2679 if (NULL == bss) {
2680 hddLog(LOGE,
2681 FL("%s: unable to create IBSS entry"),
2682 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302683 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002684 }
2685 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002686 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002687 bss);
2688
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302689 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002690}
2691
2692/**
2693 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2694 * @pAdapter: pointer to adapter
2695 * @pRoamInfo: pointer to roam info
2696 * @roamId: roam id
2697 * @roamStatus: roam status
2698 * @roamResult: roam result
2699 *
2700 * This function indicates the Mic failure to the supplicant
2701 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302702 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002703 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302704static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002705hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2706 tCsrRoamInfo *pRoamInfo,
2707 uint32_t roamId,
2708 eRoamCmdStatus roamStatus,
2709 eCsrRoamResult roamResult)
2710{
2711 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2712
2713 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2714 TKIP_COUNTER_MEASURE_STOPED ==
2715 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2716 struct iw_michaelmicfailure msg;
2717 union iwreq_data wreq;
2718 memset(&msg, '\0', sizeof(msg));
2719 msg.src_addr.sa_family = ARPHRD_ETHER;
2720 memcpy(msg.src_addr.sa_data,
2721 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2722 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2723 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2724 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2725
2726 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2727 msg.flags = IW_MICFAILURE_GROUP;
2728 else
2729 msg.flags = IW_MICFAILURE_PAIRWISE;
2730 memset(&wreq, 0, sizeof(wreq));
2731 wreq.data.length = sizeof(msg);
2732 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2733 (char *)&msg);
2734 /* inform mic failure to nl80211 */
2735 cfg80211_michael_mic_failure(pAdapter->dev,
2736 pRoamInfo->u.pMICFailureInfo->
2737 taMacAddr,
2738 ((pRoamInfo->u.pMICFailureInfo->
2739 multicast ==
2740 eSIR_TRUE) ?
2741 NL80211_KEYTYPE_GROUP :
2742 NL80211_KEYTYPE_PAIRWISE),
2743 pRoamInfo->u.pMICFailureInfo->
2744 keyId,
2745 pRoamInfo->u.pMICFailureInfo->TSC,
2746 GFP_KERNEL);
2747
2748 }
2749
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302750 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002751}
2752
2753/**
2754 * roam_roam_connect_status_update_handler() - IBSS connect status update
2755 * @pAdapter: pointer to adapter
2756 * @pRoamInfo: pointer to roam info
2757 * @roamId: roam id
2758 * @roamStatus: roam status
2759 * @roamResult: roam result
2760 *
2761 * The Ibss connection status is updated regularly here in this function.
2762 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302763 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002764 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302765static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002766roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2767 tCsrRoamInfo *pRoamInfo,
2768 uint32_t roamId,
2769 eRoamCmdStatus roamStatus,
2770 eCsrRoamResult roamResult)
2771{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302772 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773
2774 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2775 switch (roamResult) {
2776 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2777 {
2778 hdd_station_ctx_t *pHddStaCtx =
2779 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2780 struct station_info staInfo;
2781
2782 pr_info("IBSS New Peer indication from SME "
2783 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2784 MAC_ADDRESS_STR " and stationID= %d",
2785 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2786 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2787 pRoamInfo->staId);
2788
Deepak Dhamdhere0f076bd2016-06-02 11:29:21 -07002789 if (!hdd_save_peer
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002790 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2791 pRoamInfo->staId,
2792 &pRoamInfo->peerMac)) {
2793 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2794 break;
2795 }
2796
2797 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2798
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002799 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302800 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002801 pRoamInfo,
2802 pRoamInfo->staId,
2803 &pRoamInfo->peerMac,
2804 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302805 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002806 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302807 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2808 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002809 }
2810 pHddStaCtx->ibss_sta_generation++;
2811 memset(&staInfo, 0, sizeof(staInfo));
2812 staInfo.filled = 0;
2813 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2814
2815 cfg80211_new_sta(pAdapter->dev,
2816 (const u8 *)pRoamInfo->peerMac.bytes,
2817 &staInfo, GFP_KERNEL);
2818
2819 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2820 pHddStaCtx->ibss_enc_key.encType
2821 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2822 pHddStaCtx->ibss_enc_key.encType
2823 || eCSR_ENCRYPT_TYPE_TKIP ==
2824 pHddStaCtx->ibss_enc_key.encType
2825 || eCSR_ENCRYPT_TYPE_AES ==
2826 pHddStaCtx->ibss_enc_key.encType) {
2827 pHddStaCtx->ibss_enc_key.keyDirection =
2828 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302829 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002830 &pRoamInfo->peerMac);
2831
2832 hddLog(LOG2, "New peer joined set PTK encType=%d",
2833 pHddStaCtx->ibss_enc_key.encType);
2834
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302835 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002836 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2837 (pAdapter),
2838 pAdapter->sessionId,
2839 &pHddStaCtx->ibss_enc_key,
2840 &roamId);
2841
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302842 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002843 hddLog(LOGE,
2844 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302845 qdf_status);
2846 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002847 }
2848 }
2849 hddLog(LOG1, FL("Enabling queues"));
2850 wlan_hdd_netif_queue_control(pAdapter,
2851 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2852 WLAN_CONTROL_PATH);
2853 break;
2854 }
2855
2856 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2857 {
2858
2859 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2860
2861 break;
2862 }
2863 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2864 {
2865 hdd_station_ctx_t *pHddStaCtx =
2866 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2867
2868 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2869 hddLog(LOGW,
2870 "IBSS peer departed by cannot find peer in our registration table with TL");
2871
2872 pr_info("IBSS Peer Departed from SME "
2873 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2874 MAC_ADDRESS_STR " and stationID= %d",
2875 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2876 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2877 pRoamInfo->staId);
2878
2879 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2880
2881 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2882 pHddStaCtx->ibss_sta_generation++;
2883
2884 cfg80211_del_sta(pAdapter->dev,
2885 (const u8 *)&pRoamInfo->peerMac.bytes,
2886 GFP_KERNEL);
2887 break;
2888 }
2889 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2890 {
2891 hddLog(LOG3,
2892 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2893 /* Stop only when we are inactive */
2894 hddLog(LOG1, FL("Disabling queues"));
2895 wlan_hdd_netif_queue_control(pAdapter,
2896 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2897 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002898 hdd_conn_set_connection_state(pAdapter,
2899 eConnectionState_NotConnected);
2900
2901 /* Send the bssid address to the wext. */
2902 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2903 break;
2904 }
2905 default:
2906 break;
2907
2908 }
2909
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302910 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911}
2912
2913#ifdef FEATURE_WLAN_TDLS
2914/**
2915 * hdd_roam_register_tdlssta() - register new TDLS station
2916 * @pAdapter: pointer to adapter
2917 * @peerMac: pointer to peer MAC address
2918 * @staId: station identifier
2919 * @ucastSig: unicast signature
2920 *
2921 * Construct the staDesc and register with TL the new STA.
2922 * This is called as part of ADD_STA in the TDLS setup.
2923 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302924 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002925 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302926QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002927 const uint8_t *peerMac, uint16_t staId,
2928 uint8_t ucastSig)
2929{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302930 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002931 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002932 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002933
2934 /*
2935 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2936 * be peer MAC, here we are working on direct Link
2937 */
2938 staDesc.sta_id = staId;
2939
2940 /* set the QoS field appropriately .. */
2941 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2942 : (staDesc.is_qos_enabled = 0);
2943
Dhanashri Atre50141c52016-04-07 13:15:29 -07002944 /* Register the vdev transmit and receive functions */
2945 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2946 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2947 ol_txrx_vdev_register(
2948 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2949 pAdapter, &txrx_ops);
2950 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002951
2952 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002953 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302954 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002955 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302956 qdf_status, qdf_status);
2957 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002958 }
2959
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302960 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002961}
2962
2963/**
2964 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2965 * @pAdapter: pointer to adapter
2966 * @staId: station identifier
2967 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302968 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002969 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302970static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002971 uint8_t staId)
2972{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302973 QDF_STATUS qdf_status;
2974 qdf_status = ol_txrx_clear_peer(staId);
2975 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002976 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302977 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002978 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302979 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002980}
2981
2982/**
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07002983 * hdd_tdls_connection_tracker_update() - update connection tracker state
2984 * @adapter: pointer to adapter
2985 * @roam_info: pointer to roam info
2986 * @hdd_tdls_ctx: tdls context
2987 *
2988 * Return: QDF_STATUS enumeration
2989 */
2990static QDF_STATUS hdd_tdls_connection_tracker_update(hdd_adapter_t *adapter,
2991 tCsrRoamInfo *roam_info,
2992 tdlsCtx_t *hdd_tdls_ctx)
2993{
2994 hddTdlsPeer_t *curr_peer;
2995 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
2996
2997 curr_peer = wlan_hdd_tdls_find_peer(adapter,
2998 roam_info->peerMac.bytes, true);
2999
3000 if (!curr_peer) {
3001 hdd_err("curr_peer is null");
3002 return QDF_STATUS_E_FAILURE;
3003 }
3004
3005 mutex_lock(&hdd_ctx->tdls_lock);
3006
3007 if (eTDLS_LINK_CONNECTED ==
3008 curr_peer->link_status) {
3009 hdd_err("Received CONNECTION_TRACKER_NOTIFICATION "
3010 MAC_ADDRESS_STR
3011 " staId: %d, reason: %d",
3012 MAC_ADDR_ARRAY(roam_info->peerMac.bytes),
3013 roam_info->staId,
3014 roam_info->reasonCode);
3015
3016 if (roam_info->reasonCode ==
3017 eWNI_TDLS_PEER_ENTER_BUF_STA ||
3018 roam_info->reasonCode ==
3019 eWNI_TDLS_ENTER_BT_BUSY_MODE)
3020 hdd_ctx->enable_tdls_connection_tracker = true;
3021 else if (roam_info->reasonCode ==
3022 eWNI_TDLS_PEER_EXIT_BUF_STA ||
3023 roam_info->reasonCode ==
3024 eWNI_TDLS_EXIT_BT_BUSY_MODE)
3025 hdd_ctx->enable_tdls_connection_tracker = false;
3026
3027 } else {
3028 hdd_err("TDLS not connected, ignore notification, reason: %d",
3029 roam_info->reasonCode);
3030 }
3031
3032 mutex_unlock(&hdd_ctx->tdls_lock);
3033
3034 return QDF_STATUS_SUCCESS;
3035}
3036
3037
3038
3039
3040/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003041 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
3042 * @pAdapter: pointer to adapter
3043 * @pRoamInfo: pointer to roam info
3044 * @roamId: roam id
3045 * @roamStatus: roam status
3046 * @roamResult: roam result
3047 *
3048 * HDD interface between SME and TL to ensure TDLS client registration with
3049 * TL in case of new TDLS client is added and deregistration at the time
3050 * TDLS client is deleted.
3051 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303052 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003053 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303054static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003055hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
3056 tCsrRoamInfo *pRoamInfo,
3057 uint32_t roamId,
3058 eRoamCmdStatus roamStatus,
3059 eCsrRoamResult roamResult)
3060{
3061 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3062 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
3063 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303064 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003065 uint8_t staIdx;
3066 hddTdlsPeer_t *curr_peer;
3067 uint32_t reason;
3068
3069 hddLog(LOG2,
3070 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
3071 roamResult ==
3072 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
3073 ==
3074 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
3075 roamResult ==
3076 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
3077 : roamResult ==
3078 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
3079 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
3080 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
3081 roamResult ==
3082 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
3083 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
3084 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
3085 : roamResult ==
3086 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
3087 : roamResult ==
3088 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
3089 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
3090 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
3091
3092 if (!pHddTdlsCtx) {
3093 hddLog(LOG1,
3094 FL("TDLS ctx is null, ignore roamResult (%d)"),
3095 roamResult);
3096 return status;
3097 }
3098
3099 switch (roamResult) {
3100 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
3101 {
3102 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3103 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
3104 pRoamInfo->statusCode);
3105 } else {
3106 /*
3107 * Check if there is available index for this new TDLS
3108 * STA.
3109 */
3110 for (staIdx = 0;
3111 staIdx < pHddCtx->max_num_tdls_sta;
3112 staIdx++) {
3113 if (0 ==
3114 pHddCtx->tdlsConnInfo[staIdx].
3115 staId) {
3116 pHddCtx->tdlsConnInfo[staIdx].
3117 sessionId =
3118 pRoamInfo->sessionId;
3119 pHddCtx->tdlsConnInfo[staIdx].
3120 staId = pRoamInfo->staId;
3121
3122 hddLog(LOGW,
3123 ("TDLS: STA IDX at %d is %d "
3124 "of mac "
3125 MAC_ADDRESS_STR),
3126 staIdx,
3127 pHddCtx->
3128 tdlsConnInfo[staIdx].
3129 staId,
3130 MAC_ADDR_ARRAY
3131 (pRoamInfo->peerMac.bytes));
3132
Anurag Chouhanc5548422016-02-24 18:33:27 +05303133 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003134 tdlsConnInfo
3135 [staIdx].
3136 peerMac,
3137 &pRoamInfo->
3138 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303139 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003140 break;
3141 }
3142 }
3143 if (staIdx < pHddCtx->max_num_tdls_sta) {
3144 if (-1 ==
3145 wlan_hdd_tdls_set_sta_id(pAdapter,
3146 pRoamInfo->
3147 peerMac.bytes,
3148 pRoamInfo->
3149 staId)) {
3150 hddLog(LOGE,
3151 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303152 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003153 }
3154
3155 (WLAN_HDD_GET_CTX(pAdapter))->
3156 sta_to_adapter[pRoamInfo->staId] =
3157 pAdapter;
3158 /*
3159 * store the ucast signature,
3160 * if required for further reference.
3161 */
3162
3163 wlan_hdd_tdls_set_signature(pAdapter,
3164 pRoamInfo->
3165 peerMac.bytes,
3166 pRoamInfo->
3167 ucastSig);
3168 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303169 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003170 hddLog(LOGE,
3171 FL("no available slot in conn_info. staId %d cannot be stored"),
3172 pRoamInfo->staId);
3173 }
3174 pAdapter->tdlsAddStaStatus = status;
3175 }
3176 complete(&pAdapter->tdls_add_station_comp);
3177 break;
3178 }
3179 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3180 {
3181 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3182 hddLog(LOGE,
3183 FL("Add Sta failed. status code(=%d)"),
3184 pRoamInfo->statusCode);
3185 }
3186 /* store the ucast signature which will be used later when
3187 * registering to TL
3188 */
3189 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3190 complete(&pAdapter->tdls_add_station_comp);
3191 break;
3192 }
3193 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3194 {
3195 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3196 hddLog(LOGE,
3197 FL("Link Establish Request failed. status(=%d)"),
3198 pRoamInfo->statusCode);
3199 }
3200 complete(&pAdapter->tdls_link_establish_req_comp);
3201 break;
3202 }
3203 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3204 {
3205 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3206 staIdx++) {
3207 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3208 pRoamInfo->sessionId)
3209 && pRoamInfo->staId ==
3210 pHddCtx->tdlsConnInfo[staIdx].staId) {
3211 hddLog(LOGW,
3212 ("HDD: del STA IDX = %x"),
3213 pRoamInfo->staId);
3214
3215 curr_peer =
3216 wlan_hdd_tdls_find_peer(pAdapter,
3217 pRoamInfo->
3218 peerMac.bytes,
3219 true);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303220 if (NULL != curr_peer) {
3221 hdd_info("Current status for peer " MAC_ADDRESS_STR " is %d",
3222 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3223 curr_peer->link_status);
3224 if (TDLS_IS_CONNECTED(curr_peer)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225 hdd_roam_deregister_tdlssta
3226 (pAdapter,
3227 pRoamInfo->staId);
3228 wlan_hdd_tdls_decrement_peer_count
3229 (pAdapter);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303230 } else if (eTDLS_LINK_CONNECTING ==
3231 curr_peer->link_status) {
3232 hdd_roam_deregister_tdlssta
3233 (pAdapter,
3234 pRoamInfo->staId);
3235 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003236 }
3237 wlan_hdd_tdls_reset_peer(pAdapter,
3238 pRoamInfo->
3239 peerMac.bytes);
3240
3241 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3242 pHddCtx->tdlsConnInfo[staIdx].
3243 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303244 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003245 tdlsConnInfo[staIdx].
3246 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303247 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303248 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003249 break;
3250 }
3251 }
3252 complete(&pAdapter->tdls_del_station_comp);
3253 }
3254 break;
3255 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3256 {
3257 hddLog(LOGE,
3258 FL("Sending teardown to supplicant with reason code %u"),
3259 pRoamInfo->reasonCode);
3260
3261 curr_peer =
3262 wlan_hdd_tdls_find_peer(pAdapter,
3263 pRoamInfo->peerMac.bytes, true);
3264 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3265 pRoamInfo->reasonCode);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303266 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
3267 curr_peer->peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303268 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003269 break;
3270 }
3271 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3272 {
3273 /* 0 staIdx is assigned to AP we dont want to touch that */
3274 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3275 staIdx++) {
3276 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3277 pRoamInfo->sessionId)
3278 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3279 hddLog(LOGW,
3280 ("hdd_tdlsStatusUpdate: staIdx %d "
3281 MAC_ADDRESS_STR),
3282 pHddCtx->tdlsConnInfo[staIdx].
3283 staId,
3284 MAC_ADDR_ARRAY(pHddCtx->
3285 tdlsConnInfo
3286 [staIdx].
3287 peerMac.
3288 bytes));
3289 wlan_hdd_tdls_reset_peer(pAdapter,
3290 pHddCtx->
3291 tdlsConnInfo
3292 [staIdx].
3293 peerMac.bytes);
3294 hdd_roam_deregister_tdlssta(pAdapter,
3295 pHddCtx->
3296 tdlsConnInfo
3297 [staIdx].
3298 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303299 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003300 sizeof
3301 (smeTdlsPeerStateParams));
3302 smeTdlsPeerStateParams.vdevId =
3303 pHddCtx->tdlsConnInfo[staIdx].
3304 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303305 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003306 peerMacAddr,
3307 &pHddCtx->
3308 tdlsConnInfo[staIdx].
3309 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303310 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003311 smeTdlsPeerStateParams.peerState =
3312 eSME_TDLS_PEER_STATE_TEARDOWN;
3313
3314 hddLog(LOG1,
3315 FL("calling sme_update_tdls_peer_state for staIdx %d "
3316 MAC_ADDRESS_STR),
3317 pHddCtx->tdlsConnInfo[staIdx].
3318 staId,
3319 MAC_ADDR_ARRAY(pHddCtx->
3320 tdlsConnInfo
3321 [staIdx].
3322 peerMac.
3323 bytes));
3324 status =
3325 sme_update_tdls_peer_state(
3326 pHddCtx->hHal,
3327 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303328 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003329 hddLog(LOGE,
3330 FL("sme_update_tdls_peer_state failed for "
3331 MAC_ADDRESS_STR),
3332 MAC_ADDR_ARRAY
3333 (pHddCtx->
3334 tdlsConnInfo[staIdx].
3335 peerMac.bytes));
3336 }
3337 wlan_hdd_tdls_decrement_peer_count
3338 (pAdapter);
3339
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303340 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003341 tdlsConnInfo[staIdx].
3342 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303343 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003344 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3345 pHddCtx->tdlsConnInfo[staIdx].
3346 sessionId = 255;
3347
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303348 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003349 }
3350 }
3351 break;
3352 }
3353 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3354 {
3355 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303356 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3357 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003358 hddLog(LOG2,
3359 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3360 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303361 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303362 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003363 break;
3364 }
3365
Archana Ramachandran7ba24ff2016-04-26 12:29:04 -07003366 if (pHddCtx->tdls_nss_switch_in_progress) {
3367 hdd_err("TDLS antenna switch is in progress, ignore SHOULD_DISCOVER");
3368 status = QDF_STATUS_SUCCESS;
3369 break;
3370 }
3371
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003372 curr_peer =
3373 wlan_hdd_tdls_get_peer(pAdapter,
Kabilan Kannan36090ce2016-05-03 19:28:44 -07003374 pRoamInfo->peerMac.bytes,
3375 true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003376 if (!curr_peer) {
3377 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303378 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003379 } else {
3380 if (eTDLS_LINK_CONNECTED ==
3381 curr_peer->link_status) {
3382 hddLog(LOGE,
3383 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3384 } else {
3385 /*
3386 * If external control is enabled then initiate
3387 * TDLS only if forced peer is set otherwise
3388 * ignore should Discover trigger from fw.
3389 */
3390 if (pHddCtx->config->
3391 fTDLSExternalControl
3392 && (false ==
3393 curr_peer->isForcedPeer)) {
3394 hddLog(LOG2,
3395 FL
3396 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303397 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003398 break;
3399 } else {
3400 hddLog(LOG2,
3401 FL
3402 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3403 pHddCtx->config->
3404 fTDLSExternalControl,
3405 curr_peer->isForcedPeer,
3406 pRoamInfo->reasonCode);
3407 }
3408 wlan_hdd_tdls_pre_setup_init_work
3409 (pHddTdlsCtx, curr_peer);
3410 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303411 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003412 }
3413 break;
3414 }
3415
3416 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3417 {
3418 curr_peer =
3419 wlan_hdd_tdls_find_peer(pAdapter,
3420 pRoamInfo->peerMac.bytes, true);
3421 if (!curr_peer) {
3422 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303423 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003424 } else {
3425 if (eTDLS_LINK_CONNECTED ==
3426 curr_peer->link_status) {
3427 hddLog(LOGE,
3428 FL
3429 ("Received SHOULD_TEARDOWN for peer "
3430 MAC_ADDRESS_STR
3431 " staId: %d, reason: %d"),
3432 MAC_ADDR_ARRAY(pRoamInfo->
3433 peerMac.bytes),
3434 pRoamInfo->staId,
3435 pRoamInfo->reasonCode);
3436
3437 if (pRoamInfo->reasonCode ==
3438 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3439 pRoamInfo->reasonCode ==
3440 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3441 pRoamInfo->reasonCode ==
3442 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3443 pRoamInfo->reasonCode ==
3444 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3445 reason =
3446 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3447 } else
3448 reason =
3449 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3450
3451 wlan_hdd_tdls_indicate_teardown
3452 (pHddTdlsCtx->pAdapter, curr_peer,
3453 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303454 hdd_send_wlan_tdls_teardown_event(
3455 eTDLS_TEARDOWN_BSS_DISCONNECT,
3456 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003457 } else {
3458 hddLog(LOGE,
3459 FL
3460 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3461 pRoamInfo->reasonCode);
3462 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303463 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003464 }
3465 break;
3466 }
3467
3468 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3469 {
3470 curr_peer =
3471 wlan_hdd_tdls_find_peer(pAdapter,
3472 pRoamInfo->peerMac.bytes, true);
3473 if (!curr_peer) {
3474 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303475 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003476 } else {
3477 if (eTDLS_LINK_CONNECTED ==
3478 curr_peer->link_status) {
3479 hddLog(LOGE,
3480 FL
3481 ("Received SHOULD_PEER_DISCONNECTED for peer "
3482 MAC_ADDRESS_STR
3483 " staId: %d, reason: %d"),
3484 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3485 pRoamInfo->staId,
3486 pRoamInfo->reasonCode);
3487
3488 if (pRoamInfo->reasonCode ==
3489 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3490 pRoamInfo->reasonCode ==
3491 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3492 pRoamInfo->reasonCode ==
3493 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3494 pRoamInfo->reasonCode ==
3495 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3496 reason =
3497 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3498 } else
3499 reason =
3500 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3501
3502 wlan_hdd_tdls_indicate_teardown
3503 (pHddTdlsCtx->pAdapter, curr_peer,
3504 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303505 hdd_send_wlan_tdls_teardown_event(
3506 eTDLS_TEARDOWN_BSS_DISCONNECT,
3507 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003508 } else {
3509 hddLog(LOGE,
3510 FL
3511 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3512 pRoamInfo->reasonCode);
3513 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303514 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003515 }
3516 break;
3517 }
Kabilan Kannan14ec97f2016-05-16 23:48:25 -07003518
3519 case eCSR_ROAM_RESULT_TDLS_CONNECTION_TRACKER_NOTIFICATION:
3520 status = hdd_tdls_connection_tracker_update(pAdapter,
3521 pRoamInfo,
3522 pHddTdlsCtx);
3523 break;
3524
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003525 default:
3526 {
3527 break;
3528 }
3529 }
3530
3531 return status;
3532}
3533#endif
3534
3535#ifdef WLAN_FEATURE_11W
3536/**
3537 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3538 * @pAdapter: pointer to the adapter
3539 * @nFrameLength: Length of the unprotected frame being passed
3540 * @pbFrames: Pointer to the frame buffer
3541 * @frameType: 802.11 frame type
3542 *
3543 * This function forwards the unprotected management frame to the supplicant.
3544 *
3545 * Return: nothing
3546 */
3547static void
3548hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3549 uint8_t *pbFrames, uint8_t frameType)
3550{
3551 uint8_t type = 0;
3552 uint8_t subType = 0;
3553
3554 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3555 frameType, nFrameLength);
3556
3557 /* Sanity Checks */
3558 if (NULL == pAdapter) {
3559 hddLog(LOGE, FL("pAdapter is NULL"));
3560 return;
3561 }
3562
3563 if (NULL == pAdapter->dev) {
3564 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3565 return;
3566 }
3567
3568 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3569 hddLog(LOGE, FL("pAdapter has invalid magic"));
3570 return;
3571 }
3572
3573 if (!nFrameLength) {
3574 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3575 return;
3576 }
3577
3578 if (NULL == pbFrames) {
3579 hddLog(LOGE, FL("pbFrames is NULL"));
3580 return;
3581 }
3582
3583 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3584 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3585
3586 /* Get pAdapter from Destination mac address of the frame */
3587 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3589 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3590 nFrameLength);
3591#else
3592 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3593 nFrameLength);
3594#endif
3595 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3596 } else if (type == SIR_MAC_MGMT_FRAME &&
3597 subType == SIR_MAC_MGMT_DEAUTH) {
3598#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3599 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3600 nFrameLength);
3601#else
3602 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3603 nFrameLength);
3604#endif
3605 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3606 } else {
3607 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3608 type, subType);
3609 return;
3610 }
3611}
3612#endif
3613
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003614#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003615/**
3616 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3617 * @pAdapter: pointer to adapter
3618 * @tid: traffic identifier
3619 * @state: state
3620 * @measInterval: measurement interval
3621 *
3622 * This function sends traffic stream metrics IE information to
3623 * the supplicant via wireless event.
3624 *
3625 * Return: none
3626 */
3627static void
3628hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3629 uint8_t state, uint16_t measInterval)
3630{
3631 union iwreq_data wrqu;
3632 char buf[IW_CUSTOM_MAX + 1];
3633 int nBytes = 0;
3634
3635 if (NULL == pAdapter)
3636 return;
3637
3638 /* create the event */
3639 memset(&wrqu, '\0', sizeof(wrqu));
3640 memset(buf, '\0', sizeof(buf));
3641
3642 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3643 tid, state, measInterval);
3644
3645 nBytes =
3646 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3647 measInterval);
3648
3649 wrqu.data.pointer = buf;
3650 wrqu.data.length = nBytes;
3651 /* send the event */
3652 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3653}
3654
3655/**
3656 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3657 * @pAdapter: pointer to adapter
3658 * @pRoamInfo: pointer to roam info
3659 *
3660 * This function sends cckm preauth indication to the supplicant
3661 * via wireless custom event.
3662 *
3663 * Return: none
3664 */
3665static void
3666hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3667{
3668 union iwreq_data wrqu;
3669 char buf[IW_CUSTOM_MAX + 1];
3670 char *pos = buf;
3671 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3672
3673 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3674 return;
3675
3676 /* create the event */
3677 memset(&wrqu, '\0', sizeof(wrqu));
3678 memset(buf, '\0', sizeof(buf));
3679
3680 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3681 hddLog(LOG1,
3682 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3683 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3684 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3685
3686 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3687 pos += nBytes;
3688 freeBytes -= nBytes;
3689
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303690 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303691 pos += QDF_MAC_ADDR_SIZE;
3692 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003693
3694 nBytes = snprintf(pos, freeBytes, " %u:%u",
3695 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3696 freeBytes -= nBytes;
3697
3698 wrqu.data.pointer = buf;
3699 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3700
3701 /* send the event */
3702 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3703}
3704
3705/**
3706 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3707 * @pAdapter: pointer to adapter
3708 * @pRoamInfo: pointer to roam info
3709 *
3710 * Return: none
3711 */
3712static void
3713hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3714 tCsrRoamInfo *pRoamInfo)
3715{
3716 union iwreq_data wrqu;
3717 char buf[IW_CUSTOM_MAX + 1];
3718 int nBytes = 0;
3719
3720 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3721 return;
3722
3723 /* create the event */
3724 memset(&wrqu, '\0', sizeof(wrqu));
3725 memset(buf, '\0', sizeof(buf));
3726
3727 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3728
3729 nBytes =
3730 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3731 pRoamInfo->tsmRoamDelay);
3732
3733 wrqu.data.pointer = buf;
3734 wrqu.data.length = nBytes;
3735
3736 /* send the event */
3737 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3738}
3739
3740/**
3741 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3742 * @pAdapter: pointer to adapter
3743 * @measurementToken: measurement token
3744 * @flag: flag
3745 * @numBss: number of bss
3746 *
3747 * If the measurement is none and no scan results found,
3748 * indicate the supplicant about measurement done.
3749 *
3750 * Return: none
3751 */
3752void
3753hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3754 const uint16_t measurementToken,
3755 const bool flag, const uint8_t numBss)
3756{
3757 union iwreq_data wrqu;
3758 char buf[IW_CUSTOM_MAX];
3759 char *pos = buf;
3760 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3761
3762 memset(&wrqu, '\0', sizeof(wrqu));
3763 memset(buf, '\0', sizeof(buf));
3764
3765 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3766 flag, numBss);
3767
3768 nBytes =
3769 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3770 flag, numBss);
3771
3772 wrqu.data.pointer = buf;
3773 wrqu.data.length = nBytes;
3774 /* send the event */
3775 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3776}
3777
3778/**
3779 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3780 * @pAdapter: pointer to adapter
3781 * @pRoamInfo: pointer to roam info
3782 *
3783 * If the measurement is none and no scan results found,
3784 * indicate the supplicant about measurement done.
3785 *
3786 * Return: none
3787 */
3788static void
3789hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3790 const tCsrRoamInfo *pRoamInfo)
3791{
3792 union iwreq_data wrqu;
3793 char buf[IW_CUSTOM_MAX];
3794 char *pos = buf;
3795 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3796 uint8_t i = 0, len = 0;
3797 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3798 uint8_t lastSent = 0, sendBss = 0;
3799 int bcnRepFieldSize =
3800 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3801 bcnReportFields);
3802 uint8_t ieLenByte = 1;
3803 /*
3804 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3805 */
3806#define ESEBCNREPHEADER_LEN (18)
3807
3808 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3809 return;
3810
3811 /*
3812 * Custom event can pass maximum of 256 bytes of data,
3813 * based on the IE len we need to identify how many BSS info can
3814 * be filled in to custom event data.
3815 */
3816 /*
3817 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3818 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3819 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3820 */
3821
3822 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3823 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3824 hddLog(LOG1,
3825 "Measurement Done but no scan results");
3826 /* If the measurement is none and no scan results found,
3827 indicate the supplicant about measurement done */
3828 hdd_indicate_ese_bcn_report_no_results(
3829 pAdapter,
3830 pRoamInfo->pEseBcnReportRsp->
3831 measurementToken,
3832 pRoamInfo->pEseBcnReportRsp->flag,
3833 pRoamInfo->pEseBcnReportRsp->numBss);
3834 } else {
3835 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3836 memset(&wrqu, '\0', sizeof(wrqu));
3837 memset(buf, '\0', sizeof(buf));
3838 tot_bcn_ieLen = 0;
3839 sendBss = 0;
3840 pos = buf;
3841 freeBytes = IW_CUSTOM_MAX;
3842
3843 for (i = lastSent;
3844 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3845 len =
3846 bcnRepFieldSize + ieLenByte +
3847 pRoamInfo->pEseBcnReportRsp->
3848 bcnRepBssInfo[i].ieLen;
3849 if ((len + tot_bcn_ieLen) >
3850 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3851 break;
3852 }
3853 tot_bcn_ieLen += len;
3854 sendBss++;
3855 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3856 i, bcnRepFieldSize, 1,
3857 pRoamInfo->pEseBcnReportRsp->
3858 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3859 }
3860
3861 hddLog(LOG1, "Sending %d BSS Info",
3862 sendBss);
3863 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3864 pRoamInfo->pEseBcnReportRsp->measurementToken,
3865 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3866 tot_bcn_ieLen);
3867
3868 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3869 pRoamInfo->pEseBcnReportRsp->
3870 measurementToken,
3871 pRoamInfo->pEseBcnReportRsp->flag,
3872 sendBss);
3873 pos += nBytes;
3874 freeBytes -= nBytes;
3875
3876 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303877 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003878 sizeof(tot_bcn_ieLen));
3879 pos += sizeof(tot_bcn_ieLen);
3880 freeBytes -= sizeof(tot_bcn_ieLen);
3881
3882 for (i = 0; i < sendBss; i++) {
3883 hddLog(LOG1,
3884 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3885 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3886 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3887 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3888 pRoamInfo->pEseBcnReportRsp->
3889 bcnRepBssInfo[i +
3890 lastSent].bcnReportFields.
3891 ChanNum,
3892 pRoamInfo->pEseBcnReportRsp->
3893 bcnRepBssInfo[i +
3894 lastSent].bcnReportFields.
3895 Spare,
3896 pRoamInfo->pEseBcnReportRsp->
3897 bcnRepBssInfo[i +
3898 lastSent].bcnReportFields.
3899 MeasDuration,
3900 pRoamInfo->pEseBcnReportRsp->
3901 bcnRepBssInfo[i +
3902 lastSent].bcnReportFields.
3903 PhyType,
3904 pRoamInfo->pEseBcnReportRsp->
3905 bcnRepBssInfo[i +
3906 lastSent].bcnReportFields.
3907 RecvSigPower,
3908 pRoamInfo->pEseBcnReportRsp->
3909 bcnRepBssInfo[i +
3910 lastSent].bcnReportFields.
3911 ParentTsf,
3912 pRoamInfo->pEseBcnReportRsp->
3913 bcnRepBssInfo[i +
3914 lastSent].bcnReportFields.
3915 TargetTsf[0],
3916 pRoamInfo->pEseBcnReportRsp->
3917 bcnRepBssInfo[i +
3918 lastSent].bcnReportFields.
3919 TargetTsf[1],
3920 pRoamInfo->pEseBcnReportRsp->
3921 bcnRepBssInfo[i +
3922 lastSent].bcnReportFields.
3923 BcnInterval,
3924 pRoamInfo->pEseBcnReportRsp->
3925 bcnRepBssInfo[i +
3926 lastSent].bcnReportFields.
3927 CapabilityInfo,
3928 pRoamInfo->pEseBcnReportRsp->
3929 bcnRepBssInfo[i +
3930 lastSent].bcnReportFields.
3931 Bssid[0],
3932 pRoamInfo->pEseBcnReportRsp->
3933 bcnRepBssInfo[i +
3934 lastSent].bcnReportFields.
3935 Bssid[1],
3936 pRoamInfo->pEseBcnReportRsp->
3937 bcnRepBssInfo[i +
3938 lastSent].bcnReportFields.
3939 Bssid[2],
3940 pRoamInfo->pEseBcnReportRsp->
3941 bcnRepBssInfo[i +
3942 lastSent].bcnReportFields.
3943 Bssid[3],
3944 pRoamInfo->pEseBcnReportRsp->
3945 bcnRepBssInfo[i +
3946 lastSent].bcnReportFields.
3947 Bssid[4],
3948 pRoamInfo->pEseBcnReportRsp->
3949 bcnRepBssInfo[i +
3950 lastSent].bcnReportFields.
3951 Bssid[5]);
3952
3953 /* bcn report fields are copied */
3954 len =
3955 sizeof(pRoamInfo->pEseBcnReportRsp->
3956 bcnRepBssInfo[i +
3957 lastSent].
3958 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303959 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003960 (char *)&pRoamInfo->
3961 pEseBcnReportRsp->bcnRepBssInfo[i +
3962 lastSent].
3963 bcnReportFields, len);
3964 pos += len;
3965 freeBytes -= len;
3966
3967 /* Add 1 byte of ie len */
3968 len =
3969 pRoamInfo->pEseBcnReportRsp->
3970 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303971 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003972 pos += sizeof(len);
3973 freeBytes -= sizeof(len);
3974
3975 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303976 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003977 (char *)pRoamInfo->
3978 pEseBcnReportRsp->bcnRepBssInfo[i +
3979 lastSent].
3980 pBuf, len);
3981 pos += len;
3982 freeBytes -= len;
3983 }
3984
3985 wrqu.data.pointer = buf;
3986 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3987
3988 /* send the event */
3989 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3990 buf);
3991 lastSent += sendBss;
3992 }
3993 }
3994}
3995
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003996#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003997
3998/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303999 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
4000 * @pHddStaCtx: Station Context
4001 *
4002 * API to check if the connection authentication type is 8021x_sha256.
4003 *
4004 * Return: bool
4005 */
4006#ifdef WLAN_FEATURE_11W
4007static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
4008{
4009 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
4010 pHddStaCtx->conn_info.authType;
4011}
4012#else
4013static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
4014{
4015 return false;
4016}
4017#endif
4018
4019/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004020 * hdd_sme_roam_callback() - hdd sme roam callback
4021 * @pContext: pointer to adapter context
4022 * @pRoamInfo: pointer to roam info
4023 * @roamId: roam id
4024 * @roamStatus: roam status
4025 * @roamResult: roam result
4026 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304027 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004028 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304029QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004030hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
4031 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
4032{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304033 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004034 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
4035 hdd_wext_state_t *pWextState = NULL;
4036 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304037 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004038 hdd_context_t *pHddCtx = NULL;
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304039 struct hdd_chan_change_params chan_change;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004040
4041 hddLog(LOG2,
4042 "CSR Callback: status= %d result= %d roamID=%d",
4043 roamStatus, roamResult, roamId);
4044
4045 /* Sanity check */
4046 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
4047 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304048 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004049 }
4050
4051 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4052 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4053
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05304054 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05304055 pAdapter->sessionId, roamStatus));
4056
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004057 switch (roamStatus) {
4058 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05304059 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
4060 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08004061 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004062 break;
4063
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004064 /*
4065 * We did pre-auth,then we attempted a 11r or ese reassoc.
4066 * reassoc failed due to failure, timeout, reject from ap
4067 * in any case tell the OS, our carrier is off and mark
4068 * interface down.
4069 */
4070 case eCSR_ROAM_FT_REASSOC_FAILED:
4071 hddLog(LOGE,
4072 FL
4073 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
4074 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304075 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004076 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4077 roamStatus, roamResult);
4078 /*
4079 * Check if Mcast/Bcast Filters are set, if yes
4080 * clear the filters here.
4081 */
4082 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
4083 true) {
4084 (WLAN_HDD_GET_CTX(pAdapter))->
4085 hdd_mcastbcast_filter_set = false;
4086 }
4087 pHddStaCtx->ft_carrier_on = false;
4088 pHddStaCtx->hdd_ReassocScenario = false;
4089 hddLog(LOG1,
4090 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
4091 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4092 break;
4093
4094 case eCSR_ROAM_FT_START:
4095 /*
4096 * When we roam for ESE and 11r, we dont want the OS to be
4097 * informed that the link is down. So mark the link ready for
4098 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
4099 * be received. Where in we will not mark the link down
4100 * Also we want to stop tx at this point when we will be
4101 * doing disassoc at this time. This saves 30-60 msec
4102 * after reassoc.
4103 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004104 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07004105 wlan_hdd_netif_queue_control(pAdapter,
4106 WLAN_NETIF_TX_DISABLE,
4107 WLAN_CONTROL_PATH);
4108 status = hdd_roam_deregister_sta(pAdapter,
4109 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304110 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304111 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004112 pHddStaCtx->ft_carrier_on = true;
4113 pHddStaCtx->hdd_ReassocScenario = true;
4114 hddLog(LOG1,
4115 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
4116 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4117 break;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07004118 case eCSR_ROAM_DISABLE_QUEUES:
4119 hdd_info("Disabling queues");
4120 wlan_hdd_netif_queue_control(pAdapter,
4121 WLAN_NETIF_TX_DISABLE,
4122 WLAN_CONTROL_PATH);
4123 break;
4124 case eCSR_ROAM_ENABLE_QUEUES:
4125 hdd_info("Enabling queues");
4126 wlan_hdd_netif_queue_control(pAdapter,
4127 WLAN_WAKE_ALL_NETIF_QUEUE,
4128 WLAN_CONTROL_PATH);
4129 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004130
4131 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004132 /* notify apps that we can't pass traffic anymore */
4133 hddLog(LOG1, FL("Disabling queues"));
4134 wlan_hdd_netif_queue_control(pAdapter,
4135 WLAN_NETIF_TX_DISABLE,
4136 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004137 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004138 wlan_hdd_netif_queue_control(pAdapter,
4139 WLAN_NETIF_CARRIER_OFF,
4140 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004141 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004142 break;
4143 case eCSR_ROAM_LOSTLINK:
4144 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
4145 hddLog(LOG2, "Roaming started due to connection lost");
4146 hddLog(LOG1, FL("Disabling queues"));
4147 wlan_hdd_netif_queue_control(pAdapter,
4148 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4149 WLAN_CONTROL_PATH);
4150 break;
4151 }
4152 case eCSR_ROAM_DISASSOCIATED:
4153 {
4154 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304155 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004156 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4157 roamStatus, roamResult);
4158 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
4159 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4160 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
4161 hdd_conf_mcastbcast_filter(pHddCtx, false);
4162
4163 if (true ==
4164 pHddCtx->sus_res_mcastbcast_filter_valid) {
4165 pHddCtx->configuredMcastBcastFilter =
4166 pHddCtx->sus_res_mcastbcast_filter;
4167 pHddCtx->
4168 sus_res_mcastbcast_filter_valid =
4169 false;
4170 }
4171
4172 hddLog(LOG1,
4173 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4174 hddLog(LOG1,
4175 "McastBcastFilter = %d",
4176 pHddCtx->configuredMcastBcastFilter);
4177 hddLog(LOG1,
4178 "offload: already called mcastbcast filter");
4179 (WLAN_HDD_GET_CTX(pAdapter))->
4180 hdd_mcastbcast_filter_set = false;
4181 }
4182 /* Call to clear any MC Addr List filter applied after
4183 * successful connection.
4184 */
4185 wlan_hdd_set_mc_addr_list(pAdapter, false);
4186 }
4187 break;
4188 case eCSR_ROAM_IBSS_LEAVE:
4189 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304190 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004191 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4192 roamStatus, roamResult);
4193 break;
4194 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4195 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4196 /*
4197 * To Do - address probable memory leak with WEP encryption upon
4198 * successful association.
4199 */
4200 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4201 /* Clear saved connection information in HDD */
4202 hdd_conn_remove_connect_info(
4203 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4204 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304205 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004206 hdd_association_completion_handler(pAdapter, pRoamInfo,
4207 roamId, roamStatus,
4208 roamResult);
4209#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4210 if (pRoamInfo)
4211 pRoamInfo->roamSynchInProgress = false;
4212#endif
4213 break;
4214 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304215 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004216 pRoamInfo,
4217 roamId,
4218 roamStatus,
4219 roamResult);
4220 break;
4221 case eCSR_ROAM_IBSS_IND:
4222 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4223 roamStatus, roamResult);
4224 break;
4225
4226 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304227 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004228 roam_roam_connect_status_update_handler(pAdapter,
4229 pRoamInfo,
4230 roamId,
4231 roamStatus,
4232 roamResult);
4233 break;
4234
4235 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304236 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004237 hdd_roam_mic_error_indication_handler(pAdapter,
4238 pRoamInfo,
4239 roamId,
4240 roamStatus,
4241 roamResult);
4242 break;
4243
4244 case eCSR_ROAM_SET_KEY_COMPLETE:
4245 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304246 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004247 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4248 roamId, roamStatus,
4249 roamResult);
4250 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4251 pHddStaCtx->hdd_ReassocScenario = false;
4252 hddLog(LOG1,
4253 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4254 pHddStaCtx->hdd_ReassocScenario,
4255 pAdapter->sessionId);
4256 }
4257 }
4258#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4259 if (pRoamInfo != NULL)
4260 pRoamInfo->roamSynchInProgress = false;
4261#endif
4262 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004263
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004264 case eCSR_ROAM_FT_RESPONSE:
4265 hdd_send_ft_event(pAdapter);
4266 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004267
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004268 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304269 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4270 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004271 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304272 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004273 wlan_hdd_cfg80211_pmksa_candidate_notify(
4274 pAdapter, pRoamInfo, 1, false);
4275 }
4276 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004277
4278#ifdef FEATURE_WLAN_LFR_METRICS
4279 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4280 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304281 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004282 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4283 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304284 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004285 }
4286 break;
4287 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4288 /*
4289 * This event will notify pre-auth completion in case of success
4290 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304291 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004292 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4293 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304294 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004295 }
4296 break;
4297 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4298 /*
4299 * This event will notify pre-auth completion incase of failure.
4300 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304301 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004302 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4303 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304304 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004305 }
4306 break;
4307 case eCSR_ROAM_HANDOVER_SUCCESS:
4308 /* This event is to notify handover success.
4309 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304310 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004311 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4312 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304313 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004314 }
4315 break;
4316#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004317 case eCSR_ROAM_REMAIN_CHAN_READY:
4318 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4319 break;
4320 case eCSR_ROAM_SEND_ACTION_CNF:
4321 hdd_send_action_cnf(pAdapter,
4322 (roamResult ==
4323 eCSR_ROAM_RESULT_NONE) ? true : false);
4324 break;
4325#ifdef FEATURE_WLAN_TDLS
4326 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304327 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004328 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4329 roamId,
4330 roamStatus,
4331 roamResult);
4332 break;
4333 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4334 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4335 pRoamInfo->reasonCode);
4336 break;
4337#endif
4338#ifdef WLAN_FEATURE_11W
4339 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4340 hdd_indicate_unprot_mgmt_frame(pAdapter,
4341 pRoamInfo->nFrameLength,
4342 pRoamInfo->pbFrames,
4343 pRoamInfo->frameType);
4344 break;
4345#endif
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004346#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004347 case eCSR_ROAM_TSM_IE_IND:
4348 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4349 pRoamInfo->tsmIe.state,
4350 pRoamInfo->tsmIe.msmt_interval);
4351 break;
4352
4353 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4354 {
4355 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4356 pHddStaCtx->conn_info.authType
4357 || eCSR_AUTH_TYPE_CCKM_RSN ==
4358 pHddStaCtx->conn_info.authType) {
4359 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4360 }
4361 break;
4362 }
4363
4364 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4365 {
4366 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4367 break;
4368 }
4369
4370 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4371 {
4372 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4373 break;
4374 }
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004375#endif /* FEATURE_WLAN_ESE */
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304376 case eCSR_ROAM_STA_CHANNEL_SWITCH:
4377 hdd_info("channel switch for session:%d to channel:%d",
4378 pAdapter->sessionId, pRoamInfo->chan_info.chan_id);
4379
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304380 chan_change.chan = pRoamInfo->chan_info.chan_id;
4381 chan_change.chan_params.ch_width =
4382 pRoamInfo->chan_info.ch_width;
4383 chan_change.chan_params.sec_ch_offset =
4384 pRoamInfo->chan_info.sec_ch_offset;
4385 chan_change.chan_params.center_freq_seg0 =
4386 pRoamInfo->chan_info.band_center_freq1;
4387 chan_change.chan_params.center_freq_seg1 =
4388 pRoamInfo->chan_info.band_center_freq2;
4389
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304390 status = hdd_chan_change_notify(pAdapter, pAdapter->dev,
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304391 chan_change);
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304392 if (QDF_IS_STATUS_ERROR(status))
4393 hdd_err("channel change notification failed");
4394
4395 status = cds_set_hw_mode_on_channel_switch(pAdapter->sessionId);
4396 if (QDF_IS_STATUS_ERROR(status))
4397 hdd_info("set hw mode change not done");
4398 break;
Deepak Dhamdhere5cdce842016-05-31 10:39:12 -07004399 case eCSR_ROAM_NDP_STATUS_UPDATE:
4400 hdd_ndp_event_handler(pAdapter, pRoamInfo, roamId, roamStatus,
4401 roamResult);
4402 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004403 default:
4404 break;
4405 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304406 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004407}
4408
4409/**
4410 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4411 * @auth_suite: auth suite
4412 *
4413 * Return: eCsrAuthType enumeration
4414 */
4415eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4416{
4417 eCsrAuthType auth_type;
4418 /* is the auth type supported? */
4419 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4420 auth_type = eCSR_AUTH_TYPE_RSN;
4421 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4422 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004423 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004424 /* Check for 11r FT Authentication with PSK */
4425 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4426 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4427 /* Check for 11R FT Authentication with 802.1X */
4428 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4429 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004430#ifdef FEATURE_WLAN_ESE
4431 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4432 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4433 } else
4434#endif /* FEATURE_WLAN_ESE */
4435#ifdef WLAN_FEATURE_11W
4436 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4437 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4438 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4439 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4440 } else
4441#endif
4442 {
4443 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4444 }
4445 return auth_type;
4446}
4447
4448/**
4449 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4450 * @auth_suite: auth suite
4451 *
4452 * Return: eCsrAuthType enumeration
4453 */
4454eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4455{
4456 eCsrAuthType auth_type;
4457 /* is the auth type supported? */
4458 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4459 auth_type = eCSR_AUTH_TYPE_WPA;
4460 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4461 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4462 } else
4463#ifdef FEATURE_WLAN_ESE
4464 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4465 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4466 } else
4467#endif /* FEATURE_WLAN_ESE */
4468 {
4469 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4470 }
4471 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4472 return auth_type;
4473}
4474
4475/**
4476 * hdd_translate_rsn_to_csr_encryption_type() -
4477 * Translate RSN to CSR encryption type
4478 * @cipher_suite: cipher suite
4479 *
4480 * Return: eCsrEncryptionType enumeration
4481 */
4482eCsrEncryptionType
4483hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4484{
4485 eCsrEncryptionType cipher_type;
4486
4487 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4488 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4489 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4490 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4491 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4492 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4493 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4494 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4495 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4496 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4497 else
4498 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4499
4500 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4501 return cipher_type;
4502}
4503
4504/**
4505 * hdd_translate_wpa_to_csr_encryption_type() -
4506 * Translate WPA to CSR encryption type
4507 * @cipher_suite: cipher suite
4508 *
4509 * Return: eCsrEncryptionType enumeration
4510 */
4511eCsrEncryptionType
4512hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4513{
4514 eCsrEncryptionType cipher_type;
4515
4516 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4517 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4518 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4519 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4520 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4521 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4522 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4523 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4524 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4525 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4526 else
4527 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4528
4529 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4530 return cipher_type;
4531}
4532
4533/**
4534 * hdd_process_genie() - process gen ie
4535 * @pAdapter: pointer to adapter
4536 * @bssid: pointer to mac address
4537 * @pEncryptType: pointer to encryption type
4538 * @mcEncryptType: pointer to multicast encryption type
4539 * @pAuthType: pointer to auth type
4540 *
4541 * Return: 0 on success, error number otherwise
4542 */
4543static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4544 u8 *bssid,
4545 eCsrEncryptionType *pEncryptType,
4546 eCsrEncryptionType *mcEncryptType,
4547 eCsrAuthType *pAuthType,
4548#ifdef WLAN_FEATURE_11W
4549 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4550#endif
4551 uint16_t gen_ie_len, uint8_t *gen_ie)
4552{
4553 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304554 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004555 tDot11fIERSN dot11RSNIE;
4556 tDot11fIEWPA dot11WPAIE;
4557 uint32_t i;
4558 uint8_t *pRsnIe;
4559 uint16_t RSNIeLen;
4560 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4561 bool updatePMKCache = false;
4562
4563 /*
4564 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4565 * setting present flag to 0.
4566 */
4567 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4568 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4569
4570 /* Type check */
4571 if (gen_ie[0] == DOT11F_EID_RSN) {
4572 /* Validity checks */
4573 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4574 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4575 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4576 gen_ie_len);
4577 return -EINVAL;
4578 }
4579 /* Skip past the EID byte and length byte */
4580 pRsnIe = gen_ie + 2;
4581 RSNIeLen = gen_ie_len - 2;
4582 /* Unpack the RSN IE */
4583 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4584 pRsnIe, RSNIeLen, &dot11RSNIE);
4585 /* Copy out the encryption and authentication types */
4586 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4587 dot11RSNIE.pwise_cipher_suite_count);
4588 hddLog(LOG1, FL("authentication suite count: %d"),
4589 dot11RSNIE.akm_suite_count);
4590 /*Here we have followed the apple base code,
4591 but probably I suspect we can do something different */
4592 /* dot11RSNIE.akm_suite_count */
4593 /* Just translate the FIRST one */
4594 *pAuthType =
4595 hdd_translate_rsn_to_csr_auth_type(
4596 dot11RSNIE.akm_suites[0]);
4597 /* dot11RSNIE.pwise_cipher_suite_count */
4598 *pEncryptType =
4599 hdd_translate_rsn_to_csr_encryption_type(
4600 dot11RSNIE.pwise_cipher_suites[0]);
4601 /* dot11RSNIE.gp_cipher_suite_count */
4602 *mcEncryptType =
4603 hdd_translate_rsn_to_csr_encryption_type(
4604 dot11RSNIE.gp_cipher_suite);
4605#ifdef WLAN_FEATURE_11W
4606 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4607 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4608#endif
4609 /* Set the PMKSA ID Cache for this interface */
4610 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4611 if (is_zero_ether_addr(bssid)) {
4612 hddLog(LOGE, FL("MAC address is all zeroes"));
4613 break;
4614 }
4615 updatePMKCache = true;
4616 /*
4617 * For right now, I assume setASSOCIATE() has passed
4618 * in the bssid.
4619 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304620 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304621 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304622 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004623 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4624 }
4625
4626 if (updatePMKCache) {
4627 /*
4628 * Calling csr_roam_set_pmkid_cache to configure the
4629 * PMKIDs into the cache.
4630 */
4631 hddLog(LOG1,
4632 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4633 i);
4634 /* Finally set the PMKSA ID Cache in CSR */
4635 result =
4636 sme_roam_set_pmkid_cache(halHandle,
4637 pAdapter->sessionId,
4638 PMKIDCache,
4639 dot11RSNIE.pmkid_count,
4640 false);
4641 }
4642 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4643 /* Validity checks */
4644 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4645 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4646 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4647 gen_ie_len);
4648 return -EINVAL;
4649 }
4650 /* Skip past the EID and length byte - and four byte WiFi OUI */
4651 pRsnIe = gen_ie + 2 + 4;
4652 RSNIeLen = gen_ie_len - (2 + 4);
4653 /* Unpack the WPA IE */
4654 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4655 pRsnIe, RSNIeLen, &dot11WPAIE);
4656 /* Copy out the encryption and authentication types */
4657 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4658 dot11WPAIE.unicast_cipher_count);
4659 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4660 dot11WPAIE.auth_suite_count);
4661 /* dot11WPAIE.auth_suite_count */
4662 /* Just translate the FIRST one */
4663 *pAuthType =
4664 hdd_translate_wpa_to_csr_auth_type(
4665 dot11WPAIE.auth_suites[0]);
4666 /* dot11WPAIE.unicast_cipher_count */
4667 *pEncryptType =
4668 hdd_translate_wpa_to_csr_encryption_type(
4669 dot11WPAIE.unicast_ciphers[0]);
4670 /* dot11WPAIE.unicast_cipher_count */
4671 *mcEncryptType =
4672 hdd_translate_wpa_to_csr_encryption_type(
4673 dot11WPAIE.multicast_cipher);
4674 } else {
4675 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4676 return -EINVAL;
4677 }
4678 return 0;
4679}
4680
4681/**
4682 * hdd_set_genie_to_csr() - set genie to csr
4683 * @pAdapter: pointer to adapter
4684 * @RSNAuthType: pointer to auth type
4685 *
4686 * Return: 0 on success, error number otherwise
4687 */
4688int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4689{
4690 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4691 uint32_t status = 0;
4692 eCsrEncryptionType RSNEncryptType;
4693 eCsrEncryptionType mcRSNEncryptType;
4694#ifdef WLAN_FEATURE_11W
4695 uint8_t RSNMfpRequired = 0;
4696 uint8_t RSNMfpCapable = 0;
4697#endif
4698 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4699 /* MAC address of assoc peer */
4700 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304701 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004702 pWextState->roamProfile.BSSIDs.bssid,
4703 sizeof(bssid));
4704 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4705 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4706 /* continue */
4707 } else {
4708 return 0;
4709 }
4710 /* The actual processing may eventually be more extensive than this. */
4711 /* Right now, just consume any PMKIDs that are sent in by the app. */
4712 status = hdd_process_genie(pAdapter, bssid,
4713 &RSNEncryptType,
4714 &mcRSNEncryptType, RSNAuthType,
4715#ifdef WLAN_FEATURE_11W
4716 &RSNMfpRequired, &RSNMfpCapable,
4717#endif
4718 pWextState->WPARSNIE[1] + 2,
4719 pWextState->WPARSNIE);
4720 if (status == 0) {
4721 /*
4722 * Now copy over all the security attributes
4723 * you have parsed out.
4724 */
4725 pWextState->roamProfile.EncryptionType.numEntries = 1;
4726 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4727
4728 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4729 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4730 mcRSNEncryptType;
4731
Krunal Sonibe766b02016-03-10 13:00:44 -08004732 if ((QDF_IBSS_MODE == pAdapter->device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004733 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4734 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4735 /*
4736 * For wpa none supplicant sends the WPA IE with unicast
4737 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4738 * multicast cipher as either AES/TKIP based on group
4739 * cipher configuration mentioned in the
4740 * wpa_supplicant.conf.
4741 */
4742
4743 /* Set the unicast cipher same as multicast cipher */
4744 pWextState->roamProfile.EncryptionType.encryptionType[0]
4745 = mcRSNEncryptType;
4746 }
4747#ifdef WLAN_FEATURE_11W
4748 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4749 RSNMfpRequired, RSNMfpCapable);
4750 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4751 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4752#endif
4753 hddLog(LOG1,
4754 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4755 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4756 }
4757 return 0;
4758}
4759
4760/**
4761 * hdd_set_csr_auth_type() - set csr auth type
4762 * @pAdapter: pointer to adapter
4763 * @RSNAuthType: auth type
4764 *
4765 * Return: 0 on success, error number otherwise
4766 */
4767int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4768{
4769 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4770 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4771 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004772
4773 pRoamProfile->AuthType.numEntries = 1;
4774 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4775 pHddStaCtx->conn_info.authType);
4776
4777 switch (pHddStaCtx->conn_info.authType) {
4778 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4779#ifdef FEATURE_WLAN_ESE
4780 case eCSR_AUTH_TYPE_CCKM_WPA:
4781 case eCSR_AUTH_TYPE_CCKM_RSN:
4782#endif
4783 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4784
4785 pRoamProfile->AuthType.authType[0] =
4786 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4787 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4788
4789#ifdef FEATURE_WLAN_ESE
4790 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4791 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4792 == IW_AUTH_KEY_MGMT_802_1X)) {
4793 hddLog(LOG1,
4794 FL("set authType to CCKM WPA. AKM also 802.1X."));
4795 pRoamProfile->AuthType.authType[0] =
4796 eCSR_AUTH_TYPE_CCKM_WPA;
4797 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4798 hddLog(LOG1,
4799 FL("Last chance to set authType to CCKM WPA."));
4800 pRoamProfile->AuthType.authType[0] =
4801 eCSR_AUTH_TYPE_CCKM_WPA;
4802 } else
4803#endif
4804 if ((pWextState->
4805 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4806 == IW_AUTH_KEY_MGMT_802_1X) {
4807 pRoamProfile->AuthType.authType[0] =
4808 eCSR_AUTH_TYPE_WPA;
4809 } else
4810 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4811 == IW_AUTH_KEY_MGMT_PSK) {
4812 pRoamProfile->AuthType.authType[0] =
4813 eCSR_AUTH_TYPE_WPA_PSK;
4814 } else {
4815 pRoamProfile->AuthType.authType[0] =
4816 eCSR_AUTH_TYPE_WPA_NONE;
4817 }
4818 }
4819 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4820#ifdef FEATURE_WLAN_ESE
4821 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4822 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4823 == IW_AUTH_KEY_MGMT_802_1X)) {
4824 hddLog(LOG1,
4825 FL("set authType to CCKM RSN. AKM also 802.1X."));
4826 pRoamProfile->AuthType.authType[0] =
4827 eCSR_AUTH_TYPE_CCKM_RSN;
4828 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4829 hddLog(LOG1,
4830 FL("Last chance to set authType to CCKM RSN."));
4831 pRoamProfile->AuthType.authType[0] =
4832 eCSR_AUTH_TYPE_CCKM_RSN;
4833 } else
4834#endif
4835
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004836 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4837 ((pWextState->
4838 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4839 == IW_AUTH_KEY_MGMT_802_1X)) {
4840 pRoamProfile->AuthType.authType[0] =
4841 eCSR_AUTH_TYPE_FT_RSN;
4842 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4843 &&
4844 ((pWextState->
4845 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4846 == IW_AUTH_KEY_MGMT_PSK)) {
4847 pRoamProfile->AuthType.authType[0] =
4848 eCSR_AUTH_TYPE_FT_RSN_PSK;
4849 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004850
4851#ifdef WLAN_FEATURE_11W
4852 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4853 pRoamProfile->AuthType.authType[0] =
4854 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4855 } else if (RSNAuthType ==
4856 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4857 pRoamProfile->AuthType.authType[0] =
4858 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4859 } else
4860#endif
4861
4862 if ((pWextState->
4863 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4864 == IW_AUTH_KEY_MGMT_802_1X) {
4865 pRoamProfile->AuthType.authType[0] =
4866 eCSR_AUTH_TYPE_RSN;
4867 } else
4868 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4869 == IW_AUTH_KEY_MGMT_PSK) {
4870 pRoamProfile->AuthType.authType[0] =
4871 eCSR_AUTH_TYPE_RSN_PSK;
4872 } else {
4873 pRoamProfile->AuthType.authType[0] =
4874 eCSR_AUTH_TYPE_UNKNOWN;
4875 }
4876 }
4877 break;
4878
4879 case eCSR_AUTH_TYPE_SHARED_KEY:
4880
4881 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4882 break;
4883 default:
4884
4885#ifdef FEATURE_WLAN_ESE
4886 hddLog(LOG1, FL("In default, unknown auth type."));
4887#endif /* FEATURE_WLAN_ESE */
4888 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4889 break;
4890 }
4891
4892 hddLog(LOG1, FL("Set roam Authtype to %d"),
4893 pWextState->roamProfile.AuthType.authType[0]);
4894
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004895 return 0;
4896}
4897
4898/**
4899 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4900 * to the CSR roam profile.
4901 *
4902 * @dev: Pointer to the net device.
4903 * @info: Pointer to the iw_request_info.
4904 * @wrqu: Pointer to the iwreq_data.
4905 * @extra: Pointer to the data.
4906 *
4907 * Return: 0 for success, error number on failure
4908 */
4909static int __iw_set_essid(struct net_device *dev,
4910 struct iw_request_info *info,
4911 union iwreq_data *wrqu, char *extra)
4912{
4913 unsigned long rc;
4914 uint32_t status = 0;
4915 hdd_wext_state_t *pWextState;
4916 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4917 hdd_context_t *hdd_ctx;
4918 uint32_t roamId;
4919 tCsrRoamProfile *pRoamProfile;
4920 eMib_dot11DesiredBssType connectedBssType;
4921 eCsrAuthType RSNAuthType;
4922 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4923 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4924 int ret;
4925
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004926 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004927
4928 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4929 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304930 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004931 return ret;
4932
Krunal Sonibe766b02016-03-10 13:00:44 -08004933 if (pAdapter->device_mode != QDF_STA_MODE &&
4934 pAdapter->device_mode != QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004935 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4936 hdd_device_mode_to_string(pAdapter->device_mode),
4937 pAdapter->device_mode);
4938 return -EINVAL;
4939 }
4940
4941 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4942
4943 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4944 hddLog(LOG2, FL("Counter measure is in progress"));
4945 return -EBUSY;
4946 }
4947 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4948 return -EINVAL;
4949
4950 pRoamProfile = &pWextState->roamProfile;
4951 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4952 (eMib_dot11DesiredBssType_independent ==
4953 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304954 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004955
4956 /* Need to issue a disconnect to CSR. */
4957 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304958 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004959 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4960
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304961 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004962 rc = wait_for_completion_timeout(&pAdapter->
4963 disconnect_comp_var,
4964 msecs_to_jiffies
4965 (WLAN_WAIT_TIME_DISCONNECT));
4966 if (!rc)
4967 hddLog(LOGE, FL("Disconnect event timed out"));
4968 }
4969 }
4970
4971 /*
4972 * when cfg80211 defined, wpa_supplicant wext driver uses
4973 * zero-length, null-string ssid for force disconnection.
4974 * after disconnection (if previously connected) and cleaning ssid,
4975 * driver MUST return success.
4976 */
4977 if (0 == wrqu->essid.length)
4978 return 0;
4979
4980 status = hdd_wmm_get_uapsd_mask(pAdapter,
4981 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304982 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004983 pWextState->roamProfile.uapsd_mask = 0;
4984
4985 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4986
4987 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4988 wrqu->essid.length;
4989
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304990 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004991 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304992 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004993 ssId), extra, wrqu->essid.length);
4994 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4995 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4996
4997 /* set gen ie */
4998 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4999
5000 /* set auth */
5001 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
5002 }
5003#ifdef FEATURE_WLAN_WAPI
5004 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
5005 if (pAdapter->wapi_info.nWapiMode) {
5006 switch (pAdapter->wapi_info.wapiAuthMode) {
5007 case WAPI_AUTH_MODE_PSK:
5008 {
5009 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
5010 pAdapter->wapi_info.wapiAuthMode);
5011 pRoamProfile->AuthType.numEntries = 1;
5012 pRoamProfile->AuthType.authType[0] =
5013 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
5014 break;
5015 }
5016 case WAPI_AUTH_MODE_CERT:
5017 {
5018 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
5019 pAdapter->wapi_info.wapiAuthMode);
5020 pRoamProfile->AuthType.numEntries = 1;
5021 pRoamProfile->AuthType.authType[0] =
5022 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
5023 break;
5024 }
5025 } /* End of switch */
5026 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
5027 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
5028 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
5029 pRoamProfile->EncryptionType.numEntries = 1;
5030 pRoamProfile->EncryptionType.encryptionType[0] =
5031 eCSR_ENCRYPT_TYPE_WPI;
5032 pRoamProfile->mcEncryptionType.numEntries = 1;
5033 pRoamProfile->mcEncryptionType.encryptionType[0] =
5034 eCSR_ENCRYPT_TYPE_WPI;
5035 }
5036 }
5037#endif /* FEATURE_WLAN_WAPI */
5038 /* if previous genIE is not NULL, update AssocIE */
5039 if (0 != pWextState->genIE.length) {
5040 memset(&pWextState->assocAddIE, 0,
5041 sizeof(pWextState->assocAddIE));
5042 memcpy(pWextState->assocAddIE.addIEdata,
5043 pWextState->genIE.addIEdata, pWextState->genIE.length);
5044 pWextState->assocAddIE.length = pWextState->genIE.length;
5045 pWextState->roamProfile.pAddIEAssoc =
5046 pWextState->assocAddIE.addIEdata;
5047 pWextState->roamProfile.nAddIEAssocLength =
5048 pWextState->assocAddIE.length;
5049
5050 /* clear previous genIE after use it */
5051 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
5052 }
5053
5054 /*
5055 * Assumes it is not WPS Association by default, except when
5056 * pAddIEAssoc has WPS IE.
5057 */
5058 pWextState->roamProfile.bWPSAssociation = false;
5059
5060 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
5061 pWextState->roamProfile.
5062 nAddIEAssocLength))
5063 pWextState->roamProfile.bWPSAssociation = true;
5064
5065 /* Disable auto BMPS entry by PMC until DHCP is done */
5066 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
5067 true);
5068
5069 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
5070
5071 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
5072 hdd_select_cbmode(pAdapter,
5073 (WLAN_HDD_GET_CTX(pAdapter))->config->
5074 AdHocChannel5G);
5075 }
Agrawal Ashish6b015762016-05-05 11:22:18 +05305076 /*
5077 * Change conn_state to connecting before sme_roam_connect(),
5078 * because sme_roam_connect() has a direct path to call
5079 * hdd_sme_roam_callback(), which will change the conn_state
5080 * If direct path, conn_state will be accordingly changed to
5081 * NotConnected or Associated by either
5082 * hdd_association_completion_handler() or hdd_dis_connect_handler()
5083 * in sme_RoamCallback()if sme_RomConnect is to be queued,
5084 * Connecting state will remain until it is completed.
5085 *
5086 * If connection state is not changed,
5087 * connection state will remain in eConnectionState_NotConnected state.
5088 * In hdd_association_completion_handler, "hddDisconInProgress" is
5089 * set to true if conn state is eConnectionState_NotConnected.
5090 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
5091 * informed of connect result indication which is an issue.
5092 */
5093 if (QDF_STA_MODE == pAdapter->device_mode ||
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305094 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)
Agrawal Ashish6b015762016-05-05 11:22:18 +05305095 hdd_conn_set_connection_state(pAdapter,
5096 eConnectionState_Connecting);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305097
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005098 status = sme_roam_connect(hHal, pAdapter->sessionId,
5099 &(pWextState->roamProfile), &roamId);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305100 if ((QDF_STATUS_SUCCESS != status) &&
5101 (QDF_STA_MODE == pAdapter->device_mode ||
5102 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
5103 hdd_err("sme_roam_connect (session %d) failed with status %d. -> NotConnected",
5104 pAdapter->sessionId, status);
5105 /* change back to NotAssociated */
5106 hdd_conn_set_connection_state(pAdapter,
5107 eConnectionState_NotConnected);
5108 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005109 pRoamProfile->ChannelInfo.ChannelList = NULL;
5110 pRoamProfile->ChannelInfo.numOfChannels = 0;
5111
5112 EXIT();
5113 return status;
5114}
5115
5116/**
5117 * iw_set_essid() - set essid handler function
5118 * @dev: Pointer to the net device.
5119 * @info: Pointer to the iw_request_info.
5120 * @wrqu: Pointer to the iwreq_data.
5121 * @extra: Pointer to the data.
5122 *
5123 * Return: 0 for success, error number on failure
5124 */
5125int iw_set_essid(struct net_device *dev,
5126 struct iw_request_info *info,
5127 union iwreq_data *wrqu, char *extra)
5128{
5129 int ret;
5130
5131 cds_ssr_protect(__func__);
5132 ret = __iw_set_essid(dev, info, wrqu, extra);
5133 cds_ssr_unprotect(__func__);
5134
5135 return ret;
5136}
5137
5138/**
5139 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
5140 * @dev: pointer to the net device
5141 * @info: pointer to the iw request info
5142 * @dwrq: pointer to iw_point
5143 * @extra: pointer to the data
5144 *
5145 * Return: 0 on success, error number otherwise
5146 */
5147static int __iw_get_essid(struct net_device *dev,
5148 struct iw_request_info *info,
5149 struct iw_point *dwrq, char *extra)
5150{
5151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5152 hdd_context_t *hdd_ctx;
5153 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5154 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5155 int ret;
5156
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005157 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005158
5159 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5160 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305161 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005162 return ret;
5163
5164 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
5165 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
5166 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
5167 || pHddStaCtx->conn_info.connState ==
5168 eConnectionState_IbssDisconnected)
5169 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
5170 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
5171 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
5172 dwrq->length);
5173 dwrq->flags = 1;
5174 } else {
5175 memset(extra, 0, dwrq->length);
5176 dwrq->length = 0;
5177 dwrq->flags = 0;
5178 }
5179 EXIT();
5180 return 0;
5181}
5182
5183/**
5184 * iw_get_essid() - get essid handler function
5185 * @dev: Pointer to the net device.
5186 * @info: Pointer to the iw_request_info.
5187 * @wrqu: Pointer to the iwreq_data.
5188 * @extra: Pointer to the data.
5189 *
5190 * Return: 0 for success, error number on failure
5191 */
5192int iw_get_essid(struct net_device *dev,
5193 struct iw_request_info *info,
5194 struct iw_point *wrqu, char *extra)
5195{
5196 int ret;
5197
5198 cds_ssr_protect(__func__);
5199 ret = __iw_get_essid(dev, info, wrqu, extra);
5200 cds_ssr_unprotect(__func__);
5201
5202 return ret;
5203}
5204
5205/**
5206 * __iw_set_auth() -
5207 * This function sets the auth type received from the wpa_supplicant
5208 * @dev: pointer to the net device
5209 * @info: pointer to the iw request info
5210 * @wrqu: pointer to iwreq_data
5211 * @extra: pointer to the data
5212 *
5213 * Return: 0 on success, error number otherwise
5214 */
5215static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5216 union iwreq_data *wrqu, char *extra)
5217{
5218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5219 hdd_context_t *hdd_ctx;
5220 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5221 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5222 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5223 eCsrEncryptionType mcEncryptionType;
5224 eCsrEncryptionType ucEncryptionType;
5225 int ret;
5226
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005227 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005228
5229 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5230 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305231 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005232 return ret;
5233
5234 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5235 case IW_AUTH_WPA_VERSION:
5236 pWextState->wpaVersion = wrqu->param.value;
5237 break;
5238
5239 case IW_AUTH_CIPHER_PAIRWISE:
5240 {
5241 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5242 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5243 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5244 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5245 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5246 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5247 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5248 if ((IW_AUTH_KEY_MGMT_802_1X
5249 ==
5250 (pWextState->
5251 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5252 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5253 pHddStaCtx->conn_info.authType))
5254 /*Dynamic WEP key */
5255 ucEncryptionType =
5256 eCSR_ENCRYPT_TYPE_WEP40;
5257 else
5258 /*Static WEP key */
5259 ucEncryptionType =
5260 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5261 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5262 if ((IW_AUTH_KEY_MGMT_802_1X
5263 ==
5264 (pWextState->
5265 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5266 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5267 pHddStaCtx->conn_info.authType))
5268 /*Dynamic WEP key */
5269 ucEncryptionType =
5270 eCSR_ENCRYPT_TYPE_WEP104;
5271 else
5272 /*Static WEP key */
5273 ucEncryptionType =
5274 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5275 } else {
5276 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5277 wrqu->param.value);
5278 return -EINVAL;
5279 }
5280
5281 pRoamProfile->EncryptionType.numEntries = 1;
5282 pRoamProfile->EncryptionType.encryptionType[0] =
5283 ucEncryptionType;
5284 }
5285 break;
5286 case IW_AUTH_CIPHER_GROUP:
5287 {
5288 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5289 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5290 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5291 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5292 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5293 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5294 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5295 if ((IW_AUTH_KEY_MGMT_802_1X
5296 ==
5297 (pWextState->
5298 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5299 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5300 pHddStaCtx->conn_info.authType))
5301 mcEncryptionType =
5302 eCSR_ENCRYPT_TYPE_WEP40;
5303 else
5304 mcEncryptionType =
5305 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5306 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5307 /* Dynamic WEP keys won't work with shared keys */
5308 if ((IW_AUTH_KEY_MGMT_802_1X
5309 ==
5310 (pWextState->
5311 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5312 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5313 pHddStaCtx->conn_info.authType)) {
5314 mcEncryptionType =
5315 eCSR_ENCRYPT_TYPE_WEP104;
5316 } else {
5317 mcEncryptionType =
5318 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5319 }
5320 } else {
5321 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5322 wrqu->param.value);
5323 return -EINVAL;
5324 }
5325
5326 pRoamProfile->mcEncryptionType.numEntries = 1;
5327 pRoamProfile->mcEncryptionType.encryptionType[0] =
5328 mcEncryptionType;
5329 }
5330 break;
5331
5332 case IW_AUTH_80211_AUTH_ALG:
5333 {
5334 /* Save the auth algo here and set auth type to SME Roam profile
5335 in the iw_set_ap_address */
5336 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5337 pHddStaCtx->conn_info.authType =
5338 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5339
5340 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5341 pHddStaCtx->conn_info.authType =
5342 eCSR_AUTH_TYPE_SHARED_KEY;
5343
5344 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5345 /*Not supported */
5346 pHddStaCtx->conn_info.authType =
5347 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5348 pWextState->roamProfile.AuthType.authType[0] =
5349 pHddStaCtx->conn_info.authType;
5350 }
5351 break;
5352
5353 case IW_AUTH_KEY_MGMT:
5354 {
5355#ifdef FEATURE_WLAN_ESE
5356#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5357 /*Check for CCKM AKM type */
5358 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5359 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5360 /* Set the CCKM bit in authKeyMgmt */
5361 /*
5362 * Right now, this breaks all ref to authKeyMgmt because
5363 * our code doesn't realize it is a "bitfield"
5364 */
5365 pWextState->authKeyMgmt |=
5366 IW_AUTH_KEY_MGMT_CCKM;
5367 /* Set the key management to 802.1X */
5368 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5369 pWextState->isESEConnection = true;
5370 /*
5371 * This is test code. I need to actually KNOW whether
5372 * this is an RSN Assoc or WPA.
5373 */
5374 pWextState->collectedAuthType =
5375 eCSR_AUTH_TYPE_CCKM_RSN;
5376 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5377 /* Save the key management */
5378 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5379 pWextState->collectedAuthType =
5380 eCSR_AUTH_TYPE_RSN;
5381 } else
5382 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5383 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5384 /* Save the key management anyway */
5385 pWextState->authKeyMgmt = wrqu->param.value;
5386 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5387 /* Save the key management */
5388 pWextState->authKeyMgmt |=
5389 IW_AUTH_KEY_MGMT_802_1X;
5390 pWextState->collectedAuthType =
5391 eCSR_AUTH_TYPE_RSN;
5392 }
5393#else
5394 /* Save the key management */
5395 pWextState->authKeyMgmt = wrqu->param.value;
5396#endif /* FEATURE_WLAN_ESE */
5397 }
5398 break;
5399
5400 case IW_AUTH_TKIP_COUNTERMEASURES:
5401 {
5402 if (wrqu->param.value) {
5403 hddLog(LOG2,
5404 "Counter Measure started %d",
5405 wrqu->param.value);
5406 pWextState->mTKIPCounterMeasures =
5407 TKIP_COUNTER_MEASURE_STARTED;
5408 } else {
5409 hddLog(LOG2,
5410 "Counter Measure stopped=%d",
5411 wrqu->param.value);
5412 pWextState->mTKIPCounterMeasures =
5413 TKIP_COUNTER_MEASURE_STOPED;
5414 }
5415 }
5416 break;
5417 case IW_AUTH_DROP_UNENCRYPTED:
5418 case IW_AUTH_WPA_ENABLED:
5419 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5420 case IW_AUTH_ROAMING_CONTROL:
5421 case IW_AUTH_PRIVACY_INVOKED:
5422
5423 default:
5424
5425 hddLog(LOGW, FL("called with unsupported auth type %d"),
5426 wrqu->param.flags & IW_AUTH_INDEX);
5427 break;
5428 }
5429
5430 EXIT();
5431 return 0;
5432}
5433
5434/**
5435 * iw_set_auth() - set auth callback function
5436 * @dev: Pointer to the net device.
5437 * @info: Pointer to the iw_request_info.
5438 * @wrqu: Pointer to the iwreq_data.
5439 * @extra: Pointer to the data.
5440 *
5441 * Return: 0 for success, error number on failure.
5442 */
5443int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5444 union iwreq_data *wrqu, char *extra)
5445{
5446 int ret;
5447
5448 cds_ssr_protect(__func__);
5449 ret = __iw_set_auth(dev, info, wrqu, extra);
5450 cds_ssr_unprotect(__func__);
5451
5452 return ret;
5453}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005454/**
5455 * __iw_get_auth() -
5456 * This function returns the auth type to the wpa_supplicant
5457 * @dev: pointer to the net device
5458 * @info: pointer to the iw request info
5459 * @wrqu: pointer to iwreq_data
5460 * @extra: pointer to the data
5461 *
5462 * Return: 0 on success, error number otherwise
5463 */
5464static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5465 union iwreq_data *wrqu, char *extra)
5466{
5467 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5468 hdd_context_t *hdd_ctx;
5469 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5470 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5471 int ret;
5472
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005473 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005474
5475 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5476 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305477 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005478 return ret;
5479
5480 switch (pRoamProfile->negotiatedAuthType) {
5481 case eCSR_AUTH_TYPE_WPA_NONE:
5482 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5483 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5484 break;
5485 case eCSR_AUTH_TYPE_WPA:
5486 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5487 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5488 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005489
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005490 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005491 case eCSR_AUTH_TYPE_RSN:
5492 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5493 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5494 break;
5495 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5496 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5497 break;
5498 case eCSR_AUTH_TYPE_SHARED_KEY:
5499 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5500 break;
5501 case eCSR_AUTH_TYPE_UNKNOWN:
5502 hddLog(LOG1, FL("called with unknown auth type"));
5503 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5504 break;
5505 case eCSR_AUTH_TYPE_AUTOSWITCH:
5506 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5507 break;
5508 case eCSR_AUTH_TYPE_WPA_PSK:
5509 hddLog(LOG1, FL("called with WPA PSK auth type"));
5510 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5511 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005512
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005513 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005514 case eCSR_AUTH_TYPE_RSN_PSK:
5515#ifdef WLAN_FEATURE_11W
5516 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5517 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5518#endif
5519 hddLog(LOG1, FL("called with RSN PSK auth type"));
5520 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5521 return -EIO;
5522 default:
5523 hddLog(LOGE, FL("called with unknown auth type"));
5524 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5525 return -EIO;
5526 }
5527 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5528 switch (pRoamProfile->negotiatedUCEncryptionType) {
5529 case eCSR_ENCRYPT_TYPE_NONE:
5530 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5531 break;
5532 case eCSR_ENCRYPT_TYPE_WEP40:
5533 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5534 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5535 break;
5536 case eCSR_ENCRYPT_TYPE_TKIP:
5537 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5538 break;
5539 case eCSR_ENCRYPT_TYPE_WEP104:
5540 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5541 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5542 break;
5543 case eCSR_ENCRYPT_TYPE_AES:
5544 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5545 break;
5546 default:
5547 hddLog(LOG1, FL("called with unknown auth type %d"),
5548 pRoamProfile->negotiatedUCEncryptionType);
5549 return -EIO;
5550 }
5551 }
5552
5553 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5554 switch (pRoamProfile->negotiatedMCEncryptionType) {
5555 case eCSR_ENCRYPT_TYPE_NONE:
5556 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5557 break;
5558 case eCSR_ENCRYPT_TYPE_WEP40:
5559 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5560 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5561 break;
5562 case eCSR_ENCRYPT_TYPE_TKIP:
5563 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5564 break;
5565 case eCSR_ENCRYPT_TYPE_WEP104:
5566 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5567 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5568 break;
5569 case eCSR_ENCRYPT_TYPE_AES:
5570 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5571 break;
5572 default:
5573 hddLog(LOG1, FL("called with unknown auth type %d"),
5574 pRoamProfile->negotiatedMCEncryptionType);
5575 return -EIO;
5576 }
5577 }
5578
5579 hddLog(LOG1, FL("called with auth type %d"),
5580 pRoamProfile->AuthType.authType[0]);
5581 EXIT();
5582 return 0;
5583}
5584
5585/**
5586 * iw_get_auth() - get auth callback function
5587 * @dev: Pointer to the net device.
5588 * @info: Pointer to the iw_request_info.
5589 * @wrqu: Pointer to the iwreq_data.
5590 * @extra: Pointer to the data.
5591 *
5592 * Return: 0 for success, error number on failure.
5593 */
5594int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5595 union iwreq_data *wrqu, char *extra)
5596{
5597 int ret;
5598
5599 cds_ssr_protect(__func__);
5600 ret = __iw_get_auth(dev, info, wrqu, extra);
5601 cds_ssr_unprotect(__func__);
5602
5603 return ret;
5604}
5605
5606/**
5607 * __iw_set_ap_address() - set ap address
5608 * @dev: pointer to the net device
5609 * @info: pointer to the iw request info
5610 * @wrqu: pointer to iwreq_data
5611 * @extra: pointer to the data
5612 *
5613 * This function updates the HDD global station context connection info
5614 * BSSID with the MAC address received from the wpa_supplicant.
5615 *
5616 * Return: 0 on success, error number otherwise
5617 */
5618static int __iw_set_ap_address(struct net_device *dev,
5619 struct iw_request_info *info,
5620 union iwreq_data *wrqu, char *extra)
5621{
5622
5623 hdd_adapter_t *adapter;
5624 hdd_context_t *hdd_ctx;
5625 hdd_station_ctx_t *pHddStaCtx =
5626 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5627 uint8_t *pMacAddress = NULL;
5628 int ret;
5629
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005630 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005631
5632 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5633
5634 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5635 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305636 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005637 return ret;
5638
5639 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5640 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305641 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305642 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005643 EXIT();
5644
5645 return 0;
5646}
5647
5648/**
5649 * iw_set_ap_address() - set ap addresses callback function
5650 * @dev: Pointer to the net device.
5651 * @info: Pointer to the iw_request_info.
5652 * @wrqu: Pointer to the iwreq_data.
5653 * @extra: Pointer to the data.
5654 *
5655 * Return: 0 for success, error number on failure.
5656 */
5657int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5658 union iwreq_data *wrqu, char *extra)
5659{
5660 int ret;
5661
5662 cds_ssr_protect(__func__);
5663 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5664 cds_ssr_unprotect(__func__);
5665
5666 return ret;
5667}
5668
5669/**
5670 * __iw_get_ap_address() - get ap address
5671 * @dev: pointer to the net device
5672 * @info: pointer to the iw request info
5673 * @wrqu: pointer to iwreq_data
5674 * @extra: pointer to the data
5675 *
5676 * This function returns currently associated BSSID.
5677 *
5678 * Return: 0 on success, error number otherwise
5679 */
5680static int __iw_get_ap_address(struct net_device *dev,
5681 struct iw_request_info *info,
5682 union iwreq_data *wrqu, char *extra)
5683{
5684 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5685 hdd_context_t *hdd_ctx;
5686 hdd_station_ctx_t *pHddStaCtx =
5687 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5688 int ret;
5689
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005690 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005691
5692 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5693 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305694 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005695 return ret;
5696
5697 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5698 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305699 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005700 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305701 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005702 } else {
5703 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5704 }
5705 EXIT();
5706 return 0;
5707}
5708
5709/**
5710 * iw_get_ap_address() - get ap addresses callback function
5711 * @dev: Pointer to the net device.
5712 * @info: Pointer to the iw_request_info.
5713 * @wrqu: Pointer to the iwreq_data.
5714 * @extra: Pointer to the data.
5715 *
5716 * Return: 0 for success, error number on failure.
5717 */
5718int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5719 union iwreq_data *wrqu, char *extra)
5720{
5721 int ret;
5722
5723 cds_ssr_protect(__func__);
5724 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5725 cds_ssr_unprotect(__func__);
5726
5727 return ret;
5728}