blob: 80f775392fb8e745a579a156a2eabbe499e6969c [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>
53#include <cds_sched.h>
54#include "cds_concurrency.h"
55#include "sme_power_save_api.h"
56#include "ol_txrx_ctrl_api.h"
57#include "ol_txrx_types.h"
Dhanashri Atre182b0272016-02-17 15:35:07 -080058#include "ol_txrx.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080059#include "cdp_txrx_flow_ctrl_legacy.h"
60#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080061
62/* These are needed to recognize WPA and RSN suite types */
63#define HDD_WPA_OUI_SIZE 4
64#define HDD_RSN_OUI_SIZE 4
65uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
66uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
67uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
68uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
69uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
70uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
71
72#ifdef FEATURE_WLAN_ESE
73/* CCKM */
74uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
75/* CCKM */
76uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
77#endif /* FEATURE_WLAN_ESE */
78
79/* group cipher */
80uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
81
82/* WEP-40 or RSN */
83uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
84
85/* TKIP or RSN-PSK */
86uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
87
88/* Reserved */
89uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
90
91/* AES-CCMP */
92uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
93
94/* WEP-104 */
95uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
96
97#ifdef WLAN_FEATURE_11W
98/* RSN-PSK-SHA256 */
99uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
100
101/* RSN-8021X-SHA256 */
102uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
103#endif
104
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800105/* Offset where the EID-Len-IE, start. */
106#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
107#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800108
109#define BEACON_FRAME_IES_OFFSET 12
110#define HDD_PEER_AUTHORIZE_WAIT 10
111
112/**
113 * hdd_conn_set_authenticated() - set authentication state
114 * @pAdapter: pointer to the adapter
115 * @authState: authentication state
116 *
117 * This function updates the global HDD station context
118 * authentication state.
119 *
120 * Return: none
121 */
122static void
123hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
124{
125 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
126 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
127
128 /* save the new connection state */
129 hddLog(LOG1,
130 FL("Authenticated state Changed from oldState:%d to State:%d"),
131 pHddStaCtx->conn_info.uIsAuthenticated, authState);
132 pHddStaCtx->conn_info.uIsAuthenticated = authState;
133
134 /* Check is pending ROC request or not when auth state changed */
135 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
136}
137
138/**
139 * hdd_conn_set_connection_state() - set connection state
140 * @pAdapter: pointer to the adapter
141 * @connState: connection state
142 *
143 * This function updates the global HDD station context connection state.
144 *
145 * Return: none
146 */
147void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
148 eConnectionState connState)
149{
150 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
151 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
152
153 /* save the new connection state */
154 hddLog(LOG1, FL("ConnectionState Changed from oldState:%d to State:%d"),
155 pHddStaCtx->conn_info.connState, connState);
156 pHddStaCtx->conn_info.connState = connState;
157
158 /* Check is pending ROC request or not when connection state changed */
159 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
160}
161
162/**
163 * hdd_conn_get_connection_state() - get connection state
164 * @pAdapter: pointer to the adapter
165 * @pConnState: pointer to connection state
166 *
167 * This function updates the global HDD station context connection state.
168 *
169 * Return: true if (Infra Associated or IBSS Connected)
170 * and sets output parameter pConnState;
171 * false otherwise
172 */
173static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
174 eConnectionState *pConnState)
175{
176 bool fConnected = false;
177 eConnectionState connState;
178
179 /* get the connection state. */
180 connState = pHddStaCtx->conn_info.connState;
181
182 if (eConnectionState_Associated == connState ||
183 eConnectionState_IbssConnected == connState ||
184 eConnectionState_IbssDisconnected == connState) {
185 fConnected = true;
186 }
187
188 if (pConnState)
189 *pConnState = connState;
190
191 return fConnected;
192}
193
194/**
195 * hdd_is_connecting() - Function to check connection progress
196 * @hdd_sta_ctx: pointer to global HDD Station context
197 *
198 * Return: true if connecting, false otherwise
199 */
200bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
201{
202 return hdd_sta_ctx->conn_info.connState ==
203 eConnectionState_Connecting;
204}
205
206/**
207 * hdd_conn_is_connected() - Function to check connection status
208 * @pHddStaCtx: pointer to global HDD Station context
209 *
210 * Return: false if any errors encountered, true otherwise
211 */
212bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
213{
214 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
215}
216
217/**
218 * hdd_conn_get_connected_band() - get current connection radio band
219 * @pHddStaCtx: pointer to global HDD Station context
220 *
221 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
222 * eCSR_BAND_ALL if not connected
223 */
224eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
225{
226 uint8_t staChannel = 0;
227
228 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
229 staChannel = pHddStaCtx->conn_info.operationChannel;
230
231 if (staChannel > 0 && staChannel < 14)
232 return eCSR_BAND_24;
233 else if (staChannel >= 36 && staChannel <= 184)
234 return eCSR_BAND_5G;
235 else /* If station is not connected return as eCSR_BAND_ALL */
236 return eCSR_BAND_ALL;
237}
238
239/**
240 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
241 * @pHddStaCtx: pointer to global HDD Station context
242 * @pConnectedCipherAlgo: pointer to connected cipher algo
243 *
244 * Return: false if any errors encountered, true otherwise
245 */
246static inline bool
247hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
248 eCsrEncryptionType *pConnectedCipherAlgo)
249{
250 bool fConnected = false;
251
252 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
253
254 if (pConnectedCipherAlgo)
255 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
256
257 return fConnected;
258}
259
260/**
261 * hdd_conn_get_connected_bss_type() - get current bss type
262 * @pHddStaCtx: pointer to global HDD Station context
263 * @pConnectedBssType: pointer to connected bss type
264 *
265 * Return: false if any errors encountered, true otherwise
266 */
267inline bool
268hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
269 eMib_dot11DesiredBssType *pConnectedBssType)
270{
271 bool fConnected = false;
272
273 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
274
275 if (pConnectedBssType) {
276 *pConnectedBssType =
277 pHddStaCtx->conn_info.connDot11DesiredBssType;
278 }
279
280 return fConnected;
281}
282
283/**
284 * hdd_conn_save_connected_bss_type() - set connected bss type
285 * @pHddStaCtx: pointer to global HDD Station context
286 * @csr_roamBssType: bss type
287 *
288 * Return: none
289 */
290static inline void
291hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
292 eCsrRoamBssType csr_roamBssType)
293{
294 switch (csr_roamBssType) {
295 case eCSR_BSS_TYPE_INFRASTRUCTURE:
296 pHddStaCtx->conn_info.connDot11DesiredBssType =
297 eMib_dot11DesiredBssType_infrastructure;
298 break;
299
300 case eCSR_BSS_TYPE_IBSS:
301 case eCSR_BSS_TYPE_START_IBSS:
302 pHddStaCtx->conn_info.connDot11DesiredBssType =
303 eMib_dot11DesiredBssType_independent;
304 break;
305
306 /** We will never set the BssType to 'any' when attempting a connection
307 so CSR should never send this back to us.*/
308 case eCSR_BSS_TYPE_ANY:
309 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530310 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800311 break;
312 }
313}
314
315/**
316 * hdd_conn_save_connect_info() - save current connection information
317 * @pAdapter: pointer to adapter
318 * @pRoamInfo: pointer to roam info
319 * @eBssType: bss type
320 *
321 * Return: none
322 */
323static void
324hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
325 eCsrRoamBssType eBssType)
326{
327 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
328 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
329
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530330 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331
332 if (pRoamInfo) {
333 /* Save the BSSID for the connection */
334 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530335 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530336 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800337 &pRoamInfo->bssid);
338
339 /*
340 * Save the Station ID for this station from
341 * the 'Roam Info'. For IBSS mode, staId is
342 * assigned in NEW_PEER_IND. For reassoc,
343 * the staID doesn't change and it may be invalid
344 * in this structure so no change here.
345 */
346 if (!pRoamInfo->fReassocReq) {
347 pHddStaCtx->conn_info.staId[0] =
348 pRoamInfo->staId;
349 }
350 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530351 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800352 &pRoamInfo->bssid);
353 } else {
354 /*
355 * can't happen. We need a valid IBSS or Infra setting
356 * in the BSSDescription or we can't function.
357 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530358 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800359 }
360
361 /* notify WMM */
362 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
363
364 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530365 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366 } else {
367 /* Get Multicast Encryption Type */
368 encryptType =
369 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
370 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
371 /* Get Unicast Encryption Type */
372 encryptType =
373 pRoamInfo->u.pConnectedProfile->EncryptionType;
374 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
375
376 pHddStaCtx->conn_info.authType =
377 pRoamInfo->u.pConnectedProfile->AuthType;
378
379 pHddStaCtx->conn_info.operationChannel =
380 pRoamInfo->u.pConnectedProfile->operationChannel;
381
382 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530383 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 &pRoamInfo->u.pConnectedProfile->SSID,
385 sizeof(tSirMacSSid));
386
387 /* Save dot11mode in which STA associated to AP */
388 pHddStaCtx->conn_info.dot11Mode =
389 pRoamInfo->u.pConnectedProfile->dot11Mode;
390
391 pHddStaCtx->conn_info.proxyARPService =
392 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530393
394 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
395
396 pHddStaCtx->conn_info.rate_flags =
397 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800398 }
399 }
400 /* save the connected BssType */
401 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
402}
403
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800404/**
405 * hdd_send_ft_assoc_response() - send fast transition assoc response
406 * @dev: pointer to net device
407 * @pAdapter: pointer to adapter
408 * @pCsrRoamInfo: pointer to roam info
409 *
410 * Send the 11R key information to the supplicant. Only then can the supplicant
411 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
412 * for the same purpose.)
413 *
414 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
415 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
416 * This is the Assoc Response.
417 *
418 * Return: none
419 */
420static void
421hdd_send_ft_assoc_response(struct net_device *dev,
422 hdd_adapter_t *pAdapter,
423 tCsrRoamInfo *pCsrRoamInfo)
424{
425 union iwreq_data wrqu;
426 char *buff;
427 unsigned int len = 0;
428 u8 *pFTAssocRsp = NULL;
429
430 if (pCsrRoamInfo->nAssocRspLength == 0) {
431 hddLog(LOGE,
432 FL("pCsrRoamInfo->nAssocRspLength=%d"),
433 (int)pCsrRoamInfo->nAssocRspLength);
434 return;
435 }
436
437 pFTAssocRsp =
438 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
439 pCsrRoamInfo->nAssocReqLength);
440 if (pFTAssocRsp == NULL) {
441 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
442 return;
443 }
444 /* pFTAssocRsp needs to point to the IEs */
445 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
446 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
447 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
448
449 /* We need to send the IEs to the supplicant. */
450 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
451 if (buff == NULL) {
452 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
453 return;
454 }
455 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
456 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
457 wrqu.data.length = len;
458 memset(buff, 0, IW_GENERIC_IE_MAX);
459 memcpy(buff, pFTAssocRsp, len);
460 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
461
462 kfree(buff);
463}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800464
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800465/**
466 * hdd_send_ft_event() - send fast transition event
467 * @pAdapter: pointer to adapter
468 *
469 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
470 * FT events to the supplicant. At the reception of Auth2 we send the RIC
471 * followed by the auth response IEs to the supplicant.
472 * Once both are received in the supplicant, an FT event is generated
473 * to the supplicant.
474 *
475 * Return: none
476 */
477static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
478{
479 uint16_t auth_resp_len = 0;
480 uint32_t ric_ies_length = 0;
481 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
482
483#if defined(KERNEL_SUPPORT_11R_CFG80211)
484 struct cfg80211_ft_event_params ftEvent;
485 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
486 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
487 struct net_device *dev = pAdapter->dev;
488#else
489 char *buff;
490 union iwreq_data wrqu;
491 uint16_t str_len;
492#endif
493
494#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530495 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
496 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800497
498 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
499 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
500 if (ric_ies_length == 0) {
501 hddLog(LOGW,
502 FL("RIC IEs is of length 0 not sending RIC Information for now"));
503 }
504
505 ftEvent.ric_ies = ricIe;
506 ftEvent.ric_ies_len = ric_ies_length;
507 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
508
509 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
510 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
511 &auth_resp_len);
512
513 if (auth_resp_len == 0) {
514 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
515 return;
516 }
517
518 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
519
520 ftEvent.target_ap = ftIe;
521
Anurag Chouhan6d760662016-02-20 16:05:43 +0530522 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
523 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800524
525 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
526 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
527 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
528 ftEvent.target_ap[0], ftEvent.target_ap[1],
529 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
530 ftEvent.target_ap[5]);
531
532 (void)cfg80211_ft_event(dev, &ftEvent);
533
534#else
535 /* We need to send the IEs to the supplicant */
536 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
537 if (buff == NULL) {
538 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
539 return;
540 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530541 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800542
543 /* Sme needs to send the RIC IEs first */
544 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
545 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
546 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
547 &ric_ies_length);
548 if (ric_ies_length == 0) {
549 hddLog(LOGW,
550 FL("RIC IEs is of length 0 not sending RIC Information for now"));
551 } else {
552 wrqu.data.length = str_len + ric_ies_length;
553 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
554 }
555
556 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530557 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800558 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
559 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
560 (u8 *) &buff[str_len],
561 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
562
563 if (auth_resp_len == 0) {
564 kfree(buff);
565 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
566 return;
567 }
568
569 wrqu.data.length = str_len + auth_resp_len;
570 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
571
572 kfree(buff);
573#endif
574}
575
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800576#ifdef FEATURE_WLAN_ESE
577/**
578 * hdd_send_new_ap_channel_info() - send new ap channel info
579 * @dev: pointer to net device
580 * @pAdapter: pointer to adapter
581 * @pCsrRoamInfo: pointer to roam info
582 *
583 * Send the ESE required "new AP Channel info" to the supplicant.
584 * (This keeps the supplicant "up to date" on the current channel.)
585 *
586 * The current (new AP) channel information is passed in.
587 *
588 * Return: none
589 */
590static void
591hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
592 tCsrRoamInfo *pCsrRoamInfo)
593{
594 union iwreq_data wrqu;
595 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
596
597 if (descriptor == NULL) {
598 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
599 return;
600 }
601 /*
602 * Send the Channel event, the supplicant needs this to generate
603 * the Adjacent AP report.
604 */
605 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
606 descriptor->channelId);
607 memset(&wrqu, '\0', sizeof(wrqu));
608 wrqu.freq.m = descriptor->channelId;
609 wrqu.freq.e = 0;
610 wrqu.freq.i = 0;
611 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
612}
613
614#endif /* FEATURE_WLAN_ESE */
615
616/**
617 * hdd_send_update_beacon_ies_event() - send update beacons ie event
618 * @pAdapter: pointer to adapter
619 * @pCsrRoamInfo: pointer to roam info
620 *
621 * Return: none
622 */
623static void
624hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
625 tCsrRoamInfo *pCsrRoamInfo)
626{
627 union iwreq_data wrqu;
628 u8 *pBeaconIes;
629 u8 currentLen = 0;
630 char *buff;
631 int totalIeLen = 0, currentOffset = 0, strLen;
632
633 memset(&wrqu, '\0', sizeof(wrqu));
634
635 if (0 == pCsrRoamInfo->nBeaconLength) {
636 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
637 return;
638 }
639 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
640 if (pBeaconIes == NULL) {
641 hddLog(LOGW, FL("Beacon IEs is NULL"));
642 return;
643 }
644 /* pBeaconIes needs to point to the IEs */
645 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
646 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
647 hddLog(LOG1, FL("Beacon IEs length = %d"),
648 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
649
650 /* We need to send the IEs to the supplicant. */
651 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
652 if (buff == NULL) {
653 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
654 return;
655 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530656 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800657
658 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
659 currentLen = strLen + 1;
660
661 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
662 do {
663 /*
664 * If the beacon size exceeds max CUSTOM event size, break it
665 * into chunks of CUSTOM event max size and send it to
666 * supplicant. Changes are done in supplicant to handle this.
667 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530668 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800669 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530670 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530671 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800672 currentLen);
673 currentOffset += currentLen;
674 totalIeLen -= currentLen;
675 wrqu.data.length = strLen + 1 + currentLen;
676 if (totalIeLen)
677 buff[strLen] = 1; /* more chunks pending */
678 else
679 buff[strLen] = 0; /* last chunk */
680
681 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
682 currentLen);
683 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
684 } while (totalIeLen > 0);
685
686 kfree(buff);
687}
688
689/**
690 * hdd_send_association_event() - send association event
691 * @dev: pointer to net device
692 * @pCsrRoamInfo: pointer to roam info
693 *
694 * Return: none
695 */
696static void hdd_send_association_event(struct net_device *dev,
697 tCsrRoamInfo *pCsrRoamInfo)
698{
699 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
700 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
701 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
702 union iwreq_data wrqu;
703 int we_event;
704 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530705 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800706
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800707 /* Added to find the auth type on the fly at run time */
708 /* rather than with cfg to see if FT is enabled */
709 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
710 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800711
712 memset(&wrqu, '\0', sizeof(wrqu));
713 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
714 we_event = SIOCGIWAP;
715#ifdef WLAN_FEATURE_ROAM_OFFLOAD
716 if (NULL != pCsrRoamInfo)
717 if (pCsrRoamInfo->roamSynchInProgress)
718 /* change logging before release */
719 hddLog(LOG4, "LFR3:hdd_send_association_event");
720#endif
721 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
722 if (!pCsrRoamInfo) {
723 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
724 return;
725 }
726
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800727 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
728 cds_incr_active_session(pAdapter->device_mode,
729 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800730 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
731 sizeof(pCsrRoamInfo->pBssDesc->bssId));
732
733#ifdef WLAN_FEATURE_P2P_DEBUG
734 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
735 if (global_p2p_connection_status ==
736 P2P_CLIENT_CONNECTING_STATE_1) {
737 global_p2p_connection_status =
738 P2P_CLIENT_CONNECTED_STATE_1;
739 hddLog(LOGE,
740 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
741 } else if (global_p2p_connection_status ==
742 P2P_CLIENT_CONNECTING_STATE_2) {
743 global_p2p_connection_status =
744 P2P_CLIENT_COMPLETED_STATE;
745 hddLog(LOGE,
746 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
747 }
748 }
749#endif
750 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
751 MAC_ADDRESS_STR "\n",
752 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
753 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
754 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
755
756 /*
757 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
758 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800759 * fFTEnable is true.
760 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800761 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800762 if ((pRoamProfile->AuthType.authType[0] ==
763 eCSR_AUTH_TYPE_FT_RSN_PSK)
764 || (pRoamProfile->AuthType.authType[0] ==
765 eCSR_AUTH_TYPE_FT_RSN)
766#ifdef FEATURE_WLAN_ESE
767 || (pRoamProfile->AuthType.authType[0] ==
768 eCSR_AUTH_TYPE_CCKM_RSN)
769 || (pRoamProfile->AuthType.authType[0] ==
770 eCSR_AUTH_TYPE_CCKM_WPA)
771#endif
772 ) {
773 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
774 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800775 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
776 tSirSmeChanInfo chan_info;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530777 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800778 &pHddStaCtx->conn_info.bssId);
779 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
780 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
781 chan_info.info = pCsrRoamInfo->chan_info.info;
782 chan_info.band_center_freq1 =
783 pCsrRoamInfo->chan_info.band_center_freq1;
784 chan_info.band_center_freq2 =
785 pCsrRoamInfo->chan_info.band_center_freq2;
786 chan_info.reg_info_1 =
787 pCsrRoamInfo->chan_info.reg_info_1;
788 chan_info.reg_info_2 =
789 pCsrRoamInfo->chan_info.reg_info_2;
790
791 /* send peer status indication to oem app */
792 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
793 ePeerConnected,
794 pCsrRoamInfo->
795 timingMeasCap,
796 pAdapter->sessionId,
797 &chan_info);
798 }
799#ifdef MSM_PLATFORM
800#ifdef CONFIG_CNSS
801 /* start timer in sta/p2p_cli */
802 spin_lock_bh(&pHddCtx->bus_bw_lock);
803 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
804 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
805 spin_unlock_bh(&pHddCtx->bus_bw_lock);
806 hdd_start_bus_bw_compute_timer(pAdapter);
807#endif
808#endif
809 } else if (eConnectionState_IbssConnected == /* IBss Associated */
810 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800811 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800812 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
813 ETH_ALEN);
814 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
815 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
816 } else { /* Not Associated */
817
818 pr_info("wlan: disconnected\n");
819 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530820 cds_decr_session_set_pcl(pAdapter->device_mode,
821 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800822 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823
824#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
825 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
826#endif
827
828 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530829 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800830 &pHddStaCtx->conn_info.bssId);
831
832 /* send peer status indication to oem app */
833 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
834 ePeerDisconnected, 0,
835 pAdapter->sessionId,
836 NULL);
837 }
838#ifdef WLAN_FEATURE_LPSS
839 pAdapter->rssi_send = false;
840 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
841#endif
842#ifdef FEATURE_WLAN_TDLS
843 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION) &&
844 (pCsrRoamInfo)) {
845 hddLog(LOG4,
846 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
847 pCsrRoamInfo->tdls_prohibited,
848 pCsrRoamInfo->tdls_chan_swit_prohibited);
849
850 wlan_hdd_update_tdls_info(pAdapter,
851 pCsrRoamInfo->tdls_prohibited,
852 pCsrRoamInfo->tdls_chan_swit_prohibited);
853 }
854#endif
855#ifdef MSM_PLATFORM
856 /* stop timer in sta/p2p_cli */
857 spin_lock_bh(&pHddCtx->bus_bw_lock);
858 pAdapter->prev_tx_packets = 0;
859 pAdapter->prev_rx_packets = 0;
860 spin_unlock_bh(&pHddCtx->bus_bw_lock);
861 hdd_stop_bus_bw_compute_timer(pAdapter);
862#endif
863 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800864 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800865 /* Send SCC/MCC Switching event to IPA */
866 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
867
868 msg = NULL;
869 /*During the WLAN uninitialization,supplicant is stopped before the
870 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800871 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800872 wireless_send_event(dev, we_event, &wrqu, msg);
873#ifdef FEATURE_WLAN_ESE
874 if (eConnectionState_Associated ==
875 pHddStaCtx->conn_info.connState) {
876 if ((pRoamProfile->AuthType.authType[0] ==
877 eCSR_AUTH_TYPE_CCKM_RSN) ||
878 (pRoamProfile->AuthType.authType[0] ==
879 eCSR_AUTH_TYPE_CCKM_WPA))
880 hdd_send_new_ap_channel_info(dev, pAdapter,
881 pCsrRoamInfo);
882 }
883#endif
884 }
885}
886
887/**
888 * hdd_conn_remove_connect_info() - remove connection info
889 * @pHddStaCtx: pointer to global HDD station context
890 * @pCsrRoamInfo: pointer to roam info
891 *
892 * Return: none
893 */
894static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
895{
896 /* Remove staId, bssId and peerMacAddress */
897 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530898 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
899 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530900 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800901
902 /* Clear all security settings */
903 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
904 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
905 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
906
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530907 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
908 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909
910 /* Set not-connected state */
911 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
912 pHddStaCtx->conn_info.proxyARPService = 0;
913
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530914 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800915}
916
917/**
918 * hdd_roam_deregister_sta() - deregister station
919 * @pAdapter: pointer to adapter
920 * @staId: station identifier
921 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530922 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800923 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530924static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800925hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
926{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530927 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800928 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
929
930 if (eConnectionState_IbssDisconnected ==
931 pHddStaCtx->conn_info.connState) {
932 /*
933 * Do not set the carrier off when the last peer leaves.
934 * We will set the carrier off while stopping the IBSS.
935 */
936 }
937
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530938 qdf_status = ol_txrx_clear_peer(staId);
939 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800940 hddLog(LOGE,
941 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530942 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800943 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530944 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800945}
946
947/**
948 * hdd_dis_connect_handler() - disconnect event handler
949 * @pAdapter: pointer to adapter
950 * @pRoamInfo: pointer to roam info
951 * @roamId: roam identifier
952 * @roamStatus: roam status
953 * @roamResult: roam result
954 *
955 * This function handles disconnect event:
956 * 1. Disable transmit queues;
957 * 2. Clean up internal connection states and data structures;
958 * 3. Send disconnect indication to supplicant.
959 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530960 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800961 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530962static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800963 tCsrRoamInfo *pRoamInfo,
964 uint32_t roamId,
965 eRoamCmdStatus roamStatus,
966 eCsrRoamResult roamResult)
967{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530968 QDF_STATUS status = QDF_STATUS_SUCCESS;
969 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800970 struct net_device *dev = pAdapter->dev;
971 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
972 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
973 uint8_t sta_id;
974 bool sendDisconInd = true;
975
976 if (dev == NULL) {
977 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530978 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800979 }
980 /* notify apps that we can't pass traffic anymore */
981 hddLog(LOG1, FL("Disabling queues"));
982 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
983 WLAN_CONTROL_PATH);
984
985 if (hdd_ipa_is_enabled(pHddCtx))
986 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
987 WLAN_STA_DISCONNECT,
988 pHddStaCtx->conn_info.bssId.bytes);
989
990#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
991 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
992#endif
993
994#ifdef QCA_PKT_PROTO_TRACE
995 /* STA disconnected, update into trace buffer */
996 if (pHddCtx->config->gEnableDebugLog)
997 cds_pkt_trace_buf_update("ST:DISASC");
998#endif /* QCA_PKT_PROTO_TRACE */
999
1000 /* HDD has initiated disconnect, do not send disconnect indication
1001 * to kernel. Sending disconnected event to kernel for userspace
1002 * initiated disconnect will be handled by hdd_DisConnectHandler call
1003 * to cfg80211_disconnected.
1004 */
1005 if ((eConnectionState_Disconnecting ==
1006 pHddStaCtx->conn_info.connState) ||
1007 (eConnectionState_NotConnected ==
1008 pHddStaCtx->conn_info.connState)) {
1009 hddLog(LOG1,
1010 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1011 sendDisconInd = false;
1012 }
1013
1014 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1015 INIT_COMPLETION(pAdapter->disconnect_comp_var);
1016 hddLog(LOG1,
1017 FL("Set HDD connState to eConnectionState_Disconnecting"));
1018 hdd_conn_set_connection_state(pAdapter,
1019 eConnectionState_Disconnecting);
1020 }
1021
1022 hdd_clear_roam_profile_ie(pAdapter);
1023 hdd_wmm_init(pAdapter);
1024
1025 /* indicate 'disconnect' status to wpa_supplicant... */
1026 hdd_send_association_event(dev, pRoamInfo);
1027 /* indicate disconnected event to nl80211 */
1028 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1029 /*
1030 * Only send indication to kernel if not initiated
1031 * by kernel
1032 */
1033 if (sendDisconInd) {
1034 /*
1035 * To avoid wpa_supplicant sending "HANGED" CMD
1036 * to ICS UI.
1037 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001038 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1039 if (pRoamInfo->reasonCode ==
1040 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1041 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001042 cfg80211_disconnected(dev, pRoamInfo->
Ryan Hsua335c162016-01-21 12:12:20 -08001043 reasonCode, NULL, 0,
1044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1045 true,
1046#endif
1047 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001048 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001049 cfg80211_disconnected(dev,
Ryan Hsua335c162016-01-21 12:12:20 -08001050 WLAN_REASON_UNSPECIFIED, NULL, 0,
1051#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1052 true,
1053#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001054 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001055 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001056
1057 hdd_info("sent disconnected event to nl80211, rssi: %d",
1058 pAdapter->rssi);
1059 }
1060 /*
1061 * During the WLAN uninitialization,supplicant is stopped
1062 * before the driver so not sending the status of the
1063 * connection to supplicant.
1064 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001065 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001066#ifdef WLAN_FEATURE_P2P_DEBUG
1067 if (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1068 if (global_p2p_connection_status ==
1069 P2P_CLIENT_CONNECTED_STATE_1) {
1070 global_p2p_connection_status =
1071 P2P_CLIENT_DISCONNECTED_STATE;
1072 hddLog(LOGE,
1073 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1074 } else if (global_p2p_connection_status ==
1075 P2P_CLIENT_COMPLETED_STATE) {
1076 global_p2p_connection_status =
1077 P2P_NOT_ACTIVE;
1078 hddLog(LOGE,
1079 "[P2P State] P2P Client is removed and moved to inactive state");
1080 }
1081 }
1082#endif
1083
1084 }
1085 }
1086
1087 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001088 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001089 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301090 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301091 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001092 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301093 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301094 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1095 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301096 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001097 }
1098 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301099 /* Clear all the peer sta register with TL. */
1100 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1101 if (0 == pHddStaCtx->conn_info.staId[i])
1102 continue;
1103 sta_id = pHddStaCtx->conn_info.staId[i];
1104 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1105 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301106 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301107 hddLog(LOGE,
1108 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1109 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301110 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301111 }
1112 /* set the staid and peer mac as 0, all other
1113 * reset are done in hdd_connRemoveConnectInfo.
1114 */
1115 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301116 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301117 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301118 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1119 pHddCtx->sta_to_adapter[sta_id] = NULL;
1120 }
1121 } else {
1122 sta_id = pHddStaCtx->conn_info.staId[0];
1123 /* We should clear all sta register with TL,
1124 * for now, only one.
1125 */
1126 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301127 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301128 hddLog(LOGE,
1129 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1130 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301131 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301132 }
1133 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001134 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001135 /* Clear saved connection information in HDD */
1136 hdd_conn_remove_connect_info(pHddStaCtx);
1137 hddLog(LOG1, FL("Set HDD connState to eConnectionState_NotConnected"));
1138 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1139#ifdef WLAN_FEATURE_GTK_OFFLOAD
1140 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1141 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1142 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1143 sizeof(tSirGtkOffloadParams));
1144 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1145 }
1146#endif
1147
1148#ifdef FEATURE_WLAN_TDLS
1149 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1150 wlan_hdd_tdls_disconnection_callback(pAdapter);
1151#endif
1152
1153 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1154 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) {
1155 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1156 (pAdapter),
1157 pAdapter->sessionId);
1158 }
1159 /* Unblock anyone waiting for disconnect to complete */
1160 complete(&pAdapter->disconnect_comp_var);
1161 return status;
1162}
1163
1164/**
1165 * hdd_set_peer_authorized_event() - set peer_authorized_event
1166 * @vdev_id: vdevid
1167 *
1168 * Return: None
1169 */
1170void hdd_set_peer_authorized_event(uint32_t vdev_id)
1171{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301172 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001173 hdd_adapter_t *adapter = NULL;
1174
1175 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1176 if (adapter == NULL) {
1177 hddLog(LOGE,
1178 "%s: Invalid vdev_id", __func__);
1179 }
1180 complete(&adapter->sta_authorized_event);
1181}
1182
1183/**
1184 * hdd_change_peer_state() - change peer state
1185 * @pAdapter: HDD adapter
1186 * @sta_state: peer state
1187 * @roam_synch_in_progress: roam synch in progress
1188 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301189 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001190 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301191QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001192 uint8_t sta_id,
1193 enum ol_txrx_peer_state sta_state,
1194 bool roam_synch_in_progress)
1195{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301196 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001197 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001198 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001199 ol_txrx_vdev_handle vdev;
1200 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001201
1202 if (!pdev) {
1203 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301204 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 }
1206
1207 if (sta_id >= WLAN_MAX_STA_COUNT) {
1208 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301209 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001210 }
1211
1212 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1213 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301214 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001215
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001216 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1217 if (peer_mac_addr == NULL) {
1218 hddLog(LOGE, "peer mac addr is NULL");
1219 return QDF_STATUS_E_FAULT;
1220 }
1221
1222 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301223 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001224 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301225 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001226 }
1227#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1228 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301229 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001230#endif
1231
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001232 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001233#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1234 /* make sure event is reset */
1235 INIT_COMPLETION(pAdapter->sta_authorized_event);
1236#endif
1237
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001238 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001239 hdd_set_peer_authorized_event,
1240 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301241 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001242 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301243 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001244 }
1245
1246 if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION ||
1247 pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) {
1248#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
1249 unsigned long rc;
1250
1251 /* wait for event from firmware to set the event */
1252 rc = wait_for_completion_timeout(
1253 &pAdapter->sta_authorized_event,
1254 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1255 if (!rc) {
1256 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1257 __func__);
1258 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001259 vdev = ol_txrx_get_vdev_for_peer(peer);
1260 ol_txrx_vdev_unpause(vdev,
1261 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001262#endif
1263 }
1264 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301265 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001266}
1267
1268/**
1269 * hdd_roam_register_sta() - register station
1270 * @pAdapter: pointer to adapter
1271 * @pRoamInfo: pointer to roam info
1272 * @staId: station identifier
1273 * @pPeerMacAddress: peer MAC address
1274 * @pBssDesc: pointer to BSS description
1275 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301276 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001277 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301278static QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001279 tCsrRoamInfo *pRoamInfo,
1280 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301281 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001282 tSirBssDescription *pBssDesc)
1283{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301284 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001285 struct ol_txrx_desc_type staDesc = { 0 };
1286 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001287 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001288
1289 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301290 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001291
1292 /* Get the Station ID from the one saved during the association */
1293 staDesc.sta_id = staId;
1294
1295 /* set the QoS field appropriately */
1296 if (hdd_wmm_is_active(pAdapter))
1297 staDesc.is_qos_enabled = 1;
1298 else
1299 staDesc.is_qos_enabled = 0;
1300
1301#ifdef FEATURE_WLAN_WAPI
1302 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1303 pAdapter->wapi_info.fIsWapiSta);
1304 if (pAdapter->wapi_info.fIsWapiSta)
1305 staDesc.is_wapi_supported = 1;
1306 else
1307 staDesc.is_wapi_supported = 0;
1308#endif /* FEATURE_WLAN_WAPI */
1309
Dhanashri Atre50141c52016-04-07 13:15:29 -07001310 /* Register the vdev transmit and receive functions */
1311 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1312 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1313 ol_txrx_vdev_register(
1314 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1315 pAdapter, &txrx_ops);
1316 pAdapter->tx_fn = txrx_ops.tx.tx;
1317
Dhanashri Atre182b0272016-02-17 15:35:07 -08001318 qdf_status = ol_txrx_register_peer(&staDesc);
1319
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301320 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001321 hddLog(LOGW,
1322 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301323 qdf_status, qdf_status);
1324 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001325 }
1326
1327 if (!pRoamInfo->fAuthRequired) {
1328 /*
1329 * Connections that do not need Upper layer auth, transition
1330 * TLSHIM directly to 'Authenticated' state
1331 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301332 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001334 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001335#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1336 pRoamInfo->roamSynchInProgress
1337#else
1338 false
1339#endif
1340 );
1341
1342 hdd_conn_set_authenticated(pAdapter, true);
1343 } else {
1344 hddLog(LOG3,
1345 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1346 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301347 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001348 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001349 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001350#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1351 pRoamInfo->roamSynchInProgress
1352#else
1353 false
1354#endif
1355 );
1356 hdd_conn_set_authenticated(pAdapter, false);
1357 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301358 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001359}
1360
1361/**
1362 * hdd_send_re_assoc_event() - send reassoc event
1363 * @dev: pointer to net device
1364 * @pAdapter: pointer to adapter
1365 * @pCsrRoamInfo: pointer to roam info
1366 * @reqRsnIe: pointer to RSN Information element
1367 * @reqRsnLength: length of RSN IE
1368 *
1369 * Return: none
1370 */
1371static void hdd_send_re_assoc_event(struct net_device *dev,
1372 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1373 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1374{
1375 unsigned int len = 0;
1376 u8 *pFTAssocRsp = NULL;
1377 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001378 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001379 uint32_t rspRsnLength = 0;
1380 struct ieee80211_channel *chan;
1381 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1382 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1383 uint8_t *buf_ptr, ssid_ie_len;
1384 struct cfg80211_bss *bss = NULL;
1385 uint8_t *final_req_ie = NULL;
1386 tCsrRoamConnectedProfile roam_profile;
1387 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1388
1389 if (!rspRsnIe) {
1390 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001391 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001392 }
1393
Naveen Rawat14298b92015-11-25 16:27:41 -08001394 if (!assoc_req_ies) {
1395 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001396 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001397 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001398 if (pCsrRoamInfo == NULL) {
1399 hddLog(LOGE, FL("Invalid CSR roam info"));
1400 goto done;
1401 }
1402
1403 if (pCsrRoamInfo->nAssocRspLength == 0) {
1404 hddLog(LOGE, FL("Invalid assoc response length"));
1405 goto done;
1406 }
1407
1408 pFTAssocRsp =
1409 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1410 pCsrRoamInfo->nAssocReqLength);
1411 if (pFTAssocRsp == NULL)
1412 goto done;
1413
1414 /* pFTAssocRsp needs to point to the IEs */
1415 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1416 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1417 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1418
1419 /*
1420 * Active session count is decremented upon disconnection, but during
1421 * roaming, there is no disconnect indication and hence active session
1422 * count is not decremented.
1423 * After roaming is completed, active session count is incremented
1424 * as a part of connect indication but effectively after roaming the
1425 * active session count should still be the same and hence upon
1426 * successful reassoc decrement the active session count here.
1427 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001428 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05301429 cds_decr_session_set_pcl(pAdapter->device_mode,
1430 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001431
1432 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1433 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1434 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301435 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1436 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001437
1438 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1439 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301440 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001441 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1442 &roam_profile);
1443 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1444 pCsrRoamInfo->bssid.bytes,
1445 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001446#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001447 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001448#else
1449 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1450#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001451
1452 if (bss == NULL)
1453 hddLog(LOGE, FL("Get BSS returned NULL"));
1454 buf_ptr = buf_ssid_ie;
1455 *buf_ptr = SIR_MAC_SSID_EID;
1456 buf_ptr++;
1457 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1458 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301459 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001460 roam_profile.SSID.length);
1461 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001462 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301463 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001464 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1466 if (final_req_ie == NULL)
1467 goto done;
1468 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301469 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001470 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301471 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1472 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1473 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001474 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001475 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301476 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001477 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001478 cfg80211_roamed_bss(dev, bss,
1479 final_req_ie, (ssid_ie_len + reqRsnLength),
1480 rspRsnIe, rspRsnLength, GFP_KERNEL);
1481
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301482 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001483 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1484 pCsrRoamInfo->nAssocReqLength);
1485
1486 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301487 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001488 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1489
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001490 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001491 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1492 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001493 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001494done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001495 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001496 if (final_req_ie)
1497 kfree(final_req_ie);
1498 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001499 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001500}
1501
1502/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301503 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001504 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301505 *
1506 * Return: roam sync status if roaming offloaded else false
1507 */
1508#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001509bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301510{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001511 if (roaminfo)
1512 return roaminfo->roamSynchInProgress;
1513 else
1514 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301515}
1516#endif
1517
1518
1519/**
1520 * hdd_change_sta_state_authenticated()-
1521 * This function changes STA state to authenticated
1522 * @adapter: pointer to the adapter structure.
1523 * @roaminfo: pointer to the RoamInfo structure.
1524 *
1525 * This is called from hdd_RoamSetKeyCompleteHandler
1526 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1527 *
1528 * Return: 0 on success and errno on failure
1529 */
1530static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1531 tCsrRoamInfo *roaminfo)
1532{
1533 int ret;
1534 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1535
1536 hddLog(LOG1,
1537 "Changing TL state to AUTHENTICATED for StaId= %d",
1538 hddstactx->conn_info.staId[0]);
1539
1540 /* Connections that do not need Upper layer authentication,
1541 * transition TL to 'Authenticated' state after the keys are set
1542 */
1543 ret = hdd_change_peer_state(adapter,
1544 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001545 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301546 hdd_is_roam_sync_in_progress(roaminfo));
1547 hdd_conn_set_authenticated(adapter, true);
1548 if ((WLAN_HDD_INFRA_STATION == adapter->device_mode) ||
1549 (WLAN_HDD_P2P_CLIENT == adapter->device_mode)) {
1550 sme_ps_enable_auto_ps_timer(
1551 WLAN_HDD_GET_HAL_CTX(adapter),
1552 adapter->sessionId,
1553 hddstactx->hdd_ReassocScenario);
1554 }
1555
1556 return ret;
1557}
1558
1559/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001560 * hdd_roam_set_key_complete_handler() - Update the security parameters
1561 * @pAdapter: pointer to adapter
1562 * @pRoamInfo: pointer to roam info
1563 * @roamId: roam id
1564 * @roamStatus: roam status
1565 * @roamResult: roam result
1566 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301567 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001568 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301569static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001570 tCsrRoamInfo *pRoamInfo,
1571 uint32_t roamId,
1572 eRoamCmdStatus roamStatus,
1573 eCsrRoamResult roamResult)
1574{
1575 eCsrEncryptionType connectedCipherAlgo;
1576 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301577 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001578 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1579 ENTER();
1580
1581 if (NULL == pRoamInfo) {
1582 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301583 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001584 }
1585 /*
1586 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1587 * then go to 'authenticated'. For all other authentication types
1588 * (those that do not require upper layer authentication) we can put TL
1589 * directly into 'authenticated' state.
1590 */
1591 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1592 MAC_ADDRESS_STR, roamStatus, roamResult,
1593 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1594
1595 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1596 &connectedCipherAlgo);
1597 if (fConnected) {
1598 if (WLAN_HDD_IBSS == pAdapter->device_mode) {
1599 uint8_t staId;
1600
Anurag Chouhanc5548422016-02-24 18:33:27 +05301601 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001602 pHddStaCtx->roam_info.roamingState =
1603 HDD_ROAM_STATE_NONE;
1604 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301605 qdf_status = hdd_ibss_get_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001606 pHddStaCtx,
1607 &pRoamInfo->peerMac,
1608 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301609 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001610 hddLog(LOG2,
1611 "WLAN TL STA Ptk Installed for STAID=%d",
1612 staId);
1613 pHddStaCtx->roam_info.roamingState =
1614 HDD_ROAM_STATE_NONE;
1615 }
1616 }
1617 } else {
1618 /*
1619 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301620 * HDD later.This routine is invoked twice.
1621 * 1)set PTK 2)set GTK.The following if
1622 * statement will be TRUE when setting GTK.
1623 * At this time we don't handle the state in detail.
1624 * Related CR: 174048 - TL not in authenticated state
1625 */
1626 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult)
1627 pHddStaCtx->conn_info.gtk_installed = true;
1628 else
1629 pHddStaCtx->conn_info.ptk_installed = true;
1630
1631 /* In WPA case move STA to authenticated when
1632 * ptk is installed.Earlier in WEP case STA
1633 * was moved to AUTHENTICATED prior to setting
1634 * the unicast key and it was resulting in sending
1635 * few un-encrypted packet. Now in WEP case
1636 * STA state will be moved to AUTHENTICATED
1637 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001638 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301639 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1640 eCSR_ENCRYPT_TYPE_WEP40) ||
1641 (pHddStaCtx->conn_info.ucEncryptionType ==
1642 eCSR_ENCRYPT_TYPE_WEP104) ||
1643 (pHddStaCtx->conn_info.ucEncryptionType ==
1644 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1645 (pHddStaCtx->conn_info.ucEncryptionType ==
1646 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1647 if (pHddStaCtx->conn_info.gtk_installed &&
1648 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301649 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301650 hdd_change_sta_state_authenticated(pAdapter,
1651 pRoamInfo);
1652 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301653 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301654 hdd_change_sta_state_authenticated(pAdapter,
1655 pRoamInfo);
1656 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001657
Govind Singhedc5cda2015-10-23 17:11:35 +05301658 if (pHddStaCtx->conn_info.gtk_installed &&
1659 pHddStaCtx->conn_info.ptk_installed) {
1660 pHddStaCtx->conn_info.gtk_installed = false;
1661 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001662 }
1663
1664 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301665 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001666 }
1667 } else {
1668 /*
1669 * possible disassoc after issuing set key and waiting
1670 * set key complete.
1671 */
1672 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1673 }
1674
1675 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301676 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001677}
1678
1679/**
1680 * hdd_perform_roam_set_key_complete() - perform set key complete
1681 * @pAdapter: pointer to adapter
1682 *
1683 * Return: none
1684 */
1685void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1686{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301687 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001688 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1689 tCsrRoamInfo roamInfo;
1690 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301691 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301692 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301693 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301694 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001695
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301696 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001697 hdd_roam_set_key_complete_handler(pAdapter,
1698 &roamInfo,
1699 pHddStaCtx->roam_info.roamId,
1700 pHddStaCtx->roam_info.roamStatus,
1701 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301702 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001703 hddLog(LOGE, FL("Set Key complete failure"));
1704
1705 pHddStaCtx->roam_info.deferKeyComplete = false;
1706}
1707
1708/**
1709 * hdd_association_completion_handler() - association completion handler
1710 * @pAdapter: pointer to adapter
1711 * @pRoamInfo: pointer to roam info
1712 * @roamId: roam id
1713 * @roamStatus: roam status
1714 * @roamResult: roam result
1715 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301716 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001717 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301718static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001719 tCsrRoamInfo *pRoamInfo,
1720 uint32_t roamId,
1721 eRoamCmdStatus roamStatus,
1722 eCsrRoamResult roamResult)
1723{
1724 struct net_device *dev = pAdapter->dev;
1725 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1726 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301727 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001728 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1729 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001730 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001731 bool hddDisconInProgress = false;
1732 unsigned long rc;
1733
1734 if (!pHddCtx) {
1735 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301736 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001737 }
1738
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001739 /* HDD has initiated disconnect, do not send connect result indication
1740 * to kernel as it will be handled by __cfg80211_disconnect.
1741 */
1742 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1743 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1744 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1745 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1746 hddDisconInProgress = true;
1747 }
1748
1749 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1750 if (NULL == pRoamInfo) {
1751 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301752 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001753 }
1754 if (!hddDisconInProgress) {
1755 hddLog(LOG1, FL("Set HDD connState to eConnectionState_Associated"));
1756 hdd_conn_set_connection_state(pAdapter,
1757 eConnectionState_Associated);
1758 }
1759 /* Save the connection info from CSR... */
1760 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1761 eCSR_BSS_TYPE_INFRASTRUCTURE);
1762#ifdef FEATURE_WLAN_WAPI
1763 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1764 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1765 || pRoamInfo->u.pConnectedProfile->AuthType ==
1766 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1767 pAdapter->wapi_info.fIsWapiSta = 1;
1768 } else {
1769 pAdapter->wapi_info.fIsWapiSta = 0;
1770 }
1771#endif /* FEATURE_WLAN_WAPI */
1772
1773 /* Indicate 'connect' status to user space */
1774 hdd_send_association_event(dev, pRoamInfo);
1775
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001776 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001777 if (pHddCtx->miracast_value)
1778 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1779 }
1780
1781 /* Initialize the Linkup event completion variable */
1782 INIT_COMPLETION(pAdapter->linkup_event_var);
1783
1784 /*
1785 * Sometimes Switching ON the Carrier is taking time to activate
1786 * the device properly. Before allowing any packet to go up to
1787 * the application, device activation has to be ensured for
1788 * proper queue mapping by the kernel. we have registered net
1789 * device notifier for device change notification. With this we
1790 * will come to know that the device is getting
1791 * activated properly.
1792 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001793 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001794 /*
1795 * Enable Linkup Event Servicing which allows the net
1796 * device notifier to set the linkup event variable.
1797 */
1798 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001799
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001800 /* Switch on the Carrier to activate the device */
1801 wlan_hdd_netif_queue_control(pAdapter,
1802 WLAN_NETIF_CARRIER_ON,
1803 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001804
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001805 /*
1806 * Wait for the Link to up to ensure all the queues
1807 * are set properly by the kernel.
1808 */
1809 rc = wait_for_completion_timeout(
1810 &pAdapter->linkup_event_var,
1811 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1812 );
1813 if (!rc)
1814 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001815
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001816 /*
1817 * Disable Linkup Event Servicing - no more service
1818 * required from the net device notifier call.
1819 */
1820 pAdapter->isLinkUpSvcNeeded = false;
1821 } else {
1822 pHddStaCtx->ft_carrier_on = false;
1823 ft_carrier_on = true;
1824 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001825 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1826 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1827 else
1828 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1829 pRoamInfo->staId);
1830
1831 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1832
1833 if (hdd_ipa_is_enabled(pHddCtx))
1834 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1835 WLAN_STA_CONNECT,
1836 pRoamInfo->bssid.bytes);
1837
1838#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1839 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1840#endif
1841
Chandrasekaran Manishekar068e25e2016-03-07 11:51:07 +05301842 hdd_info("check for SAP restart");
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001843 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001844 pAdapter);
1845
1846#ifdef FEATURE_WLAN_TDLS
1847 wlan_hdd_tdls_connection_callback(pAdapter);
1848#endif
1849
1850#ifdef QCA_PKT_PROTO_TRACE
1851 /* STA Associated, update into trace buffer */
1852 if (pHddCtx->config->gEnableDebugLog)
1853 cds_pkt_trace_buf_update("ST:ASSOC");
1854#endif /* QCA_PKT_PROTO_TRACE */
1855 /*
1856 * For reassoc, the station is already registered, all we need
1857 * is to change the state of the STA in TL.
1858 * If authentication is required (WPA/WPA2/DWEP), change TL to
1859 * CONNECTED instead of AUTHENTICATED.
1860 */
1861 if (!pRoamInfo->fReassocReq) {
1862 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001863 u8 *pFTAssocRsp = NULL;
1864 unsigned int assocRsplen = 0;
1865 u8 *pFTAssocReq = NULL;
1866 unsigned int assocReqlen = 0;
1867 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001868 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1869 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1870
1871 /* add bss_id to cfg80211 data base */
1872 bss =
1873 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1874 pRoamInfo);
1875 if (NULL == bss) {
1876 pr_err("wlan: Not able to create BSS entry\n");
1877 wlan_hdd_netif_queue_control(pAdapter,
1878 WLAN_NETIF_CARRIER_OFF,
1879 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301880 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001881 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001882 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1883 eCSR_AUTH_TYPE_FT_RSN
1884 || pRoamInfo->u.pConnectedProfile->AuthType ==
1885 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1886
1887 /* Association Response */
1888 pFTAssocRsp =
1889 (u8 *) (pRoamInfo->pbFrames +
1890 pRoamInfo->nBeaconLength +
1891 pRoamInfo->nAssocReqLength);
1892 if (pFTAssocRsp != NULL) {
1893 /*
1894 * pFTAssocRsp needs to point to the IEs
1895 */
1896 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1897 hddLog(LOG1,
1898 FL("AssocRsp is now at %02x%02x"),
1899 (unsigned int)pFTAssocRsp[0],
1900 (unsigned int)pFTAssocRsp[1]);
1901 assocRsplen =
1902 pRoamInfo->nAssocRspLength -
1903 FT_ASSOC_RSP_IES_OFFSET;
1904 } else {
1905 hddLog(LOGE, FL("AssocRsp is NULL"));
1906 assocRsplen = 0;
1907 }
1908
1909 /* Association Request */
1910 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1911 pRoamInfo->nBeaconLength);
1912 if (pFTAssocReq != NULL) {
1913 if (!ft_carrier_on) {
1914 /*
1915 * pFTAssocReq needs to point to
1916 * the IEs
1917 */
1918 pFTAssocReq +=
1919 FT_ASSOC_REQ_IES_OFFSET;
1920 hddLog(LOG1,
1921 FL("pFTAssocReq is now at %02x%02x"),
1922 (unsigned int)
1923 pFTAssocReq[0],
1924 (unsigned int)
1925 pFTAssocReq[1]);
1926 assocReqlen =
1927 pRoamInfo->nAssocReqLength -
1928 FT_ASSOC_REQ_IES_OFFSET;
1929 } else {
1930 /*
1931 * This should contain only the
1932 * FTIEs
1933 */
1934 assocReqlen =
1935 pRoamInfo->nAssocReqLength;
1936 }
1937 } else {
1938 hddLog(LOGE, FL("AssocReq is NULL"));
1939 assocReqlen = 0;
1940 }
1941
1942 if (ft_carrier_on) {
1943 if (!hddDisconInProgress) {
1944 /*
1945 * After roaming is completed,
1946 * active session count is
1947 * incremented as a part of
1948 * connect indication but
1949 * effectively the active
1950 * session count should still
1951 * be the same and hence upon
1952 * successful reassoc
1953 * decrement the active session
1954 * count here.
1955 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001956 if (!hdd_is_roam_sync_in_progress
1957 (pRoamInfo))
1958 cds_decr_session_set_pcl
1959 (pAdapter->device_mode,
1960 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001961 hddLog(LOG1,
1962 FL("ft_carrier_on is %d, sending roamed indication"),
1963 ft_carrier_on);
1964 chan =
1965 ieee80211_get_channel
1966 (pAdapter->wdev.wiphy,
1967 (int)pRoamInfo->pBssDesc->
1968 channelId);
1969 hddLog(LOG1,
1970 "assocReqlen %d assocRsplen %d",
1971 assocReqlen,
1972 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08001973
1974 hdd_notice(
1975 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301976 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05301977 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301978 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001979 pFTAssocReq,
1980 assocReqlen);
1981
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001982 cfg80211_roamed(dev, chan,
1983 pRoamInfo->
1984 bssid.bytes,
1985 pFTAssocReq,
1986 assocReqlen,
1987 pFTAssocRsp,
1988 assocRsplen,
1989 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001990 wlan_hdd_send_roam_auth_event(
1991 pHddCtx,
1992 pRoamInfo->bssid.bytes,
1993 pFTAssocReq,
1994 assocReqlen,
1995 pFTAssocRsp,
1996 assocRsplen,
1997 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001998 }
1999 if (sme_get_ftptk_state
2000 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2001 pAdapter->sessionId)) {
2002 sme_set_ftptk_state
2003 (WLAN_HDD_GET_HAL_CTX
2004 (pAdapter),
2005 pAdapter->sessionId,
2006 false);
2007 pRoamInfo->fAuthRequired =
2008 false;
2009
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302010 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002011 roam_info.bssid,
2012 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302013 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302014 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002015 roam_info.peerMac,
2016 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302017 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002018 pHddStaCtx->roam_info.roamId =
2019 roamId;
2020 pHddStaCtx->roam_info.
2021 roamStatus = roamStatus;
2022 pHddStaCtx->roam_info.
2023 deferKeyComplete = true;
2024 }
2025 } else if (!hddDisconInProgress) {
2026 hddLog(LOG1,
2027 FL("ft_carrier_on is %d, sending connect indication"),
2028 ft_carrier_on);
2029 cfg80211_connect_result(dev,
2030 pRoamInfo->
2031 bssid.bytes,
2032 pFTAssocReq,
2033 assocReqlen,
2034 pFTAssocRsp,
2035 assocRsplen,
2036 WLAN_STATUS_SUCCESS,
2037 GFP_KERNEL);
2038 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002039 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002040 /*
2041 * wpa supplicant expecting WPA/RSN IE in
2042 * connect result.
2043 */
2044 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2045 (pAdapter),
2046 pAdapter->sessionId,
2047 &reqRsnLength,
2048 reqRsnIe);
2049
2050 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2051 (pAdapter),
2052 pAdapter->sessionId,
2053 &rspRsnLength,
2054 rspRsnIe);
2055 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002056 if (ft_carrier_on)
2057 hdd_send_re_assoc_event(dev,
2058 pAdapter,
2059 pRoamInfo,
2060 reqRsnIe,
2061 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002062 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002063 hddLog(LOG1,
2064 FL("sending connect indication to nl80211:for bssid "
2065 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302066 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002067 MAC_ADDR_ARRAY
2068 (pRoamInfo->bssid.bytes),
2069 roamResult, roamStatus);
2070
2071 /* inform connect result to nl80211 */
2072 cfg80211_connect_result(dev,
2073 pRoamInfo->
2074 bssid.bytes,
2075 reqRsnIe,
2076 reqRsnLength,
2077 rspRsnIe,
2078 rspRsnLength,
2079 WLAN_STATUS_SUCCESS,
2080 GFP_KERNEL);
2081 }
2082 }
2083 }
2084 if (!hddDisconInProgress) {
2085 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002086 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002087 bss);
2088
2089 /*
2090 * Perform any WMM-related association
2091 * processing.
2092 */
2093 hdd_wmm_assoc(pAdapter, pRoamInfo,
2094 eCSR_BSS_TYPE_INFRASTRUCTURE);
2095
2096 /*
2097 * Start the Queue - Start tx queues before
2098 * hdd_roam_register_sta, since
2099 * hdd_roam_register_sta will flush any cached
2100 * data frames immediately.
2101 */
2102 hddLog(LOG1, FL("Enabling queues"));
2103 wlan_hdd_netif_queue_control(pAdapter,
2104 WLAN_WAKE_ALL_NETIF_QUEUE,
2105 WLAN_CONTROL_PATH);
2106
2107 /*
2108 * Register the Station with TL after associated
2109 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302110 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002111 pRoamInfo,
2112 pHddStaCtx->
2113 conn_info.
2114 staId[0],
2115 NULL,
2116 pRoamInfo->
2117 pBssDesc);
2118 }
2119 } else {
2120 /*
2121 * wpa supplicant expecting WPA/RSN IE in connect result
2122 * in case of reassociation also need to indicate it to
2123 * supplicant.
2124 */
2125 csr_roam_get_wpa_rsn_req_ie(
2126 WLAN_HDD_GET_HAL_CTX(pAdapter),
2127 pAdapter->sessionId,
2128 &reqRsnLength, reqRsnIe);
2129
2130 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2131 reqRsnIe, reqRsnLength);
2132 /* Reassoc successfully */
2133 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302134 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002135 hdd_change_peer_state(pAdapter,
2136 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002137 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002138#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2139 pRoamInfo->roamSynchInProgress
2140#else
2141 false
2142#endif
2143 );
2144 hdd_conn_set_authenticated(pAdapter, false);
2145 } else {
2146 hddLog(LOG2,
2147 FL("staId: %d Changing TL state to AUTHENTICATED"),
2148 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302149 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002150 hdd_change_peer_state(pAdapter,
2151 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002152 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002153#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2154 pRoamInfo->roamSynchInProgress
2155#else
2156 false
2157#endif
2158 );
2159 hdd_conn_set_authenticated(pAdapter, true);
2160 }
2161
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302162 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002163 /*
2164 * Perform any WMM-related association
2165 * processing
2166 */
2167 hdd_wmm_assoc(pAdapter, pRoamInfo,
2168 eCSR_BSS_TYPE_INFRASTRUCTURE);
2169 }
2170
2171 /* Start the tx queues */
2172#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2173 if (pRoamInfo->roamSynchInProgress)
2174 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2175#endif
2176 hddLog(LOG1, FL("Enabling queues"));
2177 wlan_hdd_netif_queue_control(pAdapter,
2178 WLAN_WAKE_ALL_NETIF_QUEUE,
2179 WLAN_CONTROL_PATH);
2180 }
2181
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302182 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002183 hddLog(LOGE,
2184 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302185 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002186 }
2187#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302188 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002189 sizeof(pAdapter->hdd_stats.hddPmfStats));
2190#endif
2191 } else {
2192 hdd_wext_state_t *pWextState =
2193 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2194 if (pRoamInfo)
2195 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302196 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002197 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2198 roamResult, roamStatus);
2199 else
2200 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302201 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002202 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2203 roamResult, roamStatus);
2204
2205 /*
2206 * CR465478: Only send up a connection failure result when CSR
2207 * has completed operation - with a ASSOCIATION_FAILURE status.
2208 */
2209 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2210 && !hddDisconInProgress) {
2211 if (pRoamInfo)
2212 hddLog(LOGE,
2213 FL("send connect failure to nl80211: for bssid "
2214 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302215 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002216 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302217 roamResult, roamStatus,
2218 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002219 else
2220 hddLog(LOGE,
2221 FL("connect failed: for bssid "
2222 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302223 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002224 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2225 roamResult, roamStatus);
2226
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002227 /* inform association failure event to nl80211 */
2228 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2229 roamResult) {
2230 if (pRoamInfo)
2231 cfg80211_connect_result(dev,
2232 pRoamInfo->bssid.bytes,
2233 NULL, 0, NULL, 0,
2234 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2235 GFP_KERNEL);
2236 else
2237 cfg80211_connect_result(dev,
2238 pWextState->req_bssId.bytes,
2239 NULL, 0, NULL, 0,
2240 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2241 GFP_KERNEL);
2242 } else {
2243 if (pRoamInfo) {
2244 eCsrAuthType authType =
2245 pWextState->roamProfile.AuthType.
2246 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302247 eCsrEncryptionType encryption_type =
2248 pWextState->roamProfile.
2249 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002250 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302251 (((authType ==
2252 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002253 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302254 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2255 ((encryption_type ==
2256 eCSR_ENCRYPT_TYPE_WEP40) ||
2257 (encryption_type ==
2258 eCSR_ENCRYPT_TYPE_WEP104) ||
2259 (encryption_type ==
2260 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2261 (encryption_type ==
2262 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002263 /*
2264 * In case of OPEN-WEP or SHARED-WEP
2265 * authentication, send exact protocol
2266 * reason code. This enables user
2267 * applications to reconnect the station
2268 * with correct configuration.
2269 */
2270 cfg80211_connect_result(dev,
2271 pRoamInfo->bssid.bytes, NULL, 0,
2272 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302273 (isWep &&
2274 pRoamInfo->reasonCode) ?
2275 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002276 WLAN_STATUS_UNSPECIFIED_FAILURE,
2277 GFP_KERNEL);
2278 } else
2279 cfg80211_connect_result(dev,
2280 pWextState->req_bssId.bytes,
2281 NULL, 0, NULL, 0,
2282 WLAN_STATUS_UNSPECIFIED_FAILURE,
2283 GFP_KERNEL);
2284 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302285 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002286 }
2287
2288 if (pRoamInfo) {
2289 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2290 pRoamInfo->statusCode)
2291 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2292 pRoamInfo->statusCode)
2293 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2294 pRoamInfo->statusCode)) {
2295 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2296 pRoamInfo);
2297 }
2298 }
2299
2300 /*
2301 * Set connection state to eConnectionState_NotConnected only
2302 * when CSR has completed operation - with a
2303 * ASSOCIATION_FAILURE status.
2304 */
2305 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2306 && !hddDisconInProgress) {
2307 hddLog(LOG1,
2308 FL("state to eConnectionState_NotConnected"));
2309 hdd_conn_set_connection_state(pAdapter,
2310 eConnectionState_NotConnected);
2311 }
2312 hdd_wmm_init(pAdapter);
2313
2314 hddLog(LOG1, FL("Disabling queues"));
2315 wlan_hdd_netif_queue_control(pAdapter,
2316 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2317 WLAN_CONTROL_PATH);
2318 }
2319
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302320 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002321 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302322 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002323
Govind Singh24db1ed2015-12-18 15:54:59 +05302324 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2325 cds_force_sap_on_scc(roamResult,
2326 pRoamInfo->pBssDesc->channelId);
2327 } else {
2328 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302329 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302330 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002331
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302332 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002333}
2334
2335/**
2336 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2337 * @pAdapter: pointer to adapter
2338 * @pRoamInfo: pointer to roam info
2339 * @roamId: roam id
2340 * @roamStatus: roam status
2341 * @roamResult: roam result
2342 *
2343 * Here we update the status of the Ibss when we receive information that we
2344 * have started/joined an ibss session.
2345 *
2346 * Return: none
2347 */
2348static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2349 tCsrRoamInfo *pRoamInfo,
2350 uint32_t roamId,
2351 eRoamCmdStatus roamStatus,
2352 eCsrRoamResult roamResult)
2353{
2354 hddLog(LOG1, "%s: id %d, status %d, result %d",
2355 pAdapter->dev->name, roamId, roamStatus, roamResult);
2356
2357 switch (roamResult) {
2358 /* both IBSS Started and IBSS Join should come in here. */
2359 case eCSR_ROAM_RESULT_IBSS_STARTED:
2360 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2361 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2362 {
2363 hdd_context_t *pHddCtx =
2364 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302365 hdd_station_ctx_t *hdd_sta_ctx =
2366 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302367 struct qdf_mac_addr broadcastMacAddr =
2368 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002369
2370 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302371 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002372 return;
2373 }
2374
2375 /* When IBSS Started comes from CSR, we need to move
2376 * connection state to IBSS Disconnected (meaning no peers
2377 * are in the IBSS).
2378 */
2379 hddLog(LOG1,
2380 FL("Set HDD connState to eConnectionState_IbssDisconnected"));
2381 hdd_conn_set_connection_state(pAdapter,
2382 eConnectionState_IbssDisconnected);
2383 /* notify wmm */
2384 hdd_wmm_connect(pAdapter, pRoamInfo,
2385 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302386
2387 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2388
2389 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002390 pAdapter;
2391 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302392 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002393 &broadcastMacAddr,
2394 pRoamInfo->pBssDesc);
2395
2396 if (pRoamInfo->pBssDesc) {
2397 struct cfg80211_bss *bss;
2398#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2399 struct ieee80211_channel *chan;
2400 int chan_no;
2401 unsigned int freq;
2402#endif
2403 /* we created the IBSS, notify supplicant */
2404 hddLog(LOG1,
2405 FL("%s: created ibss " MAC_ADDRESS_STR),
2406 pAdapter->dev->name,
2407 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2408
2409 /* we must first give cfg80211 the BSS information */
2410 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2411 pRoamInfo);
2412 if (NULL == bss) {
2413 hddLog(LOGE,
2414 FL("%s: unable to create IBSS entry"),
2415 pAdapter->dev->name);
2416 return;
2417 }
2418 hddLog(LOG1, FL("Enabling queues"));
2419 wlan_hdd_netif_queue_control(pAdapter,
2420 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2421 WLAN_CONTROL_PATH);
2422
2423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2424 chan_no = pRoamInfo->pBssDesc->channelId;
2425
2426 if (chan_no <= 14)
2427 freq = ieee80211_channel_to_frequency(chan_no,
2428 IEEE80211_BAND_2GHZ);
2429 else
2430 freq = ieee80211_channel_to_frequency(chan_no,
2431 IEEE80211_BAND_5GHZ);
2432
2433 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2434
2435 if (chan)
2436 cfg80211_ibss_joined(pAdapter->dev,
2437 bss->bssid, chan,
2438 GFP_KERNEL);
2439 else
2440 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2441 pAdapter->dev->name,
2442 (int)pRoamInfo->pBssDesc->channelId);
2443#else
2444 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2445 GFP_KERNEL);
2446#endif
2447 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002448 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002449 bss);
2450 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002451 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002452 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002453 pAdapter->sessionId);
2454 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2455 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002456 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002457 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002458 break;
2459 }
2460
2461 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2462 {
2463 hddLog(LOGE,
2464 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2465 break;
2466 }
2467
2468 default:
2469 hddLog(LOGE, FL("%s: unexpected result %d"),
2470 pAdapter->dev->name, (int)roamResult);
2471 break;
2472 }
2473
2474 return;
2475}
2476
2477/**
2478 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2479 * @pHddStaCtx: pointer to global HDD station context
2480 * @staId: station id
2481 * @peerMacAddress: pointer to peer MAC address
2482 *
2483 * This information is passed to iwconfig later. The peer that joined
2484 * last is passed as information to iwconfig.
2485 *
2486 * Return:
2487 * true if we add MAX_IBSS_PEERS or less STA
2488 * false otherwise.
2489 */
2490static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302491 struct qdf_mac_addr *peerMacAddress)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002492{
2493 bool fSuccess = false;
2494 int idx = 0;
2495
2496 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2497 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2498 pHddStaCtx->conn_info.staId[idx] = staId;
2499
Anurag Chouhanc5548422016-02-24 18:33:27 +05302500 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002501 peerMacAddress[idx], peerMacAddress);
2502
2503 fSuccess = true;
2504 break;
2505 }
2506 }
2507
2508 return fSuccess;
2509}
2510
2511/**
2512 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2513 * @pAdapter: pointer to adapter
2514 * @staId: station id
2515 *
2516 * Return:
2517 * true if we remove MAX_IBSS_PEERS or less STA
2518 * false otherwise.
2519 */
2520static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2521{
2522 bool fSuccess = false;
2523 int idx = 0;
2524 uint8_t valid_idx = 0;
2525 uint8_t del_idx = 0;
2526 uint8_t empty_slots = 0;
2527 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2528
2529 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2530 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2531 pHddStaCtx->conn_info.staId[idx] = 0;
2532
Anurag Chouhanc5548422016-02-24 18:33:27 +05302533 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002534 peerMacAddress[idx]);
2535
2536 fSuccess = true;
2537
2538 /*
2539 * Note the deleted Index, if its 0 we need special
2540 * handling.
2541 */
2542 del_idx = idx;
2543
2544 empty_slots++;
2545 } else {
2546 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2547 valid_idx = idx;
2548 } else {
2549 /* Found an empty slot */
2550 empty_slots++;
2551 }
2552 }
2553 }
2554
2555 if (MAX_IBSS_PEERS == empty_slots) {
2556 /* Last peer departed, set the IBSS state appropriately */
2557 pHddStaCtx->conn_info.connState =
2558 eConnectionState_IbssDisconnected;
2559 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2560 }
2561 /* Find next active staId, to have a valid sta trigger for TL. */
2562 if (fSuccess == true) {
2563 if (del_idx == 0) {
2564 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2565 pHddStaCtx->conn_info.staId[0] =
2566 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302567 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002568 peerMacAddress[0],
2569 &pHddStaCtx->conn_info.
2570 peerMacAddress[valid_idx]);
2571
2572 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302573 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002574 peerMacAddress[valid_idx]);
2575 }
2576 }
2577 }
2578 return fSuccess;
2579}
2580
2581/**
2582 * roam_ibss_connect_handler() - IBSS connection handler
2583 * @pAdapter: pointer to adapter
2584 * @pRoamInfo: pointer to roam info
2585 *
2586 * We update the status of the IBSS to connected in this function.
2587 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302588 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002589 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302590static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002591 tCsrRoamInfo *pRoamInfo)
2592{
2593 struct cfg80211_bss *bss;
2594 hddLog(LOG1, FL("IBSS Connect Indication from SME. Set HDD connState to eConnectionState_IbssConnected"));
2595 /*
2596 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2597 * a partner stations).
2598 */
2599 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2600
2601 /* Save the connection info from CSR... */
2602 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2603
2604 /* Send the bssid address to the wext. */
2605 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2606 /* add bss_id to cfg80211 data base */
2607 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2608 if (NULL == bss) {
2609 hddLog(LOGE,
2610 FL("%s: unable to create IBSS entry"),
2611 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302612 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002613 }
2614 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002615 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002616 bss);
2617
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302618 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002619}
2620
2621/**
2622 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2623 * @pAdapter: pointer to adapter
2624 * @pRoamInfo: pointer to roam info
2625 * @roamId: roam id
2626 * @roamStatus: roam status
2627 * @roamResult: roam result
2628 *
2629 * This function indicates the Mic failure to the supplicant
2630 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302631 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002632 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302633static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002634hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2635 tCsrRoamInfo *pRoamInfo,
2636 uint32_t roamId,
2637 eRoamCmdStatus roamStatus,
2638 eCsrRoamResult roamResult)
2639{
2640 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2641
2642 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2643 TKIP_COUNTER_MEASURE_STOPED ==
2644 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2645 struct iw_michaelmicfailure msg;
2646 union iwreq_data wreq;
2647 memset(&msg, '\0', sizeof(msg));
2648 msg.src_addr.sa_family = ARPHRD_ETHER;
2649 memcpy(msg.src_addr.sa_data,
2650 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2651 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2652 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2653 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2654
2655 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2656 msg.flags = IW_MICFAILURE_GROUP;
2657 else
2658 msg.flags = IW_MICFAILURE_PAIRWISE;
2659 memset(&wreq, 0, sizeof(wreq));
2660 wreq.data.length = sizeof(msg);
2661 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2662 (char *)&msg);
2663 /* inform mic failure to nl80211 */
2664 cfg80211_michael_mic_failure(pAdapter->dev,
2665 pRoamInfo->u.pMICFailureInfo->
2666 taMacAddr,
2667 ((pRoamInfo->u.pMICFailureInfo->
2668 multicast ==
2669 eSIR_TRUE) ?
2670 NL80211_KEYTYPE_GROUP :
2671 NL80211_KEYTYPE_PAIRWISE),
2672 pRoamInfo->u.pMICFailureInfo->
2673 keyId,
2674 pRoamInfo->u.pMICFailureInfo->TSC,
2675 GFP_KERNEL);
2676
2677 }
2678
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302679 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002680}
2681
2682/**
2683 * roam_roam_connect_status_update_handler() - IBSS connect status update
2684 * @pAdapter: pointer to adapter
2685 * @pRoamInfo: pointer to roam info
2686 * @roamId: roam id
2687 * @roamStatus: roam status
2688 * @roamResult: roam result
2689 *
2690 * The Ibss connection status is updated regularly here in this function.
2691 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302692 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302694static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2696 tCsrRoamInfo *pRoamInfo,
2697 uint32_t roamId,
2698 eRoamCmdStatus roamStatus,
2699 eCsrRoamResult roamResult)
2700{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302701 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002702
2703 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2704 switch (roamResult) {
2705 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2706 {
2707 hdd_station_ctx_t *pHddStaCtx =
2708 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2709 struct station_info staInfo;
2710
2711 pr_info("IBSS New Peer indication from SME "
2712 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2713 MAC_ADDRESS_STR " and stationID= %d",
2714 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2715 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2716 pRoamInfo->staId);
2717
2718 if (!roam_save_ibss_station
2719 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2720 pRoamInfo->staId,
2721 &pRoamInfo->peerMac)) {
2722 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2723 break;
2724 }
2725
2726 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2727
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002728 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302729 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002730 pRoamInfo,
2731 pRoamInfo->staId,
2732 &pRoamInfo->peerMac,
2733 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302734 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002735 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302736 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2737 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002738 }
2739 pHddStaCtx->ibss_sta_generation++;
2740 memset(&staInfo, 0, sizeof(staInfo));
2741 staInfo.filled = 0;
2742 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2743
2744 cfg80211_new_sta(pAdapter->dev,
2745 (const u8 *)pRoamInfo->peerMac.bytes,
2746 &staInfo, GFP_KERNEL);
2747
2748 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2749 pHddStaCtx->ibss_enc_key.encType
2750 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2751 pHddStaCtx->ibss_enc_key.encType
2752 || eCSR_ENCRYPT_TYPE_TKIP ==
2753 pHddStaCtx->ibss_enc_key.encType
2754 || eCSR_ENCRYPT_TYPE_AES ==
2755 pHddStaCtx->ibss_enc_key.encType) {
2756 pHddStaCtx->ibss_enc_key.keyDirection =
2757 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302758 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002759 &pRoamInfo->peerMac);
2760
2761 hddLog(LOG2, "New peer joined set PTK encType=%d",
2762 pHddStaCtx->ibss_enc_key.encType);
2763
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302764 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002765 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2766 (pAdapter),
2767 pAdapter->sessionId,
2768 &pHddStaCtx->ibss_enc_key,
2769 &roamId);
2770
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302771 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002772 hddLog(LOGE,
2773 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302774 qdf_status);
2775 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002776 }
2777 }
2778 hddLog(LOG1, FL("Enabling queues"));
2779 wlan_hdd_netif_queue_control(pAdapter,
2780 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2781 WLAN_CONTROL_PATH);
2782 break;
2783 }
2784
2785 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2786 {
2787
2788 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2789
2790 break;
2791 }
2792 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2793 {
2794 hdd_station_ctx_t *pHddStaCtx =
2795 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2796
2797 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2798 hddLog(LOGW,
2799 "IBSS peer departed by cannot find peer in our registration table with TL");
2800
2801 pr_info("IBSS Peer Departed from SME "
2802 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2803 MAC_ADDRESS_STR " and stationID= %d",
2804 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2805 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2806 pRoamInfo->staId);
2807
2808 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2809
2810 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2811 pHddStaCtx->ibss_sta_generation++;
2812
2813 cfg80211_del_sta(pAdapter->dev,
2814 (const u8 *)&pRoamInfo->peerMac.bytes,
2815 GFP_KERNEL);
2816 break;
2817 }
2818 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2819 {
2820 hddLog(LOG3,
2821 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2822 /* Stop only when we are inactive */
2823 hddLog(LOG1, FL("Disabling queues"));
2824 wlan_hdd_netif_queue_control(pAdapter,
2825 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2826 WLAN_CONTROL_PATH);
2827 hddLog(LOG1,
2828 FL("Set HDD connState to eConnectionState_NotConnected"));
2829 hdd_conn_set_connection_state(pAdapter,
2830 eConnectionState_NotConnected);
2831
2832 /* Send the bssid address to the wext. */
2833 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2834 break;
2835 }
2836 default:
2837 break;
2838
2839 }
2840
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302841 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002842}
2843
2844#ifdef FEATURE_WLAN_TDLS
2845/**
2846 * hdd_roam_register_tdlssta() - register new TDLS station
2847 * @pAdapter: pointer to adapter
2848 * @peerMac: pointer to peer MAC address
2849 * @staId: station identifier
2850 * @ucastSig: unicast signature
2851 *
2852 * Construct the staDesc and register with TL the new STA.
2853 * This is called as part of ADD_STA in the TDLS setup.
2854 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302855 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002856 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302857QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002858 const uint8_t *peerMac, uint16_t staId,
2859 uint8_t ucastSig)
2860{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302861 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002862 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002863 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002864
2865 /*
2866 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2867 * be peer MAC, here we are working on direct Link
2868 */
2869 staDesc.sta_id = staId;
2870
2871 /* set the QoS field appropriately .. */
2872 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2873 : (staDesc.is_qos_enabled = 0);
2874
Dhanashri Atre50141c52016-04-07 13:15:29 -07002875 /* Register the vdev transmit and receive functions */
2876 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2877 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2878 ol_txrx_vdev_register(
2879 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2880 pAdapter, &txrx_ops);
2881 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002882
2883 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002884 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302885 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002886 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302887 qdf_status, qdf_status);
2888 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002889 }
2890
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302891 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002892}
2893
2894/**
2895 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2896 * @pAdapter: pointer to adapter
2897 * @staId: station identifier
2898 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302899 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002900 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302901static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002902 uint8_t staId)
2903{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302904 QDF_STATUS qdf_status;
2905 qdf_status = ol_txrx_clear_peer(staId);
2906 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302908 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002909 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302910 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002911}
2912
2913/**
2914 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2915 * @pAdapter: pointer to adapter
2916 * @pRoamInfo: pointer to roam info
2917 * @roamId: roam id
2918 * @roamStatus: roam status
2919 * @roamResult: roam result
2920 *
2921 * HDD interface between SME and TL to ensure TDLS client registration with
2922 * TL in case of new TDLS client is added and deregistration at the time
2923 * TDLS client is deleted.
2924 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302925 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002926 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302927static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002928hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
2929 tCsrRoamInfo *pRoamInfo,
2930 uint32_t roamId,
2931 eRoamCmdStatus roamStatus,
2932 eCsrRoamResult roamResult)
2933{
2934 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2935 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2936 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302937 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002938 uint8_t staIdx;
2939 hddTdlsPeer_t *curr_peer;
2940 uint32_t reason;
2941
2942 hddLog(LOG2,
2943 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
2944 roamResult ==
2945 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
2946 ==
2947 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
2948 roamResult ==
2949 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
2950 : roamResult ==
2951 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
2952 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
2953 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
2954 roamResult ==
2955 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
2956 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
2957 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
2958 : roamResult ==
2959 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
2960 : roamResult ==
2961 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
2962 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
2963 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
2964
2965 if (!pHddTdlsCtx) {
2966 hddLog(LOG1,
2967 FL("TDLS ctx is null, ignore roamResult (%d)"),
2968 roamResult);
2969 return status;
2970 }
2971
2972 switch (roamResult) {
2973 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
2974 {
2975 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
2976 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
2977 pRoamInfo->statusCode);
2978 } else {
2979 /*
2980 * Check if there is available index for this new TDLS
2981 * STA.
2982 */
2983 for (staIdx = 0;
2984 staIdx < pHddCtx->max_num_tdls_sta;
2985 staIdx++) {
2986 if (0 ==
2987 pHddCtx->tdlsConnInfo[staIdx].
2988 staId) {
2989 pHddCtx->tdlsConnInfo[staIdx].
2990 sessionId =
2991 pRoamInfo->sessionId;
2992 pHddCtx->tdlsConnInfo[staIdx].
2993 staId = pRoamInfo->staId;
2994
2995 hddLog(LOGW,
2996 ("TDLS: STA IDX at %d is %d "
2997 "of mac "
2998 MAC_ADDRESS_STR),
2999 staIdx,
3000 pHddCtx->
3001 tdlsConnInfo[staIdx].
3002 staId,
3003 MAC_ADDR_ARRAY
3004 (pRoamInfo->peerMac.bytes));
3005
Anurag Chouhanc5548422016-02-24 18:33:27 +05303006 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003007 tdlsConnInfo
3008 [staIdx].
3009 peerMac,
3010 &pRoamInfo->
3011 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303012 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003013 break;
3014 }
3015 }
3016 if (staIdx < pHddCtx->max_num_tdls_sta) {
3017 if (-1 ==
3018 wlan_hdd_tdls_set_sta_id(pAdapter,
3019 pRoamInfo->
3020 peerMac.bytes,
3021 pRoamInfo->
3022 staId)) {
3023 hddLog(LOGE,
3024 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303025 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003026 }
3027
3028 (WLAN_HDD_GET_CTX(pAdapter))->
3029 sta_to_adapter[pRoamInfo->staId] =
3030 pAdapter;
3031 /*
3032 * store the ucast signature,
3033 * if required for further reference.
3034 */
3035
3036 wlan_hdd_tdls_set_signature(pAdapter,
3037 pRoamInfo->
3038 peerMac.bytes,
3039 pRoamInfo->
3040 ucastSig);
3041 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303042 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003043 hddLog(LOGE,
3044 FL("no available slot in conn_info. staId %d cannot be stored"),
3045 pRoamInfo->staId);
3046 }
3047 pAdapter->tdlsAddStaStatus = status;
3048 }
3049 complete(&pAdapter->tdls_add_station_comp);
3050 break;
3051 }
3052 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3053 {
3054 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3055 hddLog(LOGE,
3056 FL("Add Sta failed. status code(=%d)"),
3057 pRoamInfo->statusCode);
3058 }
3059 /* store the ucast signature which will be used later when
3060 * registering to TL
3061 */
3062 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3063 complete(&pAdapter->tdls_add_station_comp);
3064 break;
3065 }
3066 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3067 {
3068 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3069 hddLog(LOGE,
3070 FL("Link Establish Request failed. status(=%d)"),
3071 pRoamInfo->statusCode);
3072 }
3073 complete(&pAdapter->tdls_link_establish_req_comp);
3074 break;
3075 }
3076 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3077 {
3078 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3079 staIdx++) {
3080 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3081 pRoamInfo->sessionId)
3082 && pRoamInfo->staId ==
3083 pHddCtx->tdlsConnInfo[staIdx].staId) {
3084 hddLog(LOGW,
3085 ("HDD: del STA IDX = %x"),
3086 pRoamInfo->staId);
3087
3088 curr_peer =
3089 wlan_hdd_tdls_find_peer(pAdapter,
3090 pRoamInfo->
3091 peerMac.bytes,
3092 true);
3093 if (NULL != curr_peer
3094 && TDLS_IS_CONNECTED(curr_peer)) {
3095 hdd_roam_deregister_tdlssta
3096 (pAdapter,
3097 pRoamInfo->staId);
3098 wlan_hdd_tdls_decrement_peer_count
3099 (pAdapter);
3100 }
3101 wlan_hdd_tdls_reset_peer(pAdapter,
3102 pRoamInfo->
3103 peerMac.bytes);
3104
3105 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3106 pHddCtx->tdlsConnInfo[staIdx].
3107 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303108 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003109 tdlsConnInfo[staIdx].
3110 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303111 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303112 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003113 break;
3114 }
3115 }
3116 complete(&pAdapter->tdls_del_station_comp);
3117 }
3118 break;
3119 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3120 {
3121 hddLog(LOGE,
3122 FL("Sending teardown to supplicant with reason code %u"),
3123 pRoamInfo->reasonCode);
3124
3125 curr_peer =
3126 wlan_hdd_tdls_find_peer(pAdapter,
3127 pRoamInfo->peerMac.bytes, true);
3128 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3129 pRoamInfo->reasonCode);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303130 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003131 break;
3132 }
3133 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3134 {
3135 /* 0 staIdx is assigned to AP we dont want to touch that */
3136 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3137 staIdx++) {
3138 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3139 pRoamInfo->sessionId)
3140 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3141 hddLog(LOGW,
3142 ("hdd_tdlsStatusUpdate: staIdx %d "
3143 MAC_ADDRESS_STR),
3144 pHddCtx->tdlsConnInfo[staIdx].
3145 staId,
3146 MAC_ADDR_ARRAY(pHddCtx->
3147 tdlsConnInfo
3148 [staIdx].
3149 peerMac.
3150 bytes));
3151 wlan_hdd_tdls_reset_peer(pAdapter,
3152 pHddCtx->
3153 tdlsConnInfo
3154 [staIdx].
3155 peerMac.bytes);
3156 hdd_roam_deregister_tdlssta(pAdapter,
3157 pHddCtx->
3158 tdlsConnInfo
3159 [staIdx].
3160 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303161 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003162 sizeof
3163 (smeTdlsPeerStateParams));
3164 smeTdlsPeerStateParams.vdevId =
3165 pHddCtx->tdlsConnInfo[staIdx].
3166 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303167 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003168 peerMacAddr,
3169 &pHddCtx->
3170 tdlsConnInfo[staIdx].
3171 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303172 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003173 smeTdlsPeerStateParams.peerState =
3174 eSME_TDLS_PEER_STATE_TEARDOWN;
3175
3176 hddLog(LOG1,
3177 FL("calling sme_update_tdls_peer_state for staIdx %d "
3178 MAC_ADDRESS_STR),
3179 pHddCtx->tdlsConnInfo[staIdx].
3180 staId,
3181 MAC_ADDR_ARRAY(pHddCtx->
3182 tdlsConnInfo
3183 [staIdx].
3184 peerMac.
3185 bytes));
3186 status =
3187 sme_update_tdls_peer_state(
3188 pHddCtx->hHal,
3189 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303190 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003191 hddLog(LOGE,
3192 FL("sme_update_tdls_peer_state failed for "
3193 MAC_ADDRESS_STR),
3194 MAC_ADDR_ARRAY
3195 (pHddCtx->
3196 tdlsConnInfo[staIdx].
3197 peerMac.bytes));
3198 }
3199 wlan_hdd_tdls_decrement_peer_count
3200 (pAdapter);
3201
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303202 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003203 tdlsConnInfo[staIdx].
3204 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303205 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003206 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3207 pHddCtx->tdlsConnInfo[staIdx].
3208 sessionId = 255;
3209
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303210 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003211 }
3212 }
3213 break;
3214 }
3215 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3216 {
3217 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303218 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3219 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003220 hddLog(LOG2,
3221 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3222 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303223 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303224 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003225 break;
3226 }
3227
3228 curr_peer =
3229 wlan_hdd_tdls_get_peer(pAdapter,
3230 pRoamInfo->peerMac.bytes);
3231 if (!curr_peer) {
3232 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303233 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003234 } else {
3235 if (eTDLS_LINK_CONNECTED ==
3236 curr_peer->link_status) {
3237 hddLog(LOGE,
3238 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3239 } else {
3240 /*
3241 * If external control is enabled then initiate
3242 * TDLS only if forced peer is set otherwise
3243 * ignore should Discover trigger from fw.
3244 */
3245 if (pHddCtx->config->
3246 fTDLSExternalControl
3247 && (false ==
3248 curr_peer->isForcedPeer)) {
3249 hddLog(LOG2,
3250 FL
3251 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303252 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003253 break;
3254 } else {
3255 hddLog(LOG2,
3256 FL
3257 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3258 pHddCtx->config->
3259 fTDLSExternalControl,
3260 curr_peer->isForcedPeer,
3261 pRoamInfo->reasonCode);
3262 }
3263 wlan_hdd_tdls_pre_setup_init_work
3264 (pHddTdlsCtx, curr_peer);
3265 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303266 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003267 }
3268 break;
3269 }
3270
3271 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3272 {
3273 curr_peer =
3274 wlan_hdd_tdls_find_peer(pAdapter,
3275 pRoamInfo->peerMac.bytes, true);
3276 if (!curr_peer) {
3277 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303278 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003279 } else {
3280 if (eTDLS_LINK_CONNECTED ==
3281 curr_peer->link_status) {
3282 hddLog(LOGE,
3283 FL
3284 ("Received SHOULD_TEARDOWN for peer "
3285 MAC_ADDRESS_STR
3286 " staId: %d, reason: %d"),
3287 MAC_ADDR_ARRAY(pRoamInfo->
3288 peerMac.bytes),
3289 pRoamInfo->staId,
3290 pRoamInfo->reasonCode);
3291
3292 if (pRoamInfo->reasonCode ==
3293 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3294 pRoamInfo->reasonCode ==
3295 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3296 pRoamInfo->reasonCode ==
3297 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3298 pRoamInfo->reasonCode ==
3299 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3300 reason =
3301 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3302 } else
3303 reason =
3304 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3305
3306 wlan_hdd_tdls_indicate_teardown
3307 (pHddTdlsCtx->pAdapter, curr_peer,
3308 reason);
3309 } else {
3310 hddLog(LOGE,
3311 FL
3312 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3313 pRoamInfo->reasonCode);
3314 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303315 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003316 }
3317 break;
3318 }
3319
3320 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3321 {
3322 curr_peer =
3323 wlan_hdd_tdls_find_peer(pAdapter,
3324 pRoamInfo->peerMac.bytes, true);
3325 if (!curr_peer) {
3326 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303327 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003328 } else {
3329 if (eTDLS_LINK_CONNECTED ==
3330 curr_peer->link_status) {
3331 hddLog(LOGE,
3332 FL
3333 ("Received SHOULD_PEER_DISCONNECTED for peer "
3334 MAC_ADDRESS_STR
3335 " staId: %d, reason: %d"),
3336 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3337 pRoamInfo->staId,
3338 pRoamInfo->reasonCode);
3339
3340 if (pRoamInfo->reasonCode ==
3341 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3342 pRoamInfo->reasonCode ==
3343 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3344 pRoamInfo->reasonCode ==
3345 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3346 pRoamInfo->reasonCode ==
3347 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3348 reason =
3349 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3350 } else
3351 reason =
3352 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3353
3354 wlan_hdd_tdls_indicate_teardown
3355 (pHddTdlsCtx->pAdapter, curr_peer,
3356 reason);
3357 } else {
3358 hddLog(LOGE,
3359 FL
3360 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3361 pRoamInfo->reasonCode);
3362 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303363 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003364 }
3365 break;
3366 }
3367 default:
3368 {
3369 break;
3370 }
3371 }
3372
3373 return status;
3374}
3375#endif
3376
3377#ifdef WLAN_FEATURE_11W
3378/**
3379 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3380 * @pAdapter: pointer to the adapter
3381 * @nFrameLength: Length of the unprotected frame being passed
3382 * @pbFrames: Pointer to the frame buffer
3383 * @frameType: 802.11 frame type
3384 *
3385 * This function forwards the unprotected management frame to the supplicant.
3386 *
3387 * Return: nothing
3388 */
3389static void
3390hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3391 uint8_t *pbFrames, uint8_t frameType)
3392{
3393 uint8_t type = 0;
3394 uint8_t subType = 0;
3395
3396 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3397 frameType, nFrameLength);
3398
3399 /* Sanity Checks */
3400 if (NULL == pAdapter) {
3401 hddLog(LOGE, FL("pAdapter is NULL"));
3402 return;
3403 }
3404
3405 if (NULL == pAdapter->dev) {
3406 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3407 return;
3408 }
3409
3410 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3411 hddLog(LOGE, FL("pAdapter has invalid magic"));
3412 return;
3413 }
3414
3415 if (!nFrameLength) {
3416 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3417 return;
3418 }
3419
3420 if (NULL == pbFrames) {
3421 hddLog(LOGE, FL("pbFrames is NULL"));
3422 return;
3423 }
3424
3425 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3426 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3427
3428 /* Get pAdapter from Destination mac address of the frame */
3429 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3431 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3432 nFrameLength);
3433#else
3434 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3435 nFrameLength);
3436#endif
3437 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3438 } else if (type == SIR_MAC_MGMT_FRAME &&
3439 subType == SIR_MAC_MGMT_DEAUTH) {
3440#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3441 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3442 nFrameLength);
3443#else
3444 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3445 nFrameLength);
3446#endif
3447 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3448 } else {
3449 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3450 type, subType);
3451 return;
3452 }
3453}
3454#endif
3455
3456#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
3457/**
3458 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3459 * @pAdapter: pointer to adapter
3460 * @tid: traffic identifier
3461 * @state: state
3462 * @measInterval: measurement interval
3463 *
3464 * This function sends traffic stream metrics IE information to
3465 * the supplicant via wireless event.
3466 *
3467 * Return: none
3468 */
3469static void
3470hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3471 uint8_t state, uint16_t measInterval)
3472{
3473 union iwreq_data wrqu;
3474 char buf[IW_CUSTOM_MAX + 1];
3475 int nBytes = 0;
3476
3477 if (NULL == pAdapter)
3478 return;
3479
3480 /* create the event */
3481 memset(&wrqu, '\0', sizeof(wrqu));
3482 memset(buf, '\0', sizeof(buf));
3483
3484 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3485 tid, state, measInterval);
3486
3487 nBytes =
3488 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3489 measInterval);
3490
3491 wrqu.data.pointer = buf;
3492 wrqu.data.length = nBytes;
3493 /* send the event */
3494 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3495}
3496
3497/**
3498 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3499 * @pAdapter: pointer to adapter
3500 * @pRoamInfo: pointer to roam info
3501 *
3502 * This function sends cckm preauth indication to the supplicant
3503 * via wireless custom event.
3504 *
3505 * Return: none
3506 */
3507static void
3508hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3509{
3510 union iwreq_data wrqu;
3511 char buf[IW_CUSTOM_MAX + 1];
3512 char *pos = buf;
3513 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3514
3515 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3516 return;
3517
3518 /* create the event */
3519 memset(&wrqu, '\0', sizeof(wrqu));
3520 memset(buf, '\0', sizeof(buf));
3521
3522 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3523 hddLog(LOG1,
3524 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3525 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3526 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3527
3528 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3529 pos += nBytes;
3530 freeBytes -= nBytes;
3531
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303532 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303533 pos += QDF_MAC_ADDR_SIZE;
3534 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003535
3536 nBytes = snprintf(pos, freeBytes, " %u:%u",
3537 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3538 freeBytes -= nBytes;
3539
3540 wrqu.data.pointer = buf;
3541 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3542
3543 /* send the event */
3544 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3545}
3546
3547/**
3548 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3549 * @pAdapter: pointer to adapter
3550 * @pRoamInfo: pointer to roam info
3551 *
3552 * Return: none
3553 */
3554static void
3555hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3556 tCsrRoamInfo *pRoamInfo)
3557{
3558 union iwreq_data wrqu;
3559 char buf[IW_CUSTOM_MAX + 1];
3560 int nBytes = 0;
3561
3562 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3563 return;
3564
3565 /* create the event */
3566 memset(&wrqu, '\0', sizeof(wrqu));
3567 memset(buf, '\0', sizeof(buf));
3568
3569 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3570
3571 nBytes =
3572 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3573 pRoamInfo->tsmRoamDelay);
3574
3575 wrqu.data.pointer = buf;
3576 wrqu.data.length = nBytes;
3577
3578 /* send the event */
3579 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3580}
3581
3582/**
3583 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3584 * @pAdapter: pointer to adapter
3585 * @measurementToken: measurement token
3586 * @flag: flag
3587 * @numBss: number of bss
3588 *
3589 * If the measurement is none and no scan results found,
3590 * indicate the supplicant about measurement done.
3591 *
3592 * Return: none
3593 */
3594void
3595hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3596 const uint16_t measurementToken,
3597 const bool flag, const uint8_t numBss)
3598{
3599 union iwreq_data wrqu;
3600 char buf[IW_CUSTOM_MAX];
3601 char *pos = buf;
3602 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3603
3604 memset(&wrqu, '\0', sizeof(wrqu));
3605 memset(buf, '\0', sizeof(buf));
3606
3607 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3608 flag, numBss);
3609
3610 nBytes =
3611 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3612 flag, numBss);
3613
3614 wrqu.data.pointer = buf;
3615 wrqu.data.length = nBytes;
3616 /* send the event */
3617 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3618}
3619
3620/**
3621 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3622 * @pAdapter: pointer to adapter
3623 * @pRoamInfo: pointer to roam info
3624 *
3625 * If the measurement is none and no scan results found,
3626 * indicate the supplicant about measurement done.
3627 *
3628 * Return: none
3629 */
3630static void
3631hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3632 const tCsrRoamInfo *pRoamInfo)
3633{
3634 union iwreq_data wrqu;
3635 char buf[IW_CUSTOM_MAX];
3636 char *pos = buf;
3637 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3638 uint8_t i = 0, len = 0;
3639 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3640 uint8_t lastSent = 0, sendBss = 0;
3641 int bcnRepFieldSize =
3642 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3643 bcnReportFields);
3644 uint8_t ieLenByte = 1;
3645 /*
3646 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3647 */
3648#define ESEBCNREPHEADER_LEN (18)
3649
3650 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3651 return;
3652
3653 /*
3654 * Custom event can pass maximum of 256 bytes of data,
3655 * based on the IE len we need to identify how many BSS info can
3656 * be filled in to custom event data.
3657 */
3658 /*
3659 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3660 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3661 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3662 */
3663
3664 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3665 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3666 hddLog(LOG1,
3667 "Measurement Done but no scan results");
3668 /* If the measurement is none and no scan results found,
3669 indicate the supplicant about measurement done */
3670 hdd_indicate_ese_bcn_report_no_results(
3671 pAdapter,
3672 pRoamInfo->pEseBcnReportRsp->
3673 measurementToken,
3674 pRoamInfo->pEseBcnReportRsp->flag,
3675 pRoamInfo->pEseBcnReportRsp->numBss);
3676 } else {
3677 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3678 memset(&wrqu, '\0', sizeof(wrqu));
3679 memset(buf, '\0', sizeof(buf));
3680 tot_bcn_ieLen = 0;
3681 sendBss = 0;
3682 pos = buf;
3683 freeBytes = IW_CUSTOM_MAX;
3684
3685 for (i = lastSent;
3686 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3687 len =
3688 bcnRepFieldSize + ieLenByte +
3689 pRoamInfo->pEseBcnReportRsp->
3690 bcnRepBssInfo[i].ieLen;
3691 if ((len + tot_bcn_ieLen) >
3692 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3693 break;
3694 }
3695 tot_bcn_ieLen += len;
3696 sendBss++;
3697 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3698 i, bcnRepFieldSize, 1,
3699 pRoamInfo->pEseBcnReportRsp->
3700 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3701 }
3702
3703 hddLog(LOG1, "Sending %d BSS Info",
3704 sendBss);
3705 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3706 pRoamInfo->pEseBcnReportRsp->measurementToken,
3707 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3708 tot_bcn_ieLen);
3709
3710 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3711 pRoamInfo->pEseBcnReportRsp->
3712 measurementToken,
3713 pRoamInfo->pEseBcnReportRsp->flag,
3714 sendBss);
3715 pos += nBytes;
3716 freeBytes -= nBytes;
3717
3718 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303719 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003720 sizeof(tot_bcn_ieLen));
3721 pos += sizeof(tot_bcn_ieLen);
3722 freeBytes -= sizeof(tot_bcn_ieLen);
3723
3724 for (i = 0; i < sendBss; i++) {
3725 hddLog(LOG1,
3726 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3727 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3728 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3729 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3730 pRoamInfo->pEseBcnReportRsp->
3731 bcnRepBssInfo[i +
3732 lastSent].bcnReportFields.
3733 ChanNum,
3734 pRoamInfo->pEseBcnReportRsp->
3735 bcnRepBssInfo[i +
3736 lastSent].bcnReportFields.
3737 Spare,
3738 pRoamInfo->pEseBcnReportRsp->
3739 bcnRepBssInfo[i +
3740 lastSent].bcnReportFields.
3741 MeasDuration,
3742 pRoamInfo->pEseBcnReportRsp->
3743 bcnRepBssInfo[i +
3744 lastSent].bcnReportFields.
3745 PhyType,
3746 pRoamInfo->pEseBcnReportRsp->
3747 bcnRepBssInfo[i +
3748 lastSent].bcnReportFields.
3749 RecvSigPower,
3750 pRoamInfo->pEseBcnReportRsp->
3751 bcnRepBssInfo[i +
3752 lastSent].bcnReportFields.
3753 ParentTsf,
3754 pRoamInfo->pEseBcnReportRsp->
3755 bcnRepBssInfo[i +
3756 lastSent].bcnReportFields.
3757 TargetTsf[0],
3758 pRoamInfo->pEseBcnReportRsp->
3759 bcnRepBssInfo[i +
3760 lastSent].bcnReportFields.
3761 TargetTsf[1],
3762 pRoamInfo->pEseBcnReportRsp->
3763 bcnRepBssInfo[i +
3764 lastSent].bcnReportFields.
3765 BcnInterval,
3766 pRoamInfo->pEseBcnReportRsp->
3767 bcnRepBssInfo[i +
3768 lastSent].bcnReportFields.
3769 CapabilityInfo,
3770 pRoamInfo->pEseBcnReportRsp->
3771 bcnRepBssInfo[i +
3772 lastSent].bcnReportFields.
3773 Bssid[0],
3774 pRoamInfo->pEseBcnReportRsp->
3775 bcnRepBssInfo[i +
3776 lastSent].bcnReportFields.
3777 Bssid[1],
3778 pRoamInfo->pEseBcnReportRsp->
3779 bcnRepBssInfo[i +
3780 lastSent].bcnReportFields.
3781 Bssid[2],
3782 pRoamInfo->pEseBcnReportRsp->
3783 bcnRepBssInfo[i +
3784 lastSent].bcnReportFields.
3785 Bssid[3],
3786 pRoamInfo->pEseBcnReportRsp->
3787 bcnRepBssInfo[i +
3788 lastSent].bcnReportFields.
3789 Bssid[4],
3790 pRoamInfo->pEseBcnReportRsp->
3791 bcnRepBssInfo[i +
3792 lastSent].bcnReportFields.
3793 Bssid[5]);
3794
3795 /* bcn report fields are copied */
3796 len =
3797 sizeof(pRoamInfo->pEseBcnReportRsp->
3798 bcnRepBssInfo[i +
3799 lastSent].
3800 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303801 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003802 (char *)&pRoamInfo->
3803 pEseBcnReportRsp->bcnRepBssInfo[i +
3804 lastSent].
3805 bcnReportFields, len);
3806 pos += len;
3807 freeBytes -= len;
3808
3809 /* Add 1 byte of ie len */
3810 len =
3811 pRoamInfo->pEseBcnReportRsp->
3812 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303813 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003814 pos += sizeof(len);
3815 freeBytes -= sizeof(len);
3816
3817 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303818 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003819 (char *)pRoamInfo->
3820 pEseBcnReportRsp->bcnRepBssInfo[i +
3821 lastSent].
3822 pBuf, len);
3823 pos += len;
3824 freeBytes -= len;
3825 }
3826
3827 wrqu.data.pointer = buf;
3828 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3829
3830 /* send the event */
3831 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3832 buf);
3833 lastSent += sendBss;
3834 }
3835 }
3836}
3837
3838#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
3839
3840/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303841 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3842 * @pHddStaCtx: Station Context
3843 *
3844 * API to check if the connection authentication type is 8021x_sha256.
3845 *
3846 * Return: bool
3847 */
3848#ifdef WLAN_FEATURE_11W
3849static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3850{
3851 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
3852 pHddStaCtx->conn_info.authType;
3853}
3854#else
3855static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3856{
3857 return false;
3858}
3859#endif
3860
3861/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003862 * hdd_sme_roam_callback() - hdd sme roam callback
3863 * @pContext: pointer to adapter context
3864 * @pRoamInfo: pointer to roam info
3865 * @roamId: roam id
3866 * @roamStatus: roam status
3867 * @roamResult: roam result
3868 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303869 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003870 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303871QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003872hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3873 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3874{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303875 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003876 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3877 hdd_wext_state_t *pWextState = NULL;
3878 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303879 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003880 hdd_context_t *pHddCtx = NULL;
3881
3882 hddLog(LOG2,
3883 "CSR Callback: status= %d result= %d roamID=%d",
3884 roamStatus, roamResult, roamId);
3885
3886 /* Sanity check */
3887 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3888 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303889 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003890 }
3891
3892 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3893 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3894
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303895 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303896 pAdapter->sessionId, roamStatus));
3897
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003898 switch (roamStatus) {
3899 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303900 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3901 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08003902 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003903 break;
3904
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003905 /*
3906 * We did pre-auth,then we attempted a 11r or ese reassoc.
3907 * reassoc failed due to failure, timeout, reject from ap
3908 * in any case tell the OS, our carrier is off and mark
3909 * interface down.
3910 */
3911 case eCSR_ROAM_FT_REASSOC_FAILED:
3912 hddLog(LOGE,
3913 FL
3914 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
3915 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303916 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003917 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3918 roamStatus, roamResult);
3919 /*
3920 * Check if Mcast/Bcast Filters are set, if yes
3921 * clear the filters here.
3922 */
3923 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
3924 true) {
3925 (WLAN_HDD_GET_CTX(pAdapter))->
3926 hdd_mcastbcast_filter_set = false;
3927 }
3928 pHddStaCtx->ft_carrier_on = false;
3929 pHddStaCtx->hdd_ReassocScenario = false;
3930 hddLog(LOG1,
3931 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
3932 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3933 break;
3934
3935 case eCSR_ROAM_FT_START:
3936 /*
3937 * When we roam for ESE and 11r, we dont want the OS to be
3938 * informed that the link is down. So mark the link ready for
3939 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
3940 * be received. Where in we will not mark the link down
3941 * Also we want to stop tx at this point when we will be
3942 * doing disassoc at this time. This saves 30-60 msec
3943 * after reassoc.
3944 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003945 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07003946 wlan_hdd_netif_queue_control(pAdapter,
3947 WLAN_NETIF_TX_DISABLE,
3948 WLAN_CONTROL_PATH);
3949 status = hdd_roam_deregister_sta(pAdapter,
3950 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303951 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303952 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003953 pHddStaCtx->ft_carrier_on = true;
3954 pHddStaCtx->hdd_ReassocScenario = true;
3955 hddLog(LOG1,
3956 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
3957 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
3958 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003959
3960 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003961 /* notify apps that we can't pass traffic anymore */
3962 hddLog(LOG1, FL("Disabling queues"));
3963 wlan_hdd_netif_queue_control(pAdapter,
3964 WLAN_NETIF_TX_DISABLE,
3965 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003966 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003967 wlan_hdd_netif_queue_control(pAdapter,
3968 WLAN_NETIF_CARRIER_OFF,
3969 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003970 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971 break;
3972 case eCSR_ROAM_LOSTLINK:
3973 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
3974 hddLog(LOG2, "Roaming started due to connection lost");
3975 hddLog(LOG1, FL("Disabling queues"));
3976 wlan_hdd_netif_queue_control(pAdapter,
3977 WLAN_NETIF_TX_DISABLE_N_CARRIER,
3978 WLAN_CONTROL_PATH);
3979 break;
3980 }
3981 case eCSR_ROAM_DISASSOCIATED:
3982 {
3983 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303984 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003985 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
3986 roamStatus, roamResult);
3987 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
3988 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3989 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
3990 hdd_conf_mcastbcast_filter(pHddCtx, false);
3991
3992 if (true ==
3993 pHddCtx->sus_res_mcastbcast_filter_valid) {
3994 pHddCtx->configuredMcastBcastFilter =
3995 pHddCtx->sus_res_mcastbcast_filter;
3996 pHddCtx->
3997 sus_res_mcastbcast_filter_valid =
3998 false;
3999 }
4000
4001 hddLog(LOG1,
4002 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4003 hddLog(LOG1,
4004 "McastBcastFilter = %d",
4005 pHddCtx->configuredMcastBcastFilter);
4006 hddLog(LOG1,
4007 "offload: already called mcastbcast filter");
4008 (WLAN_HDD_GET_CTX(pAdapter))->
4009 hdd_mcastbcast_filter_set = false;
4010 }
4011 /* Call to clear any MC Addr List filter applied after
4012 * successful connection.
4013 */
4014 wlan_hdd_set_mc_addr_list(pAdapter, false);
4015 }
4016 break;
4017 case eCSR_ROAM_IBSS_LEAVE:
4018 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304019 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004020 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4021 roamStatus, roamResult);
4022 break;
4023 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4024 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4025 /*
4026 * To Do - address probable memory leak with WEP encryption upon
4027 * successful association.
4028 */
4029 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4030 /* Clear saved connection information in HDD */
4031 hdd_conn_remove_connect_info(
4032 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4033 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304034 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004035 hdd_association_completion_handler(pAdapter, pRoamInfo,
4036 roamId, roamStatus,
4037 roamResult);
4038#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4039 if (pRoamInfo)
4040 pRoamInfo->roamSynchInProgress = false;
4041#endif
4042 break;
4043 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304044 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004045 pRoamInfo,
4046 roamId,
4047 roamStatus,
4048 roamResult);
4049 break;
4050 case eCSR_ROAM_IBSS_IND:
4051 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4052 roamStatus, roamResult);
4053 break;
4054
4055 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304056 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004057 roam_roam_connect_status_update_handler(pAdapter,
4058 pRoamInfo,
4059 roamId,
4060 roamStatus,
4061 roamResult);
4062 break;
4063
4064 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304065 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004066 hdd_roam_mic_error_indication_handler(pAdapter,
4067 pRoamInfo,
4068 roamId,
4069 roamStatus,
4070 roamResult);
4071 break;
4072
4073 case eCSR_ROAM_SET_KEY_COMPLETE:
4074 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304075 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004076 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4077 roamId, roamStatus,
4078 roamResult);
4079 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4080 pHddStaCtx->hdd_ReassocScenario = false;
4081 hddLog(LOG1,
4082 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4083 pHddStaCtx->hdd_ReassocScenario,
4084 pAdapter->sessionId);
4085 }
4086 }
4087#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4088 if (pRoamInfo != NULL)
4089 pRoamInfo->roamSynchInProgress = false;
4090#endif
4091 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004092
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004093 case eCSR_ROAM_FT_RESPONSE:
4094 hdd_send_ft_event(pAdapter);
4095 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004096
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004097 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304098 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4099 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004100 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304101 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004102 wlan_hdd_cfg80211_pmksa_candidate_notify(
4103 pAdapter, pRoamInfo, 1, false);
4104 }
4105 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004106
4107#ifdef FEATURE_WLAN_LFR_METRICS
4108 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4109 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304110 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004111 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4112 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304113 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004114 }
4115 break;
4116 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4117 /*
4118 * This event will notify pre-auth completion in case of success
4119 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304120 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004121 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4122 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304123 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004124 }
4125 break;
4126 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4127 /*
4128 * This event will notify pre-auth completion incase of failure.
4129 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304130 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004131 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4132 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304133 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004134 }
4135 break;
4136 case eCSR_ROAM_HANDOVER_SUCCESS:
4137 /* This event is to notify handover success.
4138 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304139 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004140 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4141 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304142 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004143 }
4144 break;
4145#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004146 case eCSR_ROAM_REMAIN_CHAN_READY:
4147 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4148 break;
4149 case eCSR_ROAM_SEND_ACTION_CNF:
4150 hdd_send_action_cnf(pAdapter,
4151 (roamResult ==
4152 eCSR_ROAM_RESULT_NONE) ? true : false);
4153 break;
4154#ifdef FEATURE_WLAN_TDLS
4155 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304156 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004157 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4158 roamId,
4159 roamStatus,
4160 roamResult);
4161 break;
4162 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4163 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4164 pRoamInfo->reasonCode);
4165 break;
4166#endif
4167#ifdef WLAN_FEATURE_11W
4168 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4169 hdd_indicate_unprot_mgmt_frame(pAdapter,
4170 pRoamInfo->nFrameLength,
4171 pRoamInfo->pbFrames,
4172 pRoamInfo->frameType);
4173 break;
4174#endif
4175#if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD)
4176 case eCSR_ROAM_TSM_IE_IND:
4177 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4178 pRoamInfo->tsmIe.state,
4179 pRoamInfo->tsmIe.msmt_interval);
4180 break;
4181
4182 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4183 {
4184 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4185 pHddStaCtx->conn_info.authType
4186 || eCSR_AUTH_TYPE_CCKM_RSN ==
4187 pHddStaCtx->conn_info.authType) {
4188 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4189 }
4190 break;
4191 }
4192
4193 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4194 {
4195 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4196 break;
4197 }
4198
4199 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4200 {
4201 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4202 break;
4203 }
4204#endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */
4205 default:
4206 break;
4207 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304208 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004209}
4210
4211/**
4212 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4213 * @auth_suite: auth suite
4214 *
4215 * Return: eCsrAuthType enumeration
4216 */
4217eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4218{
4219 eCsrAuthType auth_type;
4220 /* is the auth type supported? */
4221 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4222 auth_type = eCSR_AUTH_TYPE_RSN;
4223 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4224 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004225 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004226 /* Check for 11r FT Authentication with PSK */
4227 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4228 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4229 /* Check for 11R FT Authentication with 802.1X */
4230 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4231 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004232#ifdef FEATURE_WLAN_ESE
4233 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4234 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4235 } else
4236#endif /* FEATURE_WLAN_ESE */
4237#ifdef WLAN_FEATURE_11W
4238 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4239 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4240 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4241 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4242 } else
4243#endif
4244 {
4245 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4246 }
4247 return auth_type;
4248}
4249
4250/**
4251 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4252 * @auth_suite: auth suite
4253 *
4254 * Return: eCsrAuthType enumeration
4255 */
4256eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4257{
4258 eCsrAuthType auth_type;
4259 /* is the auth type supported? */
4260 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4261 auth_type = eCSR_AUTH_TYPE_WPA;
4262 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4263 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4264 } else
4265#ifdef FEATURE_WLAN_ESE
4266 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4267 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4268 } else
4269#endif /* FEATURE_WLAN_ESE */
4270 {
4271 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4272 }
4273 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4274 return auth_type;
4275}
4276
4277/**
4278 * hdd_translate_rsn_to_csr_encryption_type() -
4279 * Translate RSN to CSR encryption type
4280 * @cipher_suite: cipher suite
4281 *
4282 * Return: eCsrEncryptionType enumeration
4283 */
4284eCsrEncryptionType
4285hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4286{
4287 eCsrEncryptionType cipher_type;
4288
4289 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4290 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4291 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4292 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4293 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4294 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4295 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4296 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4297 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4298 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4299 else
4300 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4301
4302 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4303 return cipher_type;
4304}
4305
4306/**
4307 * hdd_translate_wpa_to_csr_encryption_type() -
4308 * Translate WPA to CSR encryption type
4309 * @cipher_suite: cipher suite
4310 *
4311 * Return: eCsrEncryptionType enumeration
4312 */
4313eCsrEncryptionType
4314hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4315{
4316 eCsrEncryptionType cipher_type;
4317
4318 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4319 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4320 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4321 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4322 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4323 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4324 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4325 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4326 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4327 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4328 else
4329 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4330
4331 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4332 return cipher_type;
4333}
4334
4335/**
4336 * hdd_process_genie() - process gen ie
4337 * @pAdapter: pointer to adapter
4338 * @bssid: pointer to mac address
4339 * @pEncryptType: pointer to encryption type
4340 * @mcEncryptType: pointer to multicast encryption type
4341 * @pAuthType: pointer to auth type
4342 *
4343 * Return: 0 on success, error number otherwise
4344 */
4345static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4346 u8 *bssid,
4347 eCsrEncryptionType *pEncryptType,
4348 eCsrEncryptionType *mcEncryptType,
4349 eCsrAuthType *pAuthType,
4350#ifdef WLAN_FEATURE_11W
4351 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4352#endif
4353 uint16_t gen_ie_len, uint8_t *gen_ie)
4354{
4355 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304356 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004357 tDot11fIERSN dot11RSNIE;
4358 tDot11fIEWPA dot11WPAIE;
4359 uint32_t i;
4360 uint8_t *pRsnIe;
4361 uint16_t RSNIeLen;
4362 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4363 bool updatePMKCache = false;
4364
4365 /*
4366 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4367 * setting present flag to 0.
4368 */
4369 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4370 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4371
4372 /* Type check */
4373 if (gen_ie[0] == DOT11F_EID_RSN) {
4374 /* Validity checks */
4375 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4376 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4377 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4378 gen_ie_len);
4379 return -EINVAL;
4380 }
4381 /* Skip past the EID byte and length byte */
4382 pRsnIe = gen_ie + 2;
4383 RSNIeLen = gen_ie_len - 2;
4384 /* Unpack the RSN IE */
4385 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4386 pRsnIe, RSNIeLen, &dot11RSNIE);
4387 /* Copy out the encryption and authentication types */
4388 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4389 dot11RSNIE.pwise_cipher_suite_count);
4390 hddLog(LOG1, FL("authentication suite count: %d"),
4391 dot11RSNIE.akm_suite_count);
4392 /*Here we have followed the apple base code,
4393 but probably I suspect we can do something different */
4394 /* dot11RSNIE.akm_suite_count */
4395 /* Just translate the FIRST one */
4396 *pAuthType =
4397 hdd_translate_rsn_to_csr_auth_type(
4398 dot11RSNIE.akm_suites[0]);
4399 /* dot11RSNIE.pwise_cipher_suite_count */
4400 *pEncryptType =
4401 hdd_translate_rsn_to_csr_encryption_type(
4402 dot11RSNIE.pwise_cipher_suites[0]);
4403 /* dot11RSNIE.gp_cipher_suite_count */
4404 *mcEncryptType =
4405 hdd_translate_rsn_to_csr_encryption_type(
4406 dot11RSNIE.gp_cipher_suite);
4407#ifdef WLAN_FEATURE_11W
4408 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4409 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4410#endif
4411 /* Set the PMKSA ID Cache for this interface */
4412 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4413 if (is_zero_ether_addr(bssid)) {
4414 hddLog(LOGE, FL("MAC address is all zeroes"));
4415 break;
4416 }
4417 updatePMKCache = true;
4418 /*
4419 * For right now, I assume setASSOCIATE() has passed
4420 * in the bssid.
4421 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304422 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304423 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304424 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004425 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4426 }
4427
4428 if (updatePMKCache) {
4429 /*
4430 * Calling csr_roam_set_pmkid_cache to configure the
4431 * PMKIDs into the cache.
4432 */
4433 hddLog(LOG1,
4434 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4435 i);
4436 /* Finally set the PMKSA ID Cache in CSR */
4437 result =
4438 sme_roam_set_pmkid_cache(halHandle,
4439 pAdapter->sessionId,
4440 PMKIDCache,
4441 dot11RSNIE.pmkid_count,
4442 false);
4443 }
4444 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4445 /* Validity checks */
4446 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4447 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4448 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4449 gen_ie_len);
4450 return -EINVAL;
4451 }
4452 /* Skip past the EID and length byte - and four byte WiFi OUI */
4453 pRsnIe = gen_ie + 2 + 4;
4454 RSNIeLen = gen_ie_len - (2 + 4);
4455 /* Unpack the WPA IE */
4456 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4457 pRsnIe, RSNIeLen, &dot11WPAIE);
4458 /* Copy out the encryption and authentication types */
4459 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4460 dot11WPAIE.unicast_cipher_count);
4461 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4462 dot11WPAIE.auth_suite_count);
4463 /* dot11WPAIE.auth_suite_count */
4464 /* Just translate the FIRST one */
4465 *pAuthType =
4466 hdd_translate_wpa_to_csr_auth_type(
4467 dot11WPAIE.auth_suites[0]);
4468 /* dot11WPAIE.unicast_cipher_count */
4469 *pEncryptType =
4470 hdd_translate_wpa_to_csr_encryption_type(
4471 dot11WPAIE.unicast_ciphers[0]);
4472 /* dot11WPAIE.unicast_cipher_count */
4473 *mcEncryptType =
4474 hdd_translate_wpa_to_csr_encryption_type(
4475 dot11WPAIE.multicast_cipher);
4476 } else {
4477 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4478 return -EINVAL;
4479 }
4480 return 0;
4481}
4482
4483/**
4484 * hdd_set_genie_to_csr() - set genie to csr
4485 * @pAdapter: pointer to adapter
4486 * @RSNAuthType: pointer to auth type
4487 *
4488 * Return: 0 on success, error number otherwise
4489 */
4490int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4491{
4492 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4493 uint32_t status = 0;
4494 eCsrEncryptionType RSNEncryptType;
4495 eCsrEncryptionType mcRSNEncryptType;
4496#ifdef WLAN_FEATURE_11W
4497 uint8_t RSNMfpRequired = 0;
4498 uint8_t RSNMfpCapable = 0;
4499#endif
4500 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4501 /* MAC address of assoc peer */
4502 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304503 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004504 pWextState->roamProfile.BSSIDs.bssid,
4505 sizeof(bssid));
4506 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4507 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4508 /* continue */
4509 } else {
4510 return 0;
4511 }
4512 /* The actual processing may eventually be more extensive than this. */
4513 /* Right now, just consume any PMKIDs that are sent in by the app. */
4514 status = hdd_process_genie(pAdapter, bssid,
4515 &RSNEncryptType,
4516 &mcRSNEncryptType, RSNAuthType,
4517#ifdef WLAN_FEATURE_11W
4518 &RSNMfpRequired, &RSNMfpCapable,
4519#endif
4520 pWextState->WPARSNIE[1] + 2,
4521 pWextState->WPARSNIE);
4522 if (status == 0) {
4523 /*
4524 * Now copy over all the security attributes
4525 * you have parsed out.
4526 */
4527 pWextState->roamProfile.EncryptionType.numEntries = 1;
4528 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4529
4530 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4531 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4532 mcRSNEncryptType;
4533
4534 if ((WLAN_HDD_IBSS == pAdapter->device_mode) &&
4535 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4536 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4537 /*
4538 * For wpa none supplicant sends the WPA IE with unicast
4539 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4540 * multicast cipher as either AES/TKIP based on group
4541 * cipher configuration mentioned in the
4542 * wpa_supplicant.conf.
4543 */
4544
4545 /* Set the unicast cipher same as multicast cipher */
4546 pWextState->roamProfile.EncryptionType.encryptionType[0]
4547 = mcRSNEncryptType;
4548 }
4549#ifdef WLAN_FEATURE_11W
4550 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4551 RSNMfpRequired, RSNMfpCapable);
4552 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4553 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4554#endif
4555 hddLog(LOG1,
4556 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4557 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4558 }
4559 return 0;
4560}
4561
4562/**
4563 * hdd_set_csr_auth_type() - set csr auth type
4564 * @pAdapter: pointer to adapter
4565 * @RSNAuthType: auth type
4566 *
4567 * Return: 0 on success, error number otherwise
4568 */
4569int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4570{
4571 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4572 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4573 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4574 ENTER();
4575
4576 pRoamProfile->AuthType.numEntries = 1;
4577 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4578 pHddStaCtx->conn_info.authType);
4579
4580 switch (pHddStaCtx->conn_info.authType) {
4581 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4582#ifdef FEATURE_WLAN_ESE
4583 case eCSR_AUTH_TYPE_CCKM_WPA:
4584 case eCSR_AUTH_TYPE_CCKM_RSN:
4585#endif
4586 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4587
4588 pRoamProfile->AuthType.authType[0] =
4589 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4590 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4591
4592#ifdef FEATURE_WLAN_ESE
4593 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4594 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4595 == IW_AUTH_KEY_MGMT_802_1X)) {
4596 hddLog(LOG1,
4597 FL("set authType to CCKM WPA. AKM also 802.1X."));
4598 pRoamProfile->AuthType.authType[0] =
4599 eCSR_AUTH_TYPE_CCKM_WPA;
4600 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4601 hddLog(LOG1,
4602 FL("Last chance to set authType to CCKM WPA."));
4603 pRoamProfile->AuthType.authType[0] =
4604 eCSR_AUTH_TYPE_CCKM_WPA;
4605 } else
4606#endif
4607 if ((pWextState->
4608 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4609 == IW_AUTH_KEY_MGMT_802_1X) {
4610 pRoamProfile->AuthType.authType[0] =
4611 eCSR_AUTH_TYPE_WPA;
4612 } else
4613 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4614 == IW_AUTH_KEY_MGMT_PSK) {
4615 pRoamProfile->AuthType.authType[0] =
4616 eCSR_AUTH_TYPE_WPA_PSK;
4617 } else {
4618 pRoamProfile->AuthType.authType[0] =
4619 eCSR_AUTH_TYPE_WPA_NONE;
4620 }
4621 }
4622 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4623#ifdef FEATURE_WLAN_ESE
4624 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4625 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4626 == IW_AUTH_KEY_MGMT_802_1X)) {
4627 hddLog(LOG1,
4628 FL("set authType to CCKM RSN. AKM also 802.1X."));
4629 pRoamProfile->AuthType.authType[0] =
4630 eCSR_AUTH_TYPE_CCKM_RSN;
4631 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4632 hddLog(LOG1,
4633 FL("Last chance to set authType to CCKM RSN."));
4634 pRoamProfile->AuthType.authType[0] =
4635 eCSR_AUTH_TYPE_CCKM_RSN;
4636 } else
4637#endif
4638
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004639 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4640 ((pWextState->
4641 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4642 == IW_AUTH_KEY_MGMT_802_1X)) {
4643 pRoamProfile->AuthType.authType[0] =
4644 eCSR_AUTH_TYPE_FT_RSN;
4645 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4646 &&
4647 ((pWextState->
4648 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4649 == IW_AUTH_KEY_MGMT_PSK)) {
4650 pRoamProfile->AuthType.authType[0] =
4651 eCSR_AUTH_TYPE_FT_RSN_PSK;
4652 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004653
4654#ifdef WLAN_FEATURE_11W
4655 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4656 pRoamProfile->AuthType.authType[0] =
4657 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4658 } else if (RSNAuthType ==
4659 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4660 pRoamProfile->AuthType.authType[0] =
4661 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4662 } else
4663#endif
4664
4665 if ((pWextState->
4666 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4667 == IW_AUTH_KEY_MGMT_802_1X) {
4668 pRoamProfile->AuthType.authType[0] =
4669 eCSR_AUTH_TYPE_RSN;
4670 } else
4671 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4672 == IW_AUTH_KEY_MGMT_PSK) {
4673 pRoamProfile->AuthType.authType[0] =
4674 eCSR_AUTH_TYPE_RSN_PSK;
4675 } else {
4676 pRoamProfile->AuthType.authType[0] =
4677 eCSR_AUTH_TYPE_UNKNOWN;
4678 }
4679 }
4680 break;
4681
4682 case eCSR_AUTH_TYPE_SHARED_KEY:
4683
4684 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4685 break;
4686 default:
4687
4688#ifdef FEATURE_WLAN_ESE
4689 hddLog(LOG1, FL("In default, unknown auth type."));
4690#endif /* FEATURE_WLAN_ESE */
4691 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4692 break;
4693 }
4694
4695 hddLog(LOG1, FL("Set roam Authtype to %d"),
4696 pWextState->roamProfile.AuthType.authType[0]);
4697
4698 EXIT();
4699 return 0;
4700}
4701
4702/**
4703 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4704 * to the CSR roam profile.
4705 *
4706 * @dev: Pointer to the net device.
4707 * @info: Pointer to the iw_request_info.
4708 * @wrqu: Pointer to the iwreq_data.
4709 * @extra: Pointer to the data.
4710 *
4711 * Return: 0 for success, error number on failure
4712 */
4713static int __iw_set_essid(struct net_device *dev,
4714 struct iw_request_info *info,
4715 union iwreq_data *wrqu, char *extra)
4716{
4717 unsigned long rc;
4718 uint32_t status = 0;
4719 hdd_wext_state_t *pWextState;
4720 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4721 hdd_context_t *hdd_ctx;
4722 uint32_t roamId;
4723 tCsrRoamProfile *pRoamProfile;
4724 eMib_dot11DesiredBssType connectedBssType;
4725 eCsrAuthType RSNAuthType;
4726 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4727 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4728 int ret;
4729
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004730 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004731
4732 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4733 ret = wlan_hdd_validate_context(hdd_ctx);
4734 if (0 != ret)
4735 return ret;
4736
4737 if (pAdapter->device_mode != WLAN_HDD_INFRA_STATION &&
4738 pAdapter->device_mode != WLAN_HDD_P2P_CLIENT) {
4739 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4740 hdd_device_mode_to_string(pAdapter->device_mode),
4741 pAdapter->device_mode);
4742 return -EINVAL;
4743 }
4744
4745 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4746
4747 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4748 hddLog(LOG2, FL("Counter measure is in progress"));
4749 return -EBUSY;
4750 }
4751 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4752 return -EINVAL;
4753
4754 pRoamProfile = &pWextState->roamProfile;
4755 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4756 (eMib_dot11DesiredBssType_independent ==
4757 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304758 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004759
4760 /* Need to issue a disconnect to CSR. */
4761 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304762 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004763 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4764
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304765 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004766 rc = wait_for_completion_timeout(&pAdapter->
4767 disconnect_comp_var,
4768 msecs_to_jiffies
4769 (WLAN_WAIT_TIME_DISCONNECT));
4770 if (!rc)
4771 hddLog(LOGE, FL("Disconnect event timed out"));
4772 }
4773 }
4774
4775 /*
4776 * when cfg80211 defined, wpa_supplicant wext driver uses
4777 * zero-length, null-string ssid for force disconnection.
4778 * after disconnection (if previously connected) and cleaning ssid,
4779 * driver MUST return success.
4780 */
4781 if (0 == wrqu->essid.length)
4782 return 0;
4783
4784 status = hdd_wmm_get_uapsd_mask(pAdapter,
4785 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304786 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004787 pWextState->roamProfile.uapsd_mask = 0;
4788
4789 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4790
4791 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4792 wrqu->essid.length;
4793
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304794 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004795 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304796 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004797 ssId), extra, wrqu->essid.length);
4798 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4799 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4800
4801 /* set gen ie */
4802 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4803
4804 /* set auth */
4805 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4806 }
4807#ifdef FEATURE_WLAN_WAPI
4808 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4809 if (pAdapter->wapi_info.nWapiMode) {
4810 switch (pAdapter->wapi_info.wapiAuthMode) {
4811 case WAPI_AUTH_MODE_PSK:
4812 {
4813 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4814 pAdapter->wapi_info.wapiAuthMode);
4815 pRoamProfile->AuthType.numEntries = 1;
4816 pRoamProfile->AuthType.authType[0] =
4817 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4818 break;
4819 }
4820 case WAPI_AUTH_MODE_CERT:
4821 {
4822 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4823 pAdapter->wapi_info.wapiAuthMode);
4824 pRoamProfile->AuthType.numEntries = 1;
4825 pRoamProfile->AuthType.authType[0] =
4826 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4827 break;
4828 }
4829 } /* End of switch */
4830 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4831 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4832 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4833 pRoamProfile->EncryptionType.numEntries = 1;
4834 pRoamProfile->EncryptionType.encryptionType[0] =
4835 eCSR_ENCRYPT_TYPE_WPI;
4836 pRoamProfile->mcEncryptionType.numEntries = 1;
4837 pRoamProfile->mcEncryptionType.encryptionType[0] =
4838 eCSR_ENCRYPT_TYPE_WPI;
4839 }
4840 }
4841#endif /* FEATURE_WLAN_WAPI */
4842 /* if previous genIE is not NULL, update AssocIE */
4843 if (0 != pWextState->genIE.length) {
4844 memset(&pWextState->assocAddIE, 0,
4845 sizeof(pWextState->assocAddIE));
4846 memcpy(pWextState->assocAddIE.addIEdata,
4847 pWextState->genIE.addIEdata, pWextState->genIE.length);
4848 pWextState->assocAddIE.length = pWextState->genIE.length;
4849 pWextState->roamProfile.pAddIEAssoc =
4850 pWextState->assocAddIE.addIEdata;
4851 pWextState->roamProfile.nAddIEAssocLength =
4852 pWextState->assocAddIE.length;
4853
4854 /* clear previous genIE after use it */
4855 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4856 }
4857
4858 /*
4859 * Assumes it is not WPS Association by default, except when
4860 * pAddIEAssoc has WPS IE.
4861 */
4862 pWextState->roamProfile.bWPSAssociation = false;
4863
4864 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4865 pWextState->roamProfile.
4866 nAddIEAssocLength))
4867 pWextState->roamProfile.bWPSAssociation = true;
4868
4869 /* Disable auto BMPS entry by PMC until DHCP is done */
4870 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
4871 true);
4872
4873 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
4874
4875 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
4876 hdd_select_cbmode(pAdapter,
4877 (WLAN_HDD_GET_CTX(pAdapter))->config->
4878 AdHocChannel5G);
4879 }
4880 status = sme_roam_connect(hHal, pAdapter->sessionId,
4881 &(pWextState->roamProfile), &roamId);
4882 pRoamProfile->ChannelInfo.ChannelList = NULL;
4883 pRoamProfile->ChannelInfo.numOfChannels = 0;
4884
4885 EXIT();
4886 return status;
4887}
4888
4889/**
4890 * iw_set_essid() - set essid handler function
4891 * @dev: Pointer to the net device.
4892 * @info: Pointer to the iw_request_info.
4893 * @wrqu: Pointer to the iwreq_data.
4894 * @extra: Pointer to the data.
4895 *
4896 * Return: 0 for success, error number on failure
4897 */
4898int iw_set_essid(struct net_device *dev,
4899 struct iw_request_info *info,
4900 union iwreq_data *wrqu, char *extra)
4901{
4902 int ret;
4903
4904 cds_ssr_protect(__func__);
4905 ret = __iw_set_essid(dev, info, wrqu, extra);
4906 cds_ssr_unprotect(__func__);
4907
4908 return ret;
4909}
4910
4911/**
4912 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
4913 * @dev: pointer to the net device
4914 * @info: pointer to the iw request info
4915 * @dwrq: pointer to iw_point
4916 * @extra: pointer to the data
4917 *
4918 * Return: 0 on success, error number otherwise
4919 */
4920static int __iw_get_essid(struct net_device *dev,
4921 struct iw_request_info *info,
4922 struct iw_point *dwrq, char *extra)
4923{
4924 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4925 hdd_context_t *hdd_ctx;
4926 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4927 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4928 int ret;
4929
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004930 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004931
4932 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4933 ret = wlan_hdd_validate_context(hdd_ctx);
4934 if (0 != ret)
4935 return ret;
4936
4937 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
4938 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
4939 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
4940 || pHddStaCtx->conn_info.connState ==
4941 eConnectionState_IbssDisconnected)
4942 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
4943 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
4944 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
4945 dwrq->length);
4946 dwrq->flags = 1;
4947 } else {
4948 memset(extra, 0, dwrq->length);
4949 dwrq->length = 0;
4950 dwrq->flags = 0;
4951 }
4952 EXIT();
4953 return 0;
4954}
4955
4956/**
4957 * iw_get_essid() - get essid handler function
4958 * @dev: Pointer to the net device.
4959 * @info: Pointer to the iw_request_info.
4960 * @wrqu: Pointer to the iwreq_data.
4961 * @extra: Pointer to the data.
4962 *
4963 * Return: 0 for success, error number on failure
4964 */
4965int iw_get_essid(struct net_device *dev,
4966 struct iw_request_info *info,
4967 struct iw_point *wrqu, char *extra)
4968{
4969 int ret;
4970
4971 cds_ssr_protect(__func__);
4972 ret = __iw_get_essid(dev, info, wrqu, extra);
4973 cds_ssr_unprotect(__func__);
4974
4975 return ret;
4976}
4977
4978/**
4979 * __iw_set_auth() -
4980 * This function sets the auth type received from the wpa_supplicant
4981 * @dev: pointer to the net device
4982 * @info: pointer to the iw request info
4983 * @wrqu: pointer to iwreq_data
4984 * @extra: pointer to the data
4985 *
4986 * Return: 0 on success, error number otherwise
4987 */
4988static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
4989 union iwreq_data *wrqu, char *extra)
4990{
4991 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4992 hdd_context_t *hdd_ctx;
4993 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4994 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4995 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
4996 eCsrEncryptionType mcEncryptionType;
4997 eCsrEncryptionType ucEncryptionType;
4998 int ret;
4999
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005000 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005001
5002 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5003 ret = wlan_hdd_validate_context(hdd_ctx);
5004 if (0 != ret)
5005 return ret;
5006
5007 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5008 case IW_AUTH_WPA_VERSION:
5009 pWextState->wpaVersion = wrqu->param.value;
5010 break;
5011
5012 case IW_AUTH_CIPHER_PAIRWISE:
5013 {
5014 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5015 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5016 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5017 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5018 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5019 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5020 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5021 if ((IW_AUTH_KEY_MGMT_802_1X
5022 ==
5023 (pWextState->
5024 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5025 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5026 pHddStaCtx->conn_info.authType))
5027 /*Dynamic WEP key */
5028 ucEncryptionType =
5029 eCSR_ENCRYPT_TYPE_WEP40;
5030 else
5031 /*Static WEP key */
5032 ucEncryptionType =
5033 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5034 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5035 if ((IW_AUTH_KEY_MGMT_802_1X
5036 ==
5037 (pWextState->
5038 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5039 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5040 pHddStaCtx->conn_info.authType))
5041 /*Dynamic WEP key */
5042 ucEncryptionType =
5043 eCSR_ENCRYPT_TYPE_WEP104;
5044 else
5045 /*Static WEP key */
5046 ucEncryptionType =
5047 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5048 } else {
5049 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5050 wrqu->param.value);
5051 return -EINVAL;
5052 }
5053
5054 pRoamProfile->EncryptionType.numEntries = 1;
5055 pRoamProfile->EncryptionType.encryptionType[0] =
5056 ucEncryptionType;
5057 }
5058 break;
5059 case IW_AUTH_CIPHER_GROUP:
5060 {
5061 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5062 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5063 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5064 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5065 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5066 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5067 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5068 if ((IW_AUTH_KEY_MGMT_802_1X
5069 ==
5070 (pWextState->
5071 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5072 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5073 pHddStaCtx->conn_info.authType))
5074 mcEncryptionType =
5075 eCSR_ENCRYPT_TYPE_WEP40;
5076 else
5077 mcEncryptionType =
5078 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5079 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5080 /* Dynamic WEP keys won't work with shared keys */
5081 if ((IW_AUTH_KEY_MGMT_802_1X
5082 ==
5083 (pWextState->
5084 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5085 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5086 pHddStaCtx->conn_info.authType)) {
5087 mcEncryptionType =
5088 eCSR_ENCRYPT_TYPE_WEP104;
5089 } else {
5090 mcEncryptionType =
5091 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5092 }
5093 } else {
5094 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5095 wrqu->param.value);
5096 return -EINVAL;
5097 }
5098
5099 pRoamProfile->mcEncryptionType.numEntries = 1;
5100 pRoamProfile->mcEncryptionType.encryptionType[0] =
5101 mcEncryptionType;
5102 }
5103 break;
5104
5105 case IW_AUTH_80211_AUTH_ALG:
5106 {
5107 /* Save the auth algo here and set auth type to SME Roam profile
5108 in the iw_set_ap_address */
5109 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5110 pHddStaCtx->conn_info.authType =
5111 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5112
5113 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5114 pHddStaCtx->conn_info.authType =
5115 eCSR_AUTH_TYPE_SHARED_KEY;
5116
5117 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5118 /*Not supported */
5119 pHddStaCtx->conn_info.authType =
5120 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5121 pWextState->roamProfile.AuthType.authType[0] =
5122 pHddStaCtx->conn_info.authType;
5123 }
5124 break;
5125
5126 case IW_AUTH_KEY_MGMT:
5127 {
5128#ifdef FEATURE_WLAN_ESE
5129#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5130 /*Check for CCKM AKM type */
5131 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5132 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5133 /* Set the CCKM bit in authKeyMgmt */
5134 /*
5135 * Right now, this breaks all ref to authKeyMgmt because
5136 * our code doesn't realize it is a "bitfield"
5137 */
5138 pWextState->authKeyMgmt |=
5139 IW_AUTH_KEY_MGMT_CCKM;
5140 /* Set the key management to 802.1X */
5141 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5142 pWextState->isESEConnection = true;
5143 /*
5144 * This is test code. I need to actually KNOW whether
5145 * this is an RSN Assoc or WPA.
5146 */
5147 pWextState->collectedAuthType =
5148 eCSR_AUTH_TYPE_CCKM_RSN;
5149 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5150 /* Save the key management */
5151 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5152 pWextState->collectedAuthType =
5153 eCSR_AUTH_TYPE_RSN;
5154 } else
5155 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5156 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5157 /* Save the key management anyway */
5158 pWextState->authKeyMgmt = wrqu->param.value;
5159 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5160 /* Save the key management */
5161 pWextState->authKeyMgmt |=
5162 IW_AUTH_KEY_MGMT_802_1X;
5163 pWextState->collectedAuthType =
5164 eCSR_AUTH_TYPE_RSN;
5165 }
5166#else
5167 /* Save the key management */
5168 pWextState->authKeyMgmt = wrqu->param.value;
5169#endif /* FEATURE_WLAN_ESE */
5170 }
5171 break;
5172
5173 case IW_AUTH_TKIP_COUNTERMEASURES:
5174 {
5175 if (wrqu->param.value) {
5176 hddLog(LOG2,
5177 "Counter Measure started %d",
5178 wrqu->param.value);
5179 pWextState->mTKIPCounterMeasures =
5180 TKIP_COUNTER_MEASURE_STARTED;
5181 } else {
5182 hddLog(LOG2,
5183 "Counter Measure stopped=%d",
5184 wrqu->param.value);
5185 pWextState->mTKIPCounterMeasures =
5186 TKIP_COUNTER_MEASURE_STOPED;
5187 }
5188 }
5189 break;
5190 case IW_AUTH_DROP_UNENCRYPTED:
5191 case IW_AUTH_WPA_ENABLED:
5192 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5193 case IW_AUTH_ROAMING_CONTROL:
5194 case IW_AUTH_PRIVACY_INVOKED:
5195
5196 default:
5197
5198 hddLog(LOGW, FL("called with unsupported auth type %d"),
5199 wrqu->param.flags & IW_AUTH_INDEX);
5200 break;
5201 }
5202
5203 EXIT();
5204 return 0;
5205}
5206
5207/**
5208 * iw_set_auth() - set auth callback function
5209 * @dev: Pointer to the net device.
5210 * @info: Pointer to the iw_request_info.
5211 * @wrqu: Pointer to the iwreq_data.
5212 * @extra: Pointer to the data.
5213 *
5214 * Return: 0 for success, error number on failure.
5215 */
5216int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5217 union iwreq_data *wrqu, char *extra)
5218{
5219 int ret;
5220
5221 cds_ssr_protect(__func__);
5222 ret = __iw_set_auth(dev, info, wrqu, extra);
5223 cds_ssr_unprotect(__func__);
5224
5225 return ret;
5226}
5227
5228/**
5229 * __iw_get_auth() -
5230 * This function returns the auth type to the wpa_supplicant
5231 * @dev: pointer to the net device
5232 * @info: pointer to the iw request info
5233 * @wrqu: pointer to iwreq_data
5234 * @extra: pointer to the data
5235 *
5236 * Return: 0 on success, error number otherwise
5237 */
5238static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5239 union iwreq_data *wrqu, char *extra)
5240{
5241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5242 hdd_context_t *hdd_ctx;
5243 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5244 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5245 int ret;
5246
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005247 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005248
5249 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5250 ret = wlan_hdd_validate_context(hdd_ctx);
5251 if (0 != ret)
5252 return ret;
5253
5254 switch (pRoamProfile->negotiatedAuthType) {
5255 case eCSR_AUTH_TYPE_WPA_NONE:
5256 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5257 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5258 break;
5259 case eCSR_AUTH_TYPE_WPA:
5260 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5261 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5262 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005263
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005264 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005265 case eCSR_AUTH_TYPE_RSN:
5266 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5267 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5268 break;
5269 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5270 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5271 break;
5272 case eCSR_AUTH_TYPE_SHARED_KEY:
5273 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5274 break;
5275 case eCSR_AUTH_TYPE_UNKNOWN:
5276 hddLog(LOG1, FL("called with unknown auth type"));
5277 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5278 break;
5279 case eCSR_AUTH_TYPE_AUTOSWITCH:
5280 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5281 break;
5282 case eCSR_AUTH_TYPE_WPA_PSK:
5283 hddLog(LOG1, FL("called with WPA PSK auth type"));
5284 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5285 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005286
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005287 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005288 case eCSR_AUTH_TYPE_RSN_PSK:
5289#ifdef WLAN_FEATURE_11W
5290 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5291 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5292#endif
5293 hddLog(LOG1, FL("called with RSN PSK auth type"));
5294 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5295 return -EIO;
5296 default:
5297 hddLog(LOGE, FL("called with unknown auth type"));
5298 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5299 return -EIO;
5300 }
5301 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5302 switch (pRoamProfile->negotiatedUCEncryptionType) {
5303 case eCSR_ENCRYPT_TYPE_NONE:
5304 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5305 break;
5306 case eCSR_ENCRYPT_TYPE_WEP40:
5307 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5308 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5309 break;
5310 case eCSR_ENCRYPT_TYPE_TKIP:
5311 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5312 break;
5313 case eCSR_ENCRYPT_TYPE_WEP104:
5314 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5315 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5316 break;
5317 case eCSR_ENCRYPT_TYPE_AES:
5318 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5319 break;
5320 default:
5321 hddLog(LOG1, FL("called with unknown auth type %d"),
5322 pRoamProfile->negotiatedUCEncryptionType);
5323 return -EIO;
5324 }
5325 }
5326
5327 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5328 switch (pRoamProfile->negotiatedMCEncryptionType) {
5329 case eCSR_ENCRYPT_TYPE_NONE:
5330 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5331 break;
5332 case eCSR_ENCRYPT_TYPE_WEP40:
5333 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5334 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5335 break;
5336 case eCSR_ENCRYPT_TYPE_TKIP:
5337 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5338 break;
5339 case eCSR_ENCRYPT_TYPE_WEP104:
5340 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5341 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5342 break;
5343 case eCSR_ENCRYPT_TYPE_AES:
5344 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5345 break;
5346 default:
5347 hddLog(LOG1, FL("called with unknown auth type %d"),
5348 pRoamProfile->negotiatedMCEncryptionType);
5349 return -EIO;
5350 }
5351 }
5352
5353 hddLog(LOG1, FL("called with auth type %d"),
5354 pRoamProfile->AuthType.authType[0]);
5355 EXIT();
5356 return 0;
5357}
5358
5359/**
5360 * iw_get_auth() - get auth callback function
5361 * @dev: Pointer to the net device.
5362 * @info: Pointer to the iw_request_info.
5363 * @wrqu: Pointer to the iwreq_data.
5364 * @extra: Pointer to the data.
5365 *
5366 * Return: 0 for success, error number on failure.
5367 */
5368int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5369 union iwreq_data *wrqu, char *extra)
5370{
5371 int ret;
5372
5373 cds_ssr_protect(__func__);
5374 ret = __iw_get_auth(dev, info, wrqu, extra);
5375 cds_ssr_unprotect(__func__);
5376
5377 return ret;
5378}
5379
5380/**
5381 * __iw_set_ap_address() - set ap address
5382 * @dev: pointer to the net device
5383 * @info: pointer to the iw request info
5384 * @wrqu: pointer to iwreq_data
5385 * @extra: pointer to the data
5386 *
5387 * This function updates the HDD global station context connection info
5388 * BSSID with the MAC address received from the wpa_supplicant.
5389 *
5390 * Return: 0 on success, error number otherwise
5391 */
5392static int __iw_set_ap_address(struct net_device *dev,
5393 struct iw_request_info *info,
5394 union iwreq_data *wrqu, char *extra)
5395{
5396
5397 hdd_adapter_t *adapter;
5398 hdd_context_t *hdd_ctx;
5399 hdd_station_ctx_t *pHddStaCtx =
5400 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5401 uint8_t *pMacAddress = NULL;
5402 int ret;
5403
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005404 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005405
5406 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5407
5408 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5409 ret = wlan_hdd_validate_context(hdd_ctx);
5410 if (0 != ret)
5411 return ret;
5412
5413 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5414 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305415 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305416 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005417 EXIT();
5418
5419 return 0;
5420}
5421
5422/**
5423 * iw_set_ap_address() - set ap addresses callback function
5424 * @dev: Pointer to the net device.
5425 * @info: Pointer to the iw_request_info.
5426 * @wrqu: Pointer to the iwreq_data.
5427 * @extra: Pointer to the data.
5428 *
5429 * Return: 0 for success, error number on failure.
5430 */
5431int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5432 union iwreq_data *wrqu, char *extra)
5433{
5434 int ret;
5435
5436 cds_ssr_protect(__func__);
5437 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5438 cds_ssr_unprotect(__func__);
5439
5440 return ret;
5441}
5442
5443/**
5444 * __iw_get_ap_address() - get ap address
5445 * @dev: pointer to the net device
5446 * @info: pointer to the iw request info
5447 * @wrqu: pointer to iwreq_data
5448 * @extra: pointer to the data
5449 *
5450 * This function returns currently associated BSSID.
5451 *
5452 * Return: 0 on success, error number otherwise
5453 */
5454static int __iw_get_ap_address(struct net_device *dev,
5455 struct iw_request_info *info,
5456 union iwreq_data *wrqu, char *extra)
5457{
5458 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5459 hdd_context_t *hdd_ctx;
5460 hdd_station_ctx_t *pHddStaCtx =
5461 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5462 int ret;
5463
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005464 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005465
5466 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5467 ret = wlan_hdd_validate_context(hdd_ctx);
5468 if (0 != ret)
5469 return ret;
5470
5471 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5472 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305473 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005474 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305475 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005476 } else {
5477 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5478 }
5479 EXIT();
5480 return 0;
5481}
5482
5483/**
5484 * iw_get_ap_address() - get ap addresses callback function
5485 * @dev: Pointer to the net device.
5486 * @info: Pointer to the iw_request_info.
5487 * @wrqu: Pointer to the iwreq_data.
5488 * @extra: Pointer to the data.
5489 *
5490 * Return: 0 for success, error number on failure.
5491 */
5492int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5493 union iwreq_data *wrqu, char *extra)
5494{
5495 int ret;
5496
5497 cds_ssr_protect(__func__);
5498 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5499 cds_ssr_unprotect(__func__);
5500
5501 return ret;
5502}