blob: a7d4cf5d04b59de4e6ee337e92acbc7b3d25b128 [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"
Himanshu Agarwal11c874a2016-05-06 18:35:29 +053059#include "ol_rx_fwd.h"
Dhanashri Atreb08959a2016-03-01 17:28:03 -080060#include "cdp_txrx_flow_ctrl_legacy.h"
61#include "cdp_txrx_peer_ops.h"
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080062
63/* These are needed to recognize WPA and RSN suite types */
64#define HDD_WPA_OUI_SIZE 4
65#define HDD_RSN_OUI_SIZE 4
66uint8_t ccp_wpa_oui00[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x00 };
67uint8_t ccp_wpa_oui01[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x01 };
68uint8_t ccp_wpa_oui02[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
69uint8_t ccp_wpa_oui03[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x03 };
70uint8_t ccp_wpa_oui04[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x04 };
71uint8_t ccp_wpa_oui05[HDD_WPA_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x05 };
72
73#ifdef FEATURE_WLAN_ESE
74/* CCKM */
75uint8_t ccp_wpa_oui06[HDD_WPA_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
76/* CCKM */
77uint8_t ccp_rsn_oui06[HDD_RSN_OUI_SIZE] = { 0x00, 0x40, 0x96, 0x00 };
78#endif /* FEATURE_WLAN_ESE */
79
80/* group cipher */
81uint8_t ccp_rsn_oui00[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x00 };
82
83/* WEP-40 or RSN */
84uint8_t ccp_rsn_oui01[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x01 };
85
86/* TKIP or RSN-PSK */
87uint8_t ccp_rsn_oui02[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x02 };
88
89/* Reserved */
90uint8_t ccp_rsn_oui03[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x03 };
91
92/* AES-CCMP */
93uint8_t ccp_rsn_oui04[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x04 };
94
95/* WEP-104 */
96uint8_t ccp_rsn_oui05[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
97
98#ifdef WLAN_FEATURE_11W
99/* RSN-PSK-SHA256 */
100uint8_t ccp_rsn_oui07[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x06 };
101
102/* RSN-8021X-SHA256 */
103uint8_t ccp_rsn_oui08[HDD_RSN_OUI_SIZE] = { 0x00, 0x0F, 0xAC, 0x05 };
104#endif
105
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800106/* Offset where the EID-Len-IE, start. */
107#define FT_ASSOC_RSP_IES_OFFSET 6 /* Capability(2) + AID(2) + Status Code(2) */
108#define FT_ASSOC_REQ_IES_OFFSET 4 /* Capability(2) + LI(2) */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800109
110#define BEACON_FRAME_IES_OFFSET 12
111#define HDD_PEER_AUTHORIZE_WAIT 10
112
113/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700114 * beacon_filter_table - table of IEs used for beacon filtering
115 */
116static const int beacon_filter_table[] = {
117 SIR_MAC_DS_PARAM_SET_EID,
118 SIR_MAC_ERP_INFO_EID,
119 SIR_MAC_EDCA_PARAM_SET_EID,
120 SIR_MAC_QOS_CAPABILITY_EID,
121 SIR_MAC_HT_INFO_EID,
122 SIR_MAC_VHT_OPMODE_EID,
123 SIR_MAC_VHT_OPERATION_EID,
124};
125
126/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800127 * hdd_conn_set_authenticated() - set authentication state
128 * @pAdapter: pointer to the adapter
129 * @authState: authentication state
130 *
131 * This function updates the global HDD station context
132 * authentication state.
133 *
134 * Return: none
135 */
136static void
137hdd_conn_set_authenticated(hdd_adapter_t *pAdapter, uint8_t authState)
138{
139 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
140 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
141
142 /* save the new connection state */
143 hddLog(LOG1,
144 FL("Authenticated state Changed from oldState:%d to State:%d"),
145 pHddStaCtx->conn_info.uIsAuthenticated, authState);
146 pHddStaCtx->conn_info.uIsAuthenticated = authState;
147
148 /* Check is pending ROC request or not when auth state changed */
149 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
150}
151
152/**
153 * hdd_conn_set_connection_state() - set connection state
154 * @pAdapter: pointer to the adapter
155 * @connState: connection state
156 *
157 * This function updates the global HDD station context connection state.
158 *
159 * Return: none
160 */
161void hdd_conn_set_connection_state(hdd_adapter_t *pAdapter,
162 eConnectionState connState)
163{
164 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
165 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
166
167 /* save the new connection state */
Abhishek Singh23edd1c2016-05-05 11:56:06 +0530168 hdd_info("%pS Changed connectionState Changed from oldState:%d to State:%d",
169 (void *)_RET_IP_, pHddStaCtx->conn_info.connState,
170 connState);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800171 pHddStaCtx->conn_info.connState = connState;
172
173 /* Check is pending ROC request or not when connection state changed */
174 schedule_delayed_work(&pHddCtx->roc_req_work, 0);
175}
176
177/**
178 * hdd_conn_get_connection_state() - get connection state
179 * @pAdapter: pointer to the adapter
180 * @pConnState: pointer to connection state
181 *
182 * This function updates the global HDD station context connection state.
183 *
184 * Return: true if (Infra Associated or IBSS Connected)
185 * and sets output parameter pConnState;
186 * false otherwise
187 */
188static inline bool hdd_conn_get_connection_state(hdd_station_ctx_t *pHddStaCtx,
189 eConnectionState *pConnState)
190{
191 bool fConnected = false;
192 eConnectionState connState;
193
194 /* get the connection state. */
195 connState = pHddStaCtx->conn_info.connState;
196
197 if (eConnectionState_Associated == connState ||
198 eConnectionState_IbssConnected == connState ||
199 eConnectionState_IbssDisconnected == connState) {
200 fConnected = true;
201 }
202
203 if (pConnState)
204 *pConnState = connState;
205
206 return fConnected;
207}
208
209/**
210 * hdd_is_connecting() - Function to check connection progress
211 * @hdd_sta_ctx: pointer to global HDD Station context
212 *
213 * Return: true if connecting, false otherwise
214 */
215bool hdd_is_connecting(hdd_station_ctx_t *hdd_sta_ctx)
216{
217 return hdd_sta_ctx->conn_info.connState ==
218 eConnectionState_Connecting;
219}
220
221/**
222 * hdd_conn_is_connected() - Function to check connection status
223 * @pHddStaCtx: pointer to global HDD Station context
224 *
225 * Return: false if any errors encountered, true otherwise
226 */
227bool hdd_conn_is_connected(hdd_station_ctx_t *pHddStaCtx)
228{
229 return hdd_conn_get_connection_state(pHddStaCtx, NULL);
230}
231
232/**
233 * hdd_conn_get_connected_band() - get current connection radio band
234 * @pHddStaCtx: pointer to global HDD Station context
235 *
236 * Return: eCSR_BAND_24 or eCSR_BAND_5G based on current AP connection
237 * eCSR_BAND_ALL if not connected
238 */
239eCsrBand hdd_conn_get_connected_band(hdd_station_ctx_t *pHddStaCtx)
240{
241 uint8_t staChannel = 0;
242
243 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
244 staChannel = pHddStaCtx->conn_info.operationChannel;
245
246 if (staChannel > 0 && staChannel < 14)
247 return eCSR_BAND_24;
248 else if (staChannel >= 36 && staChannel <= 184)
249 return eCSR_BAND_5G;
250 else /* If station is not connected return as eCSR_BAND_ALL */
251 return eCSR_BAND_ALL;
252}
253
254/**
255 * hdd_conn_get_connected_cipher_algo() - get current connection cipher type
256 * @pHddStaCtx: pointer to global HDD Station context
257 * @pConnectedCipherAlgo: pointer to connected cipher algo
258 *
259 * Return: false if any errors encountered, true otherwise
260 */
261static inline bool
262hdd_conn_get_connected_cipher_algo(hdd_station_ctx_t *pHddStaCtx,
263 eCsrEncryptionType *pConnectedCipherAlgo)
264{
265 bool fConnected = false;
266
267 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
268
269 if (pConnectedCipherAlgo)
270 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
271
272 return fConnected;
273}
274
275/**
276 * hdd_conn_get_connected_bss_type() - get current bss type
277 * @pHddStaCtx: pointer to global HDD Station context
278 * @pConnectedBssType: pointer to connected bss type
279 *
280 * Return: false if any errors encountered, true otherwise
281 */
282inline bool
283hdd_conn_get_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
284 eMib_dot11DesiredBssType *pConnectedBssType)
285{
286 bool fConnected = false;
287
288 fConnected = hdd_conn_get_connection_state(pHddStaCtx, NULL);
289
290 if (pConnectedBssType) {
291 *pConnectedBssType =
292 pHddStaCtx->conn_info.connDot11DesiredBssType;
293 }
294
295 return fConnected;
296}
297
298/**
299 * hdd_conn_save_connected_bss_type() - set connected bss type
300 * @pHddStaCtx: pointer to global HDD Station context
301 * @csr_roamBssType: bss type
302 *
303 * Return: none
304 */
305static inline void
306hdd_conn_save_connected_bss_type(hdd_station_ctx_t *pHddStaCtx,
307 eCsrRoamBssType csr_roamBssType)
308{
309 switch (csr_roamBssType) {
310 case eCSR_BSS_TYPE_INFRASTRUCTURE:
311 pHddStaCtx->conn_info.connDot11DesiredBssType =
312 eMib_dot11DesiredBssType_infrastructure;
313 break;
314
315 case eCSR_BSS_TYPE_IBSS:
316 case eCSR_BSS_TYPE_START_IBSS:
317 pHddStaCtx->conn_info.connDot11DesiredBssType =
318 eMib_dot11DesiredBssType_independent;
319 break;
320
321 /** We will never set the BssType to 'any' when attempting a connection
322 so CSR should never send this back to us.*/
323 case eCSR_BSS_TYPE_ANY:
324 default:
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530325 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800326 break;
327 }
328}
329
330/**
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -0700331 * hdd_remove_beacon_filter() - remove beacon filter
332 * @adapter: Pointer to the hdd adapter
333 *
334 * Return: 0 on success and errno on failure
335 */
336static int hdd_remove_beacon_filter(hdd_adapter_t *adapter)
337{
338 QDF_STATUS status;
339 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
340
341 status = sme_remove_beacon_filter(hdd_ctx->hHal,
342 adapter->sessionId);
343 if (!QDF_IS_STATUS_SUCCESS(status)) {
344 hdd_err("sme_remove_beacon_filter() failed");
345 return -EFAULT;
346 }
347
348 return 0;
349}
350
351/**
352 * hdd_add_beacon_filter() - add beacon filter
353 * @adapter: Pointer to the hdd adapter
354 *
355 * Return: 0 on success and errno on failure
356 */
357static int hdd_add_beacon_filter(hdd_adapter_t *adapter)
358{
359 int i;
360 uint32_t ie_map[SIR_BCN_FLT_MAX_ELEMS_IE_LIST] = {0};
361 QDF_STATUS status;
362 hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
363
364 for (i = 0; i < ARRAY_SIZE(beacon_filter_table); i++)
365 qdf_set_bit((beacon_filter_table[i] - 1),
366 (unsigned long int *)ie_map);
367
368 status = sme_add_beacon_filter(hdd_ctx->hHal,
369 adapter->sessionId, ie_map);
370 if (!QDF_IS_STATUS_SUCCESS(status)) {
371 hdd_err("sme_add_beacon_filter() failed");
372 return -EFAULT;
373 }
374 return 0;
375}
376
377/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800378 * hdd_conn_save_connect_info() - save current connection information
379 * @pAdapter: pointer to adapter
380 * @pRoamInfo: pointer to roam info
381 * @eBssType: bss type
382 *
383 * Return: none
384 */
385static void
386hdd_conn_save_connect_info(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
387 eCsrRoamBssType eBssType)
388{
389 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
390 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
391
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530392 QDF_ASSERT(pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800393
394 if (pRoamInfo) {
395 /* Save the BSSID for the connection */
396 if (eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530397 QDF_ASSERT(pRoamInfo->pBssDesc);
Anurag Chouhanc5548422016-02-24 18:33:27 +0530398 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 &pRoamInfo->bssid);
400
401 /*
402 * Save the Station ID for this station from
403 * the 'Roam Info'. For IBSS mode, staId is
404 * assigned in NEW_PEER_IND. For reassoc,
405 * the staID doesn't change and it may be invalid
406 * in this structure so no change here.
407 */
408 if (!pRoamInfo->fReassocReq) {
409 pHddStaCtx->conn_info.staId[0] =
410 pRoamInfo->staId;
411 }
412 } else if (eCSR_BSS_TYPE_IBSS == eBssType) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530413 qdf_copy_macaddr(&pHddStaCtx->conn_info.bssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800414 &pRoamInfo->bssid);
415 } else {
416 /*
417 * can't happen. We need a valid IBSS or Infra setting
418 * in the BSSDescription or we can't function.
419 */
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530420 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800421 }
422
423 /* notify WMM */
424 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
425
426 if (!pRoamInfo->u.pConnectedProfile) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530427 QDF_ASSERT(pRoamInfo->u.pConnectedProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800428 } else {
429 /* Get Multicast Encryption Type */
430 encryptType =
431 pRoamInfo->u.pConnectedProfile->mcEncryptionType;
432 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
433 /* Get Unicast Encryption Type */
434 encryptType =
435 pRoamInfo->u.pConnectedProfile->EncryptionType;
436 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
437
438 pHddStaCtx->conn_info.authType =
439 pRoamInfo->u.pConnectedProfile->AuthType;
440
441 pHddStaCtx->conn_info.operationChannel =
442 pRoamInfo->u.pConnectedProfile->operationChannel;
443
444 /* Save the ssid for the connection */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530445 qdf_mem_copy(&pHddStaCtx->conn_info.SSID.SSID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800446 &pRoamInfo->u.pConnectedProfile->SSID,
447 sizeof(tSirMacSSid));
448
449 /* Save dot11mode in which STA associated to AP */
450 pHddStaCtx->conn_info.dot11Mode =
451 pRoamInfo->u.pConnectedProfile->dot11Mode;
452
453 pHddStaCtx->conn_info.proxyARPService =
454 pRoamInfo->u.pConnectedProfile->proxyARPService;
Kanchanapally, Vidyullathae3062812015-05-22 17:28:57 +0530455
456 pHddStaCtx->conn_info.nss = pRoamInfo->chan_info.nss;
457
458 pHddStaCtx->conn_info.rate_flags =
459 pRoamInfo->chan_info.rate_flags;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800460 }
461 }
462 /* save the connected BssType */
463 hdd_conn_save_connected_bss_type(pHddStaCtx, eBssType);
464}
465
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800466/**
467 * hdd_send_ft_assoc_response() - send fast transition assoc response
468 * @dev: pointer to net device
469 * @pAdapter: pointer to adapter
470 * @pCsrRoamInfo: pointer to roam info
471 *
472 * Send the 11R key information to the supplicant. Only then can the supplicant
473 * generate the PMK-R1. (BTW, the ESE supplicant also needs the Assoc Resp IEs
474 * for the same purpose.)
475 *
476 * Mainly the Assoc Rsp IEs are passed here. For the IMDA this contains the
477 * R1KHID, R0KHID and the MDID. For FT, this consists of the Reassoc Rsp FTIEs.
478 * This is the Assoc Response.
479 *
480 * Return: none
481 */
482static void
483hdd_send_ft_assoc_response(struct net_device *dev,
484 hdd_adapter_t *pAdapter,
485 tCsrRoamInfo *pCsrRoamInfo)
486{
487 union iwreq_data wrqu;
488 char *buff;
489 unsigned int len = 0;
490 u8 *pFTAssocRsp = NULL;
491
492 if (pCsrRoamInfo->nAssocRspLength == 0) {
493 hddLog(LOGE,
494 FL("pCsrRoamInfo->nAssocRspLength=%d"),
495 (int)pCsrRoamInfo->nAssocRspLength);
496 return;
497 }
498
499 pFTAssocRsp =
500 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
501 pCsrRoamInfo->nAssocReqLength);
502 if (pFTAssocRsp == NULL) {
503 hddLog(LOGE, FL("AssocReq or AssocRsp is NULL"));
504 return;
505 }
506 /* pFTAssocRsp needs to point to the IEs */
507 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
508 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
509 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
510
511 /* We need to send the IEs to the supplicant. */
512 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
513 if (buff == NULL) {
514 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
515 return;
516 }
517 /* Send the Assoc Resp, the supplicant needs this for initial Auth. */
518 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
519 wrqu.data.length = len;
520 memset(buff, 0, IW_GENERIC_IE_MAX);
521 memcpy(buff, pFTAssocRsp, len);
522 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
523
524 kfree(buff);
525}
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800526
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800527/**
528 * hdd_send_ft_event() - send fast transition event
529 * @pAdapter: pointer to adapter
530 *
531 * Send the FTIEs, RIC IEs during FT. This is eventually used to send the
532 * FT events to the supplicant. At the reception of Auth2 we send the RIC
533 * followed by the auth response IEs to the supplicant.
534 * Once both are received in the supplicant, an FT event is generated
535 * to the supplicant.
536 *
537 * Return: none
538 */
539static void hdd_send_ft_event(hdd_adapter_t *pAdapter)
540{
541 uint16_t auth_resp_len = 0;
542 uint32_t ric_ies_length = 0;
543 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
544
545#if defined(KERNEL_SUPPORT_11R_CFG80211)
546 struct cfg80211_ft_event_params ftEvent;
547 uint8_t ftIe[DOT11F_IE_FTINFO_MAX_LEN];
548 uint8_t ricIe[DOT11F_IE_RICDESCRIPTOR_MAX_LEN];
549 struct net_device *dev = pAdapter->dev;
550#else
551 char *buff;
552 union iwreq_data wrqu;
553 uint16_t str_len;
554#endif
555
556#if defined(KERNEL_SUPPORT_11R_CFG80211)
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530557 qdf_mem_zero(ftIe, DOT11F_IE_FTINFO_MAX_LEN);
558 qdf_mem_zero(ricIe, DOT11F_IE_RICDESCRIPTOR_MAX_LEN);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800559
560 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId, (u8 *) ricIe,
561 DOT11F_IE_RICDESCRIPTOR_MAX_LEN, &ric_ies_length);
562 if (ric_ies_length == 0) {
563 hddLog(LOGW,
564 FL("RIC IEs is of length 0 not sending RIC Information for now"));
565 }
566
567 ftEvent.ric_ies = ricIe;
568 ftEvent.ric_ies_len = ric_ies_length;
569 hddLog(LOG1, FL("RIC IEs is of length %d"), (int)ric_ies_length);
570
571 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
572 (u8 *) ftIe, DOT11F_IE_FTINFO_MAX_LEN,
573 &auth_resp_len);
574
575 if (auth_resp_len == 0) {
576 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
577 return;
578 }
579
580 sme_set_ft_pre_auth_state(pHddCtx->hHal, pAdapter->sessionId, true);
581
582 ftEvent.target_ap = ftIe;
583
Anurag Chouhan6d760662016-02-20 16:05:43 +0530584 ftEvent.ies = (u8 *) (ftIe + QDF_MAC_ADDR_SIZE);
585 ftEvent.ies_len = auth_resp_len - QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800586
587 hddLog(LOG1, FL("ftEvent.ies_len %zu"), ftEvent.ies_len);
588 hddLog(LOG1, FL("ftEvent.ric_ies_len %zu"), ftEvent.ric_ies_len);
589 hddLog(LOG1, FL("ftEvent.target_ap %2x-%2x-%2x-%2x-%2x-%2x"),
590 ftEvent.target_ap[0], ftEvent.target_ap[1],
591 ftEvent.target_ap[2], ftEvent.target_ap[3], ftEvent.target_ap[4],
592 ftEvent.target_ap[5]);
593
594 (void)cfg80211_ft_event(dev, &ftEvent);
595
596#else
597 /* We need to send the IEs to the supplicant */
598 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
599 if (buff == NULL) {
600 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
601 return;
602 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530603 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800604
605 /* Sme needs to send the RIC IEs first */
606 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
607 sme_get_rici_es(pHddCtx->hHal, pAdapter->sessionId,
608 (u8 *) &(buff[str_len]), (IW_CUSTOM_MAX - str_len),
609 &ric_ies_length);
610 if (ric_ies_length == 0) {
611 hddLog(LOGW,
612 FL("RIC IEs is of length 0 not sending RIC Information for now"));
613 } else {
614 wrqu.data.length = str_len + ric_ies_length;
615 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
616 }
617
618 /* Sme needs to provide the Auth Resp */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530619 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800620 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
621 sme_get_ft_pre_auth_response(pHddCtx->hHal, pAdapter->sessionId,
622 (u8 *) &buff[str_len],
623 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
624
625 if (auth_resp_len == 0) {
626 kfree(buff);
627 hddLog(LOGE, FL("AuthRsp FTIES is of length 0"));
628 return;
629 }
630
631 wrqu.data.length = str_len + auth_resp_len;
632 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
633
634 kfree(buff);
635#endif
636}
637
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800638#ifdef FEATURE_WLAN_ESE
639/**
640 * hdd_send_new_ap_channel_info() - send new ap channel info
641 * @dev: pointer to net device
642 * @pAdapter: pointer to adapter
643 * @pCsrRoamInfo: pointer to roam info
644 *
645 * Send the ESE required "new AP Channel info" to the supplicant.
646 * (This keeps the supplicant "up to date" on the current channel.)
647 *
648 * The current (new AP) channel information is passed in.
649 *
650 * Return: none
651 */
652static void
653hdd_send_new_ap_channel_info(struct net_device *dev, hdd_adapter_t *pAdapter,
654 tCsrRoamInfo *pCsrRoamInfo)
655{
656 union iwreq_data wrqu;
657 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
658
659 if (descriptor == NULL) {
660 hddLog(LOGE, FL("pCsrRoamInfo->pBssDesc(%p)"), descriptor);
661 return;
662 }
663 /*
664 * Send the Channel event, the supplicant needs this to generate
665 * the Adjacent AP report.
666 */
667 hddLog(LOGW, FL("Sending up an SIOCGIWFREQ, channelId(%d)"),
668 descriptor->channelId);
669 memset(&wrqu, '\0', sizeof(wrqu));
670 wrqu.freq.m = descriptor->channelId;
671 wrqu.freq.e = 0;
672 wrqu.freq.i = 0;
673 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
674}
675
676#endif /* FEATURE_WLAN_ESE */
677
678/**
679 * hdd_send_update_beacon_ies_event() - send update beacons ie event
680 * @pAdapter: pointer to adapter
681 * @pCsrRoamInfo: pointer to roam info
682 *
683 * Return: none
684 */
685static void
686hdd_send_update_beacon_ies_event(hdd_adapter_t *pAdapter,
687 tCsrRoamInfo *pCsrRoamInfo)
688{
689 union iwreq_data wrqu;
690 u8 *pBeaconIes;
691 u8 currentLen = 0;
692 char *buff;
693 int totalIeLen = 0, currentOffset = 0, strLen;
694
695 memset(&wrqu, '\0', sizeof(wrqu));
696
697 if (0 == pCsrRoamInfo->nBeaconLength) {
698 hddLog(LOGW, FL("pCsrRoamInfo->nBeaconFrameLength = 0"));
699 return;
700 }
701 pBeaconIes = (u8 *) (pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
702 if (pBeaconIes == NULL) {
703 hddLog(LOGW, FL("Beacon IEs is NULL"));
704 return;
705 }
706 /* pBeaconIes needs to point to the IEs */
707 hddLog(LOG1, FL("Beacon IEs is now at %02x%02x"),
708 (unsigned int)pBeaconIes[0], (unsigned int)pBeaconIes[1]);
709 hddLog(LOG1, FL("Beacon IEs length = %d"),
710 pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
711
712 /* We need to send the IEs to the supplicant. */
713 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
714 if (buff == NULL) {
715 hddLog(LOGE, FL("kmalloc unable to allocate memory"));
716 return;
717 }
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530718 qdf_mem_zero(buff, IW_CUSTOM_MAX);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800719
720 strLen = strlcpy(buff, "BEACONIEs=", IW_CUSTOM_MAX);
721 currentLen = strLen + 1;
722
723 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
724 do {
725 /*
726 * If the beacon size exceeds max CUSTOM event size, break it
727 * into chunks of CUSTOM event max size and send it to
728 * supplicant. Changes are done in supplicant to handle this.
729 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530730 qdf_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800731 currentLen =
Anurag Chouhan6d760662016-02-20 16:05:43 +0530732 QDF_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530733 qdf_mem_copy(&buff[strLen + 1], pBeaconIes + currentOffset,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800734 currentLen);
735 currentOffset += currentLen;
736 totalIeLen -= currentLen;
737 wrqu.data.length = strLen + 1 + currentLen;
738 if (totalIeLen)
739 buff[strLen] = 1; /* more chunks pending */
740 else
741 buff[strLen] = 0; /* last chunk */
742
743 hddLog(LOG1, FL("Beacon IEs length to supplicant = %d"),
744 currentLen);
745 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
746 } while (totalIeLen > 0);
747
748 kfree(buff);
749}
750
751/**
752 * hdd_send_association_event() - send association event
753 * @dev: pointer to net device
754 * @pCsrRoamInfo: pointer to roam info
755 *
756 * Return: none
757 */
758static void hdd_send_association_event(struct net_device *dev,
759 tCsrRoamInfo *pCsrRoamInfo)
760{
761 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
762 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
763 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
764 union iwreq_data wrqu;
765 int we_event;
766 char *msg;
Anurag Chouhan6d760662016-02-20 16:05:43 +0530767 struct qdf_mac_addr peerMacAddr;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800768
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800769 /* Added to find the auth type on the fly at run time */
770 /* rather than with cfg to see if FT is enabled */
771 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
772 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800773
774 memset(&wrqu, '\0', sizeof(wrqu));
775 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
776 we_event = SIOCGIWAP;
777#ifdef WLAN_FEATURE_ROAM_OFFLOAD
778 if (NULL != pCsrRoamInfo)
779 if (pCsrRoamInfo->roamSynchInProgress)
780 /* change logging before release */
781 hddLog(LOG4, "LFR3:hdd_send_association_event");
782#endif
783 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) {
784 if (!pCsrRoamInfo) {
785 hddLog(LOGE, FL("STA in associated state but pCsrRoamInfo is null"));
786 return;
787 }
788
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -0800789 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
790 cds_incr_active_session(pAdapter->device_mode,
791 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800792 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId,
793 sizeof(pCsrRoamInfo->pBssDesc->bssId));
794
795#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -0800796 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800797 if (global_p2p_connection_status ==
798 P2P_CLIENT_CONNECTING_STATE_1) {
799 global_p2p_connection_status =
800 P2P_CLIENT_CONNECTED_STATE_1;
801 hddLog(LOGE,
802 "[P2P State] Changing state from Connecting state to Connected State for 8-way Handshake");
803 } else if (global_p2p_connection_status ==
804 P2P_CLIENT_CONNECTING_STATE_2) {
805 global_p2p_connection_status =
806 P2P_CLIENT_COMPLETED_STATE;
807 hddLog(LOGE,
808 "[P2P State] Changing state from Connecting state to P2P Client Connection Completed");
809 }
810 }
811#endif
812 pr_info("wlan: " MAC_ADDRESS_STR " connected to "
813 MAC_ADDRESS_STR "\n",
814 MAC_ADDR_ARRAY(pAdapter->macAddressCurrent.bytes),
815 MAC_ADDR_ARRAY(wrqu.ap_addr.sa_data));
816 hdd_send_update_beacon_ies_event(pAdapter, pCsrRoamInfo);
817
818 /*
819 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS
820 * is Enabled Or Send IWEVASSOCRESPIE Event if
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -0800821 * fFTEnable is true.
822 * Send FT Keys to the supplicant when FT is enabled
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800823 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800824 if ((pRoamProfile->AuthType.authType[0] ==
825 eCSR_AUTH_TYPE_FT_RSN_PSK)
826 || (pRoamProfile->AuthType.authType[0] ==
827 eCSR_AUTH_TYPE_FT_RSN)
828#ifdef FEATURE_WLAN_ESE
829 || (pRoamProfile->AuthType.authType[0] ==
830 eCSR_AUTH_TYPE_CCKM_RSN)
831 || (pRoamProfile->AuthType.authType[0] ==
832 eCSR_AUTH_TYPE_CCKM_WPA)
833#endif
834 ) {
835 hdd_send_ft_assoc_response(dev, pAdapter, pCsrRoamInfo);
836 }
Krunal Sonibe766b02016-03-10 13:00:44 -0800837 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800838 tSirSmeChanInfo chan_info;
Anurag Chouhanc5548422016-02-24 18:33:27 +0530839 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800840 &pHddStaCtx->conn_info.bssId);
841 chan_info.chan_id = pCsrRoamInfo->chan_info.chan_id;
842 chan_info.mhz = pCsrRoamInfo->chan_info.mhz;
843 chan_info.info = pCsrRoamInfo->chan_info.info;
844 chan_info.band_center_freq1 =
845 pCsrRoamInfo->chan_info.band_center_freq1;
846 chan_info.band_center_freq2 =
847 pCsrRoamInfo->chan_info.band_center_freq2;
848 chan_info.reg_info_1 =
849 pCsrRoamInfo->chan_info.reg_info_1;
850 chan_info.reg_info_2 =
851 pCsrRoamInfo->chan_info.reg_info_2;
852
853 /* send peer status indication to oem app */
854 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
855 ePeerConnected,
856 pCsrRoamInfo->
857 timingMeasCap,
858 pAdapter->sessionId,
859 &chan_info);
860 }
861#ifdef MSM_PLATFORM
862#ifdef CONFIG_CNSS
863 /* start timer in sta/p2p_cli */
864 spin_lock_bh(&pHddCtx->bus_bw_lock);
865 pAdapter->prev_tx_packets = pAdapter->stats.tx_packets;
866 pAdapter->prev_rx_packets = pAdapter->stats.rx_packets;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530867 ol_get_intra_bss_fwd_pkts_count(pAdapter->sessionId,
868 &pAdapter->prev_fwd_tx_packets,
869 &pAdapter->prev_fwd_rx_packets);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800870 spin_unlock_bh(&pHddCtx->bus_bw_lock);
871 hdd_start_bus_bw_compute_timer(pAdapter);
872#endif
873#endif
874 } else if (eConnectionState_IbssConnected == /* IBss Associated */
875 pHddStaCtx->conn_info.connState) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800876 cds_update_connection_info(pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800877 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId.bytes,
878 ETH_ALEN);
879 pr_info("wlan: new IBSS connection to " MAC_ADDRESS_STR "\n",
880 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes));
881 } else { /* Not Associated */
882
883 pr_info("wlan: disconnected\n");
884 memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +0530885 cds_decr_session_set_pcl(pAdapter->device_mode,
886 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800887 wlan_hdd_enable_roaming(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800888
889#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
890 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
891#endif
892
Krunal Sonibe766b02016-03-10 13:00:44 -0800893 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Anurag Chouhanc5548422016-02-24 18:33:27 +0530894 qdf_copy_macaddr(&peerMacAddr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800895 &pHddStaCtx->conn_info.bssId);
896
897 /* send peer status indication to oem app */
898 hdd_send_peer_status_ind_to_oem_app(&peerMacAddr,
899 ePeerDisconnected, 0,
900 pAdapter->sessionId,
901 NULL);
902 }
903#ifdef WLAN_FEATURE_LPSS
904 pAdapter->rssi_send = false;
905 wlan_hdd_send_status_pkg(pAdapter, pHddStaCtx, 1, 0);
906#endif
907#ifdef FEATURE_WLAN_TDLS
Krunal Sonibe766b02016-03-10 13:00:44 -0800908 if ((pAdapter->device_mode == QDF_STA_MODE) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800909 (pCsrRoamInfo)) {
910 hddLog(LOG4,
911 FL("tdls_prohibited: %d, tdls_chan_swit_prohibited: %d"),
912 pCsrRoamInfo->tdls_prohibited,
913 pCsrRoamInfo->tdls_chan_swit_prohibited);
914
915 wlan_hdd_update_tdls_info(pAdapter,
916 pCsrRoamInfo->tdls_prohibited,
917 pCsrRoamInfo->tdls_chan_swit_prohibited);
918 }
919#endif
920#ifdef MSM_PLATFORM
921 /* stop timer in sta/p2p_cli */
922 spin_lock_bh(&pHddCtx->bus_bw_lock);
923 pAdapter->prev_tx_packets = 0;
924 pAdapter->prev_rx_packets = 0;
Himanshu Agarwal5ac2f7b2016-05-06 20:08:10 +0530925 pAdapter->prev_fwd_tx_packets = 0;
926 pAdapter->prev_fwd_rx_packets = 0;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800927 spin_unlock_bh(&pHddCtx->bus_bw_lock);
928 hdd_stop_bus_bw_compute_timer(pAdapter);
929#endif
930 }
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -0800931 cds_dump_concurrency_info();
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800932 /* Send SCC/MCC Switching event to IPA */
933 hdd_ipa_send_mcc_scc_msg(pHddCtx, pHddCtx->mcc_mode);
934
935 msg = NULL;
936 /*During the WLAN uninitialization,supplicant is stopped before the
937 driver so not sending the status of the connection to supplicant */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -0800938 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800939 wireless_send_event(dev, we_event, &wrqu, msg);
940#ifdef FEATURE_WLAN_ESE
941 if (eConnectionState_Associated ==
942 pHddStaCtx->conn_info.connState) {
943 if ((pRoamProfile->AuthType.authType[0] ==
944 eCSR_AUTH_TYPE_CCKM_RSN) ||
945 (pRoamProfile->AuthType.authType[0] ==
946 eCSR_AUTH_TYPE_CCKM_WPA))
947 hdd_send_new_ap_channel_info(dev, pAdapter,
948 pCsrRoamInfo);
949 }
950#endif
951 }
952}
953
954/**
955 * hdd_conn_remove_connect_info() - remove connection info
956 * @pHddStaCtx: pointer to global HDD station context
957 * @pCsrRoamInfo: pointer to roam info
958 *
959 * Return: none
960 */
961static void hdd_conn_remove_connect_info(hdd_station_ctx_t *pHddStaCtx)
962{
963 /* Remove staId, bssId and peerMacAddress */
964 pHddStaCtx->conn_info.staId[0] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530965 qdf_mem_zero(&pHddStaCtx->conn_info.bssId, QDF_MAC_ADDR_SIZE);
966 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[0],
Anurag Chouhan6d760662016-02-20 16:05:43 +0530967 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800968
969 /* Clear all security settings */
970 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
971 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
972 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
973
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530974 qdf_mem_zero(&pHddStaCtx->conn_info.Keys, sizeof(tCsrKeys));
975 qdf_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800976
977 /* Set not-connected state */
978 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
979 pHddStaCtx->conn_info.proxyARPService = 0;
980
Anurag Chouhan600c3a02016-03-01 10:33:54 +0530981 qdf_mem_zero(&pHddStaCtx->conn_info.SSID, sizeof(tCsrSSIDInfo));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800982}
983
984/**
985 * hdd_roam_deregister_sta() - deregister station
986 * @pAdapter: pointer to adapter
987 * @staId: station identifier
988 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530989 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800990 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530991static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800992hdd_roam_deregister_sta(hdd_adapter_t *pAdapter, uint8_t staId)
993{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +0530994 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800995 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
996
997 if (eConnectionState_IbssDisconnected ==
998 pHddStaCtx->conn_info.connState) {
999 /*
1000 * Do not set the carrier off when the last peer leaves.
1001 * We will set the carrier off while stopping the IBSS.
1002 */
1003 }
1004
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301005 qdf_status = ol_txrx_clear_peer(staId);
1006 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001007 hddLog(LOGE,
1008 FL("ol_txrx_clear_peer() failed for staID %d. Status(%d) [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301009 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001010 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301011 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001012}
1013
1014/**
1015 * hdd_dis_connect_handler() - disconnect event handler
1016 * @pAdapter: pointer to adapter
1017 * @pRoamInfo: pointer to roam info
1018 * @roamId: roam identifier
1019 * @roamStatus: roam status
1020 * @roamResult: roam result
1021 *
1022 * This function handles disconnect event:
1023 * 1. Disable transmit queues;
1024 * 2. Clean up internal connection states and data structures;
1025 * 3. Send disconnect indication to supplicant.
1026 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301027 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001028 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301029static QDF_STATUS hdd_dis_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001030 tCsrRoamInfo *pRoamInfo,
1031 uint32_t roamId,
1032 eRoamCmdStatus roamStatus,
1033 eCsrRoamResult roamResult)
1034{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301035 QDF_STATUS status = QDF_STATUS_SUCCESS;
1036 QDF_STATUS vstatus;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001037 struct net_device *dev = pAdapter->dev;
1038 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1039 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1040 uint8_t sta_id;
1041 bool sendDisconInd = true;
1042
1043 if (dev == NULL) {
1044 hddLog(LOGE, FL("net_dev is released return"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301045 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001046 }
1047 /* notify apps that we can't pass traffic anymore */
1048 hddLog(LOG1, FL("Disabling queues"));
1049 wlan_hdd_netif_queue_control(pAdapter, WLAN_NETIF_TX_DISABLE_N_CARRIER,
1050 WLAN_CONTROL_PATH);
1051
1052 if (hdd_ipa_is_enabled(pHddCtx))
1053 hdd_ipa_wlan_evt(pAdapter, pHddStaCtx->conn_info.staId[0],
1054 WLAN_STA_DISCONNECT,
1055 pHddStaCtx->conn_info.bssId.bytes);
1056
1057#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1058 wlan_hdd_auto_shutdown_enable(pHddCtx, true);
1059#endif
1060
1061#ifdef QCA_PKT_PROTO_TRACE
1062 /* STA disconnected, update into trace buffer */
1063 if (pHddCtx->config->gEnableDebugLog)
1064 cds_pkt_trace_buf_update("ST:DISASC");
1065#endif /* QCA_PKT_PROTO_TRACE */
1066
1067 /* HDD has initiated disconnect, do not send disconnect indication
1068 * to kernel. Sending disconnected event to kernel for userspace
1069 * initiated disconnect will be handled by hdd_DisConnectHandler call
1070 * to cfg80211_disconnected.
1071 */
1072 if ((eConnectionState_Disconnecting ==
1073 pHddStaCtx->conn_info.connState) ||
1074 (eConnectionState_NotConnected ==
1075 pHddStaCtx->conn_info.connState)) {
1076 hddLog(LOG1,
1077 FL("HDD has initiated a disconnect, no need to send disconnect indication to kernel"));
1078 sendDisconInd = false;
1079 }
1080
1081 if (pHddStaCtx->conn_info.connState != eConnectionState_Disconnecting) {
1082 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001083 hdd_conn_set_connection_state(pAdapter,
1084 eConnectionState_Disconnecting);
1085 }
1086
1087 hdd_clear_roam_profile_ie(pAdapter);
1088 hdd_wmm_init(pAdapter);
1089
1090 /* indicate 'disconnect' status to wpa_supplicant... */
1091 hdd_send_association_event(dev, pRoamInfo);
1092 /* indicate disconnected event to nl80211 */
1093 if (roamStatus != eCSR_ROAM_IBSS_LEAVE) {
1094 /*
1095 * Only send indication to kernel if not initiated
1096 * by kernel
1097 */
1098 if (sendDisconInd) {
1099 /*
1100 * To avoid wpa_supplicant sending "HANGED" CMD
1101 * to ICS UI.
1102 */
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001103 if (eCSR_ROAM_LOSTLINK == roamStatus) {
1104 if (pRoamInfo->reasonCode ==
1105 eSIR_MAC_PEER_STA_REQ_LEAVING_BSS_REASON)
1106 pr_info("wlan: disconnected due to poor signal, rssi is %d dB\n", pRoamInfo->rxRssi);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001107 cfg80211_disconnected(dev, pRoamInfo->
Ryan Hsua335c162016-01-21 12:12:20 -08001108 reasonCode, NULL, 0,
1109#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1110 true,
1111#endif
1112 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001113 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001114 cfg80211_disconnected(dev,
Ryan Hsua335c162016-01-21 12:12:20 -08001115 WLAN_REASON_UNSPECIFIED, NULL, 0,
1116#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || defined(WITH_BACKPORTS)
1117 true,
1118#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001119 GFP_KERNEL);
Kiran Kumar Lokere37d3aa22015-11-03 14:58:26 -08001120 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001121
1122 hdd_info("sent disconnected event to nl80211, rssi: %d",
1123 pAdapter->rssi);
1124 }
1125 /*
1126 * During the WLAN uninitialization,supplicant is stopped
1127 * before the driver so not sending the status of the
1128 * connection to supplicant.
1129 */
Rajeev Kumarfec3dbe2016-01-19 15:23:52 -08001130 if (cds_is_load_or_unload_in_progress()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001131#ifdef WLAN_FEATURE_P2P_DEBUG
Krunal Sonibe766b02016-03-10 13:00:44 -08001132 if (pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001133 if (global_p2p_connection_status ==
1134 P2P_CLIENT_CONNECTED_STATE_1) {
1135 global_p2p_connection_status =
1136 P2P_CLIENT_DISCONNECTED_STATE;
1137 hddLog(LOGE,
1138 "[P2P State] 8 way Handshake completed and moved to disconnected state");
1139 } else if (global_p2p_connection_status ==
1140 P2P_CLIENT_COMPLETED_STATE) {
1141 global_p2p_connection_status =
1142 P2P_NOT_ACTIVE;
1143 hddLog(LOGE,
1144 "[P2P State] P2P Client is removed and moved to inactive state");
1145 }
1146 }
1147#endif
1148
1149 }
1150 }
1151
1152 hdd_wmm_adapter_clear(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001153 sme_ft_reset(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001154 if (hdd_remove_beacon_filter(pAdapter) != 0)
1155 hdd_err("hdd_remove_beacon_filter() failed");
1156
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001157 if (eCSR_ROAM_IBSS_LEAVE == roamStatus) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301158 uint8_t i;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301159 sta_id = pHddStaCtx->broadcast_ibss_staid;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001160 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301161 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05301162 hdd_err("hdd_roam_deregister_sta() failed for staID %d Status=%d [0x%x]",
1163 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301164 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001165 }
1166 pHddCtx->sta_to_adapter[sta_id] = NULL;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301167 /* Clear all the peer sta register with TL. */
1168 for (i = 0; i < MAX_IBSS_PEERS; i++) {
1169 if (0 == pHddStaCtx->conn_info.staId[i])
1170 continue;
1171 sta_id = pHddStaCtx->conn_info.staId[i];
1172 hddLog(LOG1, FL("Deregister StaID %d"), sta_id);
1173 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301174 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301175 hddLog(LOGE,
1176 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1177 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301178 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301179 }
1180 /* set the staid and peer mac as 0, all other
1181 * reset are done in hdd_connRemoveConnectInfo.
1182 */
1183 pHddStaCtx->conn_info.staId[i] = 0;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301184 qdf_mem_zero(&pHddStaCtx->conn_info.peerMacAddress[i],
Anurag Chouhan6d760662016-02-20 16:05:43 +05301185 sizeof(struct qdf_mac_addr));
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301186 if (sta_id < (WLAN_MAX_STA_COUNT + 3))
1187 pHddCtx->sta_to_adapter[sta_id] = NULL;
1188 }
1189 } else {
1190 sta_id = pHddStaCtx->conn_info.staId[0];
1191 /* We should clear all sta register with TL,
1192 * for now, only one.
1193 */
1194 vstatus = hdd_roam_deregister_sta(pAdapter, sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301195 if (!QDF_IS_STATUS_SUCCESS(vstatus)) {
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301196 hddLog(LOGE,
1197 FL("hdd_roam_deregister_sta() failed to for staID %d. Status= %d [0x%x]"),
1198 sta_id, status, status);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301199 status = QDF_STATUS_E_FAILURE;
Sreelakshmi Konamki32eadb12015-09-02 15:18:32 +05301200 }
1201 pHddCtx->sta_to_adapter[sta_id] = NULL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001202 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001203 /* Clear saved connection information in HDD */
1204 hdd_conn_remove_connect_info(pHddStaCtx);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001205 hdd_conn_set_connection_state(pAdapter, eConnectionState_NotConnected);
1206#ifdef WLAN_FEATURE_GTK_OFFLOAD
Krunal Sonibe766b02016-03-10 13:00:44 -08001207 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1208 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001209 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
1210 sizeof(tSirGtkOffloadParams));
1211 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
1212 }
1213#endif
1214
1215#ifdef FEATURE_WLAN_TDLS
1216 if (eCSR_ROAM_IBSS_LEAVE != roamStatus)
1217 wlan_hdd_tdls_disconnection_callback(pAdapter);
1218#endif
1219
Krunal Sonibe766b02016-03-10 13:00:44 -08001220 if ((QDF_STA_MODE == pAdapter->device_mode) ||
1221 (QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001222 sme_ps_disable_auto_ps_timer(WLAN_HDD_GET_HAL_CTX
1223 (pAdapter),
1224 pAdapter->sessionId);
1225 }
1226 /* Unblock anyone waiting for disconnect to complete */
1227 complete(&pAdapter->disconnect_comp_var);
1228 return status;
1229}
1230
1231/**
1232 * hdd_set_peer_authorized_event() - set peer_authorized_event
1233 * @vdev_id: vdevid
1234 *
1235 * Return: None
1236 */
1237void hdd_set_peer_authorized_event(uint32_t vdev_id)
1238{
Anurag Chouhan6d760662016-02-20 16:05:43 +05301239 hdd_context_t *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001240 hdd_adapter_t *adapter = NULL;
1241
1242 adapter = hdd_get_adapter_by_vdev(hdd_ctx, vdev_id);
1243 if (adapter == NULL) {
1244 hddLog(LOGE,
1245 "%s: Invalid vdev_id", __func__);
1246 }
1247 complete(&adapter->sta_authorized_event);
1248}
1249
1250/**
1251 * hdd_change_peer_state() - change peer state
1252 * @pAdapter: HDD adapter
1253 * @sta_state: peer state
1254 * @roam_synch_in_progress: roam synch in progress
1255 *
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301256 * Return: QDF status
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001257 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301258QDF_STATUS hdd_change_peer_state(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001259 uint8_t sta_id,
1260 enum ol_txrx_peer_state sta_state,
1261 bool roam_synch_in_progress)
1262{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301263 QDF_STATUS err;
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001264 uint8_t *peer_mac_addr;
Manjunathappa Prakash2593a642016-04-01 08:53:35 -07001265 struct ol_txrx_pdev_t *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001266 ol_txrx_peer_handle peer;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001267
1268 if (!pdev) {
1269 hdd_err("Failed to get txrx context");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301270 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001271 }
1272
1273 if (sta_id >= WLAN_MAX_STA_COUNT) {
1274 hddLog(LOGE, "Invalid sta id :%d", sta_id);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301275 return QDF_STATUS_E_INVAL;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001276 }
1277
1278 peer = ol_txrx_peer_find_by_local_id(pdev, sta_id);
1279 if (!peer)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301280 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001281
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001282 peer_mac_addr = ol_txrx_peer_get_peer_mac_addr(peer);
1283 if (peer_mac_addr == NULL) {
1284 hddLog(LOGE, "peer mac addr is NULL");
1285 return QDF_STATUS_E_FAULT;
1286 }
1287
1288 err = ol_txrx_peer_state_update(pdev, peer_mac_addr, sta_state);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301289 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001290 hddLog(LOGE, "peer state update failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301291 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001292 }
1293#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1294 if (roam_synch_in_progress)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301295 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001296#endif
1297
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001298 if (sta_state == OL_TXRX_PEER_STATE_AUTH) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001299#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
1300 /* make sure event is reset */
1301 INIT_COMPLETION(pAdapter->sta_authorized_event);
1302#endif
1303
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001304 err = sme_set_peer_authorized(peer_mac_addr,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001305 hdd_set_peer_authorized_event,
1306 pAdapter->sessionId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301307 if (err != QDF_STATUS_SUCCESS) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001308 hddLog(LOGE, "Failed to set the peer state to authorized");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301309 return QDF_STATUS_E_FAULT;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001310 }
1311
Krunal Sonibe766b02016-03-10 13:00:44 -08001312 if (pAdapter->device_mode == QDF_STA_MODE ||
1313 pAdapter->device_mode == QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001314#if defined(QCA_LL_LEGACY_TX_FLOW_CONTROL) || defined(QCA_LL_TX_FLOW_CONTROL_V2)
Houston Hoffman52ec6692016-04-21 16:36:45 -07001315 ol_txrx_vdev_handle vdev;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001316 unsigned long rc;
1317
1318 /* wait for event from firmware to set the event */
1319 rc = wait_for_completion_timeout(
1320 &pAdapter->sta_authorized_event,
1321 msecs_to_jiffies(HDD_PEER_AUTHORIZE_WAIT));
1322 if (!rc) {
1323 hddLog(LOG1, "%s: timeout waiting for sta_authorized_event",
1324 __func__);
1325 }
Manjunathappa Prakash10d357a2016-03-31 19:20:49 -07001326 vdev = ol_txrx_get_vdev_for_peer(peer);
1327 ol_txrx_vdev_unpause(vdev,
1328 OL_TXQ_PAUSE_REASON_PEER_UNAUTHORIZED);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001329#endif
1330 }
1331 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301332 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001333}
1334
1335/**
1336 * hdd_roam_register_sta() - register station
1337 * @pAdapter: pointer to adapter
1338 * @pRoamInfo: pointer to roam info
1339 * @staId: station identifier
1340 * @pPeerMacAddress: peer MAC address
1341 * @pBssDesc: pointer to BSS description
1342 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301343 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001344 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301345static QDF_STATUS hdd_roam_register_sta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001346 tCsrRoamInfo *pRoamInfo,
1347 uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301348 struct qdf_mac_addr *pPeerMacAddress,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001349 tSirBssDescription *pBssDesc)
1350{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301351 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001352 struct ol_txrx_desc_type staDesc = { 0 };
1353 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Dhanashri Atre182b0272016-02-17 15:35:07 -08001354 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001355
1356 if (NULL == pBssDesc)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301357 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001358
1359 /* Get the Station ID from the one saved during the association */
1360 staDesc.sta_id = staId;
1361
1362 /* set the QoS field appropriately */
1363 if (hdd_wmm_is_active(pAdapter))
1364 staDesc.is_qos_enabled = 1;
1365 else
1366 staDesc.is_qos_enabled = 0;
1367
1368#ifdef FEATURE_WLAN_WAPI
1369 hddLog(LOG1, FL("WAPI STA Registered: %d"),
1370 pAdapter->wapi_info.fIsWapiSta);
1371 if (pAdapter->wapi_info.fIsWapiSta)
1372 staDesc.is_wapi_supported = 1;
1373 else
1374 staDesc.is_wapi_supported = 0;
1375#endif /* FEATURE_WLAN_WAPI */
1376
Dhanashri Atre50141c52016-04-07 13:15:29 -07001377 /* Register the vdev transmit and receive functions */
1378 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
1379 txrx_ops.rx.rx = hdd_rx_packet_cbk;
1380 ol_txrx_vdev_register(
1381 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
1382 pAdapter, &txrx_ops);
1383 pAdapter->tx_fn = txrx_ops.tx.tx;
1384
Dhanashri Atre182b0272016-02-17 15:35:07 -08001385 qdf_status = ol_txrx_register_peer(&staDesc);
1386
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301387 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001388 hddLog(LOGW,
1389 "ol_txrx_register_peer() failed to register. Status=%d [0x%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301390 qdf_status, qdf_status);
1391 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001392 }
1393
1394 if (!pRoamInfo->fAuthRequired) {
1395 /*
1396 * Connections that do not need Upper layer auth, transition
1397 * TLSHIM directly to 'Authenticated' state
1398 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301399 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001400 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001401 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001402#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1403 pRoamInfo->roamSynchInProgress
1404#else
1405 false
1406#endif
1407 );
1408
1409 hdd_conn_set_authenticated(pAdapter, true);
1410 } else {
1411 hddLog(LOG3,
1412 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time",
1413 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301414 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001415 hdd_change_peer_state(pAdapter, staDesc.sta_id,
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001416 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001417#ifdef WLAN_FEATURE_ROAM_OFFLOAD
1418 pRoamInfo->roamSynchInProgress
1419#else
1420 false
1421#endif
1422 );
1423 hdd_conn_set_authenticated(pAdapter, false);
1424 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301425 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001426}
1427
1428/**
1429 * hdd_send_re_assoc_event() - send reassoc event
1430 * @dev: pointer to net device
1431 * @pAdapter: pointer to adapter
1432 * @pCsrRoamInfo: pointer to roam info
1433 * @reqRsnIe: pointer to RSN Information element
1434 * @reqRsnLength: length of RSN IE
1435 *
1436 * Return: none
1437 */
1438static void hdd_send_re_assoc_event(struct net_device *dev,
1439 hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo,
1440 uint8_t *reqRsnIe, uint32_t reqRsnLength)
1441{
1442 unsigned int len = 0;
1443 u8 *pFTAssocRsp = NULL;
1444 uint8_t *rspRsnIe = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Naveen Rawat14298b92015-11-25 16:27:41 -08001445 uint8_t *assoc_req_ies = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001446 uint32_t rspRsnLength = 0;
1447 struct ieee80211_channel *chan;
1448 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1449 uint8_t buf_ssid_ie[2 + SIR_MAC_SSID_EID_MAX]; /* 2 bytes-EID and len */
1450 uint8_t *buf_ptr, ssid_ie_len;
1451 struct cfg80211_bss *bss = NULL;
1452 uint8_t *final_req_ie = NULL;
1453 tCsrRoamConnectedProfile roam_profile;
1454 tHalHandle hal_handle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1455
1456 if (!rspRsnIe) {
1457 hddLog(LOGE, FL("Unable to allocate RSN IE"));
Naveen Rawatdafda292016-01-06 18:32:14 -08001458 goto done;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001459 }
1460
Naveen Rawat14298b92015-11-25 16:27:41 -08001461 if (!assoc_req_ies) {
1462 hdd_err("Unable to allocate Assoc Req IE");
Naveen Rawatdafda292016-01-06 18:32:14 -08001463 goto done;
Naveen Rawat14298b92015-11-25 16:27:41 -08001464 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001465 if (pCsrRoamInfo == NULL) {
1466 hddLog(LOGE, FL("Invalid CSR roam info"));
1467 goto done;
1468 }
1469
1470 if (pCsrRoamInfo->nAssocRspLength == 0) {
1471 hddLog(LOGE, FL("Invalid assoc response length"));
1472 goto done;
1473 }
1474
1475 pFTAssocRsp =
1476 (u8 *) (pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
1477 pCsrRoamInfo->nAssocReqLength);
1478 if (pFTAssocRsp == NULL)
1479 goto done;
1480
1481 /* pFTAssocRsp needs to point to the IEs */
1482 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1483 hddLog(LOG1, FL("AssocRsp is now at %02x%02x"),
1484 (unsigned int)pFTAssocRsp[0], (unsigned int)pFTAssocRsp[1]);
1485
1486 /*
1487 * Active session count is decremented upon disconnection, but during
1488 * roaming, there is no disconnect indication and hence active session
1489 * count is not decremented.
1490 * After roaming is completed, active session count is incremented
1491 * as a part of connect indication but effectively after roaming the
1492 * active session count should still be the same and hence upon
1493 * successful reassoc decrement the active session count here.
1494 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001495 if (!hdd_is_roam_sync_in_progress(pCsrRoamInfo))
Chandrasekaran, Manishekar6e9aa1b2015-12-02 18:04:00 +05301496 cds_decr_session_set_pcl(pAdapter->device_mode,
1497 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001498
1499 /* Send the Assoc Resp, the supplicant needs this for initial Auth */
1500 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
1501 rspRsnLength = len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301502 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1503 qdf_mem_zero(rspRsnIe + len, IW_GENERIC_IE_MAX - len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001504
1505 chan = ieee80211_get_channel(pAdapter->wdev.wiphy,
1506 (int)pCsrRoamInfo->pBssDesc->channelId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301507 qdf_mem_zero(&roam_profile, sizeof(tCsrRoamConnectedProfile));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001508 sme_roam_get_connect_profile(hal_handle, pAdapter->sessionId,
1509 &roam_profile);
1510 bss = cfg80211_get_bss(pAdapter->wdev.wiphy, chan,
1511 pCsrRoamInfo->bssid.bytes,
1512 &roam_profile.SSID.ssId[0], roam_profile.SSID.length,
Ryan Hsu535d16a2016-01-18 16:45:12 -08001513#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)) && !defined(WITH_BACKPORTS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001514 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
Ryan Hsu535d16a2016-01-18 16:45:12 -08001515#else
1516 IEEE80211_BSS_TYPE_ESS, IEEE80211_PRIVACY_ANY);
1517#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001518
1519 if (bss == NULL)
1520 hddLog(LOGE, FL("Get BSS returned NULL"));
1521 buf_ptr = buf_ssid_ie;
1522 *buf_ptr = SIR_MAC_SSID_EID;
1523 buf_ptr++;
1524 *buf_ptr = roam_profile.SSID.length; /*len of ssid*/
1525 buf_ptr++;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301526 qdf_mem_copy(buf_ptr, &roam_profile.SSID.ssId[0],
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001527 roam_profile.SSID.length);
1528 ssid_ie_len = 2 + roam_profile.SSID.length;
Jeff Johnson9991f472016-01-06 16:02:31 -08001529 hdd_notice("SSIDIE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301530 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001531 buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001532 final_req_ie = kmalloc(IW_GENERIC_IE_MAX, GFP_KERNEL);
1533 if (final_req_ie == NULL)
1534 goto done;
1535 buf_ptr = final_req_ie;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301536 qdf_mem_copy(buf_ptr, buf_ssid_ie, ssid_ie_len);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001537 buf_ptr += ssid_ie_len;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301538 qdf_mem_copy(buf_ptr, reqRsnIe, reqRsnLength);
1539 qdf_mem_copy(rspRsnIe, pFTAssocRsp, len);
1540 qdf_mem_zero(final_req_ie + (ssid_ie_len + reqRsnLength),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001541 IW_GENERIC_IE_MAX - (ssid_ie_len + reqRsnLength));
Jeff Johnson9991f472016-01-06 16:02:31 -08001542 hdd_notice("Req RSN IE:");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301543 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Jeff Johnson9991f472016-01-06 16:02:31 -08001544 final_req_ie, (ssid_ie_len + reqRsnLength));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001545 cfg80211_roamed_bss(dev, bss,
1546 final_req_ie, (ssid_ie_len + reqRsnLength),
1547 rspRsnIe, rspRsnLength, GFP_KERNEL);
1548
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301549 qdf_mem_copy(assoc_req_ies,
Naveen Rawat14298b92015-11-25 16:27:41 -08001550 (u8 *)pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength,
1551 pCsrRoamInfo->nAssocReqLength);
1552
1553 hdd_notice("ReAssoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05301554 QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08001555 assoc_req_ies, pCsrRoamInfo->nAssocReqLength);
1556
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001557 wlan_hdd_send_roam_auth_event(pHddCtx, pCsrRoamInfo->bssid.bytes,
Naveen Rawat14298b92015-11-25 16:27:41 -08001558 assoc_req_ies, pCsrRoamInfo->nAssocReqLength,
1559 rspRsnIe, rspRsnLength,
Prashanth Bhattabfc25292015-11-05 11:16:21 -08001560 pCsrRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001561done:
Naveen Rawatdf0a7e72016-01-06 18:35:53 -08001562 sme_roam_free_connect_profile(&roam_profile);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001563 if (final_req_ie)
1564 kfree(final_req_ie);
1565 kfree(rspRsnIe);
Naveen Rawat14298b92015-11-25 16:27:41 -08001566 kfree(assoc_req_ies);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001567}
1568
1569/**
Govind Singhedc5cda2015-10-23 17:11:35 +05301570 * hdd_is_roam_sync_in_progress()- Check if roam offloaded
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001571 * @roaminfo - Roaming Information
Govind Singhedc5cda2015-10-23 17:11:35 +05301572 *
1573 * Return: roam sync status if roaming offloaded else false
1574 */
1575#ifdef WLAN_FEATURE_ROAM_OFFLOAD
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001576bool hdd_is_roam_sync_in_progress(tCsrRoamInfo *roaminfo)
Govind Singhedc5cda2015-10-23 17:11:35 +05301577{
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08001578 if (roaminfo)
1579 return roaminfo->roamSynchInProgress;
1580 else
1581 return false;
Govind Singhedc5cda2015-10-23 17:11:35 +05301582}
1583#endif
1584
1585
1586/**
1587 * hdd_change_sta_state_authenticated()-
1588 * This function changes STA state to authenticated
1589 * @adapter: pointer to the adapter structure.
1590 * @roaminfo: pointer to the RoamInfo structure.
1591 *
1592 * This is called from hdd_RoamSetKeyCompleteHandler
1593 * in context to eCSR_ROAM_SET_KEY_COMPLETE event from fw.
1594 *
1595 * Return: 0 on success and errno on failure
1596 */
1597static int hdd_change_sta_state_authenticated(hdd_adapter_t *adapter,
1598 tCsrRoamInfo *roaminfo)
1599{
1600 int ret;
1601 hdd_station_ctx_t *hddstactx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
1602
1603 hddLog(LOG1,
1604 "Changing TL state to AUTHENTICATED for StaId= %d",
1605 hddstactx->conn_info.staId[0]);
1606
1607 /* Connections that do not need Upper layer authentication,
1608 * transition TL to 'Authenticated' state after the keys are set
1609 */
1610 ret = hdd_change_peer_state(adapter,
1611 hddstactx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08001612 OL_TXRX_PEER_STATE_AUTH,
Govind Singhedc5cda2015-10-23 17:11:35 +05301613 hdd_is_roam_sync_in_progress(roaminfo));
1614 hdd_conn_set_authenticated(adapter, true);
Krunal Sonibe766b02016-03-10 13:00:44 -08001615 if ((QDF_STA_MODE == adapter->device_mode) ||
1616 (QDF_P2P_CLIENT_MODE == adapter->device_mode)) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301617 sme_ps_enable_auto_ps_timer(
1618 WLAN_HDD_GET_HAL_CTX(adapter),
1619 adapter->sessionId,
1620 hddstactx->hdd_ReassocScenario);
1621 }
1622
1623 return ret;
1624}
1625
1626/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001627 * hdd_roam_set_key_complete_handler() - Update the security parameters
1628 * @pAdapter: pointer to adapter
1629 * @pRoamInfo: pointer to roam info
1630 * @roamId: roam id
1631 * @roamStatus: roam status
1632 * @roamResult: roam result
1633 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301634 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001635 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301636static QDF_STATUS hdd_roam_set_key_complete_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001637 tCsrRoamInfo *pRoamInfo,
1638 uint32_t roamId,
1639 eRoamCmdStatus roamStatus,
1640 eCsrRoamResult roamResult)
1641{
1642 eCsrEncryptionType connectedCipherAlgo;
1643 bool fConnected = false;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301644 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001645 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301646 tHalHandle hal_ctx = WLAN_HDD_GET_HAL_CTX(pAdapter);
1647 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_ctx);
1648
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001649 ENTER();
1650
1651 if (NULL == pRoamInfo) {
1652 hddLog(LOG2, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301653 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001654 }
1655 /*
1656 * if (WPA), tell TL to go to 'authenticated' after the keys are set.
1657 * then go to 'authenticated'. For all other authentication types
1658 * (those that do not require upper layer authentication) we can put TL
1659 * directly into 'authenticated' state.
1660 */
1661 hddLog(LOG2, "Set Key completion roamStatus =%d roamResult=%d "
1662 MAC_ADDRESS_STR, roamStatus, roamResult,
1663 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
1664
1665 fConnected = hdd_conn_get_connected_cipher_algo(pHddStaCtx,
1666 &connectedCipherAlgo);
1667 if (fConnected) {
Krunal Sonibe766b02016-03-10 13:00:44 -08001668 if (QDF_IBSS_MODE == pAdapter->device_mode) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001669 uint8_t staId;
1670
Anurag Chouhanc5548422016-02-24 18:33:27 +05301671 if (qdf_is_macaddr_broadcast(&pRoamInfo->peerMac)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001672 pHddStaCtx->roam_info.roamingState =
1673 HDD_ROAM_STATE_NONE;
1674 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301675 qdf_status = hdd_ibss_get_sta_id(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001676 pHddStaCtx,
1677 &pRoamInfo->peerMac,
1678 &staId);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301679 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001680 hddLog(LOG2,
1681 "WLAN TL STA Ptk Installed for STAID=%d",
1682 staId);
1683 pHddStaCtx->roam_info.roamingState =
1684 HDD_ROAM_STATE_NONE;
1685 }
1686 }
1687 } else {
1688 /*
1689 * TODO: Considering getting a state machine in
Govind Singhedc5cda2015-10-23 17:11:35 +05301690 * HDD later.This routine is invoked twice.
1691 * 1)set PTK 2)set GTK.The following if
1692 * statement will be TRUE when setting GTK.
1693 * At this time we don't handle the state in detail.
1694 * Related CR: 174048 - TL not in authenticated state
1695 */
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301696 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
Govind Singhedc5cda2015-10-23 17:11:35 +05301697 pHddStaCtx->conn_info.gtk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301698 /*
1699 * PTK exchange happens in preauthentication
1700 * itself if key_mgmt is FT-PSK, ptk_installed
1701 * was false as there is no set PTK after
1702 * roaming. STA TL state moves to authenticated
1703 * only if ptk_installed is true. So, make
1704 * ptk_installed to true in case of 11R roaming.
1705 */
1706 if (csr_neighbor_roam_is11r_assoc(mac_ctx,
1707 pAdapter->sessionId))
1708 pHddStaCtx->conn_info.ptk_installed =
1709 true;
1710 } else {
Govind Singhedc5cda2015-10-23 17:11:35 +05301711 pHddStaCtx->conn_info.ptk_installed = true;
Sreelakshmi Konamki720f2b72016-02-26 16:44:04 +05301712 }
Govind Singhedc5cda2015-10-23 17:11:35 +05301713
1714 /* In WPA case move STA to authenticated when
1715 * ptk is installed.Earlier in WEP case STA
1716 * was moved to AUTHENTICATED prior to setting
1717 * the unicast key and it was resulting in sending
1718 * few un-encrypted packet. Now in WEP case
1719 * STA state will be moved to AUTHENTICATED
1720 * after we set the unicast and broadcast key.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001721 */
Govind Singhedc5cda2015-10-23 17:11:35 +05301722 if ((pHddStaCtx->conn_info.ucEncryptionType ==
1723 eCSR_ENCRYPT_TYPE_WEP40) ||
1724 (pHddStaCtx->conn_info.ucEncryptionType ==
1725 eCSR_ENCRYPT_TYPE_WEP104) ||
1726 (pHddStaCtx->conn_info.ucEncryptionType ==
1727 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
1728 (pHddStaCtx->conn_info.ucEncryptionType ==
1729 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)) {
1730 if (pHddStaCtx->conn_info.gtk_installed &&
1731 pHddStaCtx->conn_info.ptk_installed)
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301732 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301733 hdd_change_sta_state_authenticated(pAdapter,
1734 pRoamInfo);
1735 } else if (pHddStaCtx->conn_info.ptk_installed) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301736 qdf_status =
Govind Singhedc5cda2015-10-23 17:11:35 +05301737 hdd_change_sta_state_authenticated(pAdapter,
1738 pRoamInfo);
1739 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001740
Govind Singhedc5cda2015-10-23 17:11:35 +05301741 if (pHddStaCtx->conn_info.gtk_installed &&
1742 pHddStaCtx->conn_info.ptk_installed) {
1743 pHddStaCtx->conn_info.gtk_installed = false;
1744 pHddStaCtx->conn_info.ptk_installed = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001745 }
1746
1747 pHddStaCtx->roam_info.roamingState =
Govind Singhedc5cda2015-10-23 17:11:35 +05301748 HDD_ROAM_STATE_NONE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001749 }
1750 } else {
1751 /*
1752 * possible disassoc after issuing set key and waiting
1753 * set key complete.
1754 */
1755 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1756 }
1757
1758 EXIT();
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301759 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001760}
1761
1762/**
1763 * hdd_perform_roam_set_key_complete() - perform set key complete
1764 * @pAdapter: pointer to adapter
1765 *
1766 * Return: none
1767 */
1768void hdd_perform_roam_set_key_complete(hdd_adapter_t *pAdapter)
1769{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301770 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001771 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1772 tCsrRoamInfo roamInfo;
1773 roamInfo.fAuthRequired = false;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301774 qdf_mem_copy(roamInfo.bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301775 pHddStaCtx->roam_info.bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05301776 qdf_mem_copy(roamInfo.peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05301777 pHddStaCtx->roam_info.peerMac, QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001778
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301779 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001780 hdd_roam_set_key_complete_handler(pAdapter,
1781 &roamInfo,
1782 pHddStaCtx->roam_info.roamId,
1783 pHddStaCtx->roam_info.roamStatus,
1784 eCSR_ROAM_RESULT_AUTHENTICATED);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05301785 if (qdf_ret_status != QDF_STATUS_SUCCESS)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001786 hddLog(LOGE, FL("Set Key complete failure"));
1787
1788 pHddStaCtx->roam_info.deferKeyComplete = false;
1789}
1790
1791/**
1792 * hdd_association_completion_handler() - association completion handler
1793 * @pAdapter: pointer to adapter
1794 * @pRoamInfo: pointer to roam info
1795 * @roamId: roam id
1796 * @roamStatus: roam status
1797 * @roamResult: roam result
1798 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301799 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001800 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301801static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001802 tCsrRoamInfo *pRoamInfo,
1803 uint32_t roamId,
1804 eRoamCmdStatus roamStatus,
1805 eCsrRoamResult roamResult)
1806{
1807 struct net_device *dev = pAdapter->dev;
1808 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1809 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301810 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001811 uint8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1812 uint32_t reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001813 int ft_carrier_on = false;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001814 bool hddDisconInProgress = false;
1815 unsigned long rc;
1816
1817 if (!pHddCtx) {
1818 hdd_err("HDD context is NULL");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301819 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001820 }
1821
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001822 /* HDD has initiated disconnect, do not send connect result indication
1823 * to kernel as it will be handled by __cfg80211_disconnect.
1824 */
1825 if ((eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
1826 && ((eCSR_ROAM_RESULT_ASSOCIATED == roamResult)
1827 || (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus))) {
1828 hddLog(LOG1, FL("Disconnect from HDD in progress"));
1829 hddDisconInProgress = true;
1830 }
1831
1832 if (eCSR_ROAM_RESULT_ASSOCIATED == roamResult) {
1833 if (NULL == pRoamInfo) {
1834 hddLog(LOGE, FL("pRoamInfo is NULL"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301835 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001836 }
1837 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001838 hdd_conn_set_connection_state(pAdapter,
1839 eConnectionState_Associated);
1840 }
1841 /* Save the connection info from CSR... */
1842 hdd_conn_save_connect_info(pAdapter, pRoamInfo,
1843 eCSR_BSS_TYPE_INFRASTRUCTURE);
Gupta, Kapil4cb1d7d2016-04-16 18:16:25 -07001844
1845 if (hdd_add_beacon_filter(pAdapter) != 0)
1846 hdd_err("hdd_add_beacon_filter() failed");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001847#ifdef FEATURE_WLAN_WAPI
1848 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1849 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE
1850 || pRoamInfo->u.pConnectedProfile->AuthType ==
1851 eCSR_AUTH_TYPE_WAPI_WAI_PSK) {
1852 pAdapter->wapi_info.fIsWapiSta = 1;
1853 } else {
1854 pAdapter->wapi_info.fIsWapiSta = 0;
1855 }
1856#endif /* FEATURE_WLAN_WAPI */
1857
1858 /* Indicate 'connect' status to user space */
1859 hdd_send_association_event(dev, pRoamInfo);
1860
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08001861 if (cds_is_mcc_in_24G()) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001862 if (pHddCtx->miracast_value)
1863 cds_set_mas(pAdapter, pHddCtx->miracast_value);
1864 }
1865
1866 /* Initialize the Linkup event completion variable */
1867 INIT_COMPLETION(pAdapter->linkup_event_var);
1868
1869 /*
1870 * Sometimes Switching ON the Carrier is taking time to activate
1871 * the device properly. Before allowing any packet to go up to
1872 * the application, device activation has to be ensured for
1873 * proper queue mapping by the kernel. we have registered net
1874 * device notifier for device change notification. With this we
1875 * will come to know that the device is getting
1876 * activated properly.
1877 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001878 if (pHddStaCtx->ft_carrier_on == false) {
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001879 /*
1880 * Enable Linkup Event Servicing which allows the net
1881 * device notifier to set the linkup event variable.
1882 */
1883 pAdapter->isLinkUpSvcNeeded = true;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001884
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001885 /* Switch on the Carrier to activate the device */
1886 wlan_hdd_netif_queue_control(pAdapter,
1887 WLAN_NETIF_CARRIER_ON,
1888 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001889
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001890 /*
1891 * Wait for the Link to up to ensure all the queues
1892 * are set properly by the kernel.
1893 */
1894 rc = wait_for_completion_timeout(
1895 &pAdapter->linkup_event_var,
1896 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT)
1897 );
1898 if (!rc)
1899 hdd_warn("Warning:ASSOC_LINKUP_TIMEOUT");
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001900
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07001901 /*
1902 * Disable Linkup Event Servicing - no more service
1903 * required from the net device notifier call.
1904 */
1905 pAdapter->isLinkUpSvcNeeded = false;
1906 } else {
1907 pHddStaCtx->ft_carrier_on = false;
1908 ft_carrier_on = true;
1909 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001910 if ((WLAN_MAX_STA_COUNT + 3) > pRoamInfo->staId)
1911 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1912 else
1913 hddLog(LOGE, "%s: Wrong Staid: %d", __func__,
1914 pRoamInfo->staId);
1915
1916 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1917
1918 if (hdd_ipa_is_enabled(pHddCtx))
1919 hdd_ipa_wlan_evt(pAdapter, pRoamInfo->staId,
1920 WLAN_STA_CONNECT,
1921 pRoamInfo->bssid.bytes);
1922
1923#ifdef FEATURE_WLAN_AUTO_SHUTDOWN
1924 wlan_hdd_auto_shutdown_enable(pHddCtx, false);
1925#endif
1926
Chandrasekaran Manishekar068e25e2016-03-07 11:51:07 +05301927 hdd_info("check for SAP restart");
Tushnim Bhattacharyya4adb3682016-01-07 15:07:12 -08001928 cds_check_concurrent_intf_and_restart_sap(pHddStaCtx,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001929 pAdapter);
1930
1931#ifdef FEATURE_WLAN_TDLS
1932 wlan_hdd_tdls_connection_callback(pAdapter);
1933#endif
1934
1935#ifdef QCA_PKT_PROTO_TRACE
1936 /* STA Associated, update into trace buffer */
1937 if (pHddCtx->config->gEnableDebugLog)
1938 cds_pkt_trace_buf_update("ST:ASSOC");
1939#endif /* QCA_PKT_PROTO_TRACE */
1940 /*
1941 * For reassoc, the station is already registered, all we need
1942 * is to change the state of the STA in TL.
1943 * If authentication is required (WPA/WPA2/DWEP), change TL to
1944 * CONNECTED instead of AUTHENTICATED.
1945 */
1946 if (!pRoamInfo->fReassocReq) {
1947 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001948 u8 *pFTAssocRsp = NULL;
1949 unsigned int assocRsplen = 0;
1950 u8 *pFTAssocReq = NULL;
1951 unsigned int assocReqlen = 0;
1952 struct ieee80211_channel *chan;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001953 uint8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1954 uint32_t rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1955
1956 /* add bss_id to cfg80211 data base */
1957 bss =
1958 wlan_hdd_cfg80211_update_bss_db(pAdapter,
1959 pRoamInfo);
1960 if (NULL == bss) {
1961 pr_err("wlan: Not able to create BSS entry\n");
1962 wlan_hdd_netif_queue_control(pAdapter,
1963 WLAN_NETIF_CARRIER_OFF,
1964 WLAN_CONTROL_PATH);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05301965 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001966 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001967 if (pRoamInfo->u.pConnectedProfile->AuthType ==
1968 eCSR_AUTH_TYPE_FT_RSN
1969 || pRoamInfo->u.pConnectedProfile->AuthType ==
1970 eCSR_AUTH_TYPE_FT_RSN_PSK) {
1971
1972 /* Association Response */
1973 pFTAssocRsp =
1974 (u8 *) (pRoamInfo->pbFrames +
1975 pRoamInfo->nBeaconLength +
1976 pRoamInfo->nAssocReqLength);
1977 if (pFTAssocRsp != NULL) {
1978 /*
1979 * pFTAssocRsp needs to point to the IEs
1980 */
1981 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
1982 hddLog(LOG1,
1983 FL("AssocRsp is now at %02x%02x"),
1984 (unsigned int)pFTAssocRsp[0],
1985 (unsigned int)pFTAssocRsp[1]);
1986 assocRsplen =
1987 pRoamInfo->nAssocRspLength -
1988 FT_ASSOC_RSP_IES_OFFSET;
1989 } else {
1990 hddLog(LOGE, FL("AssocRsp is NULL"));
1991 assocRsplen = 0;
1992 }
1993
1994 /* Association Request */
1995 pFTAssocReq = (u8 *) (pRoamInfo->pbFrames +
1996 pRoamInfo->nBeaconLength);
1997 if (pFTAssocReq != NULL) {
1998 if (!ft_carrier_on) {
1999 /*
2000 * pFTAssocReq needs to point to
2001 * the IEs
2002 */
2003 pFTAssocReq +=
2004 FT_ASSOC_REQ_IES_OFFSET;
2005 hddLog(LOG1,
2006 FL("pFTAssocReq is now at %02x%02x"),
2007 (unsigned int)
2008 pFTAssocReq[0],
2009 (unsigned int)
2010 pFTAssocReq[1]);
2011 assocReqlen =
2012 pRoamInfo->nAssocReqLength -
2013 FT_ASSOC_REQ_IES_OFFSET;
2014 } else {
2015 /*
2016 * This should contain only the
2017 * FTIEs
2018 */
2019 assocReqlen =
2020 pRoamInfo->nAssocReqLength;
2021 }
2022 } else {
2023 hddLog(LOGE, FL("AssocReq is NULL"));
2024 assocReqlen = 0;
2025 }
2026
2027 if (ft_carrier_on) {
2028 if (!hddDisconInProgress) {
2029 /*
2030 * After roaming is completed,
2031 * active session count is
2032 * incremented as a part of
2033 * connect indication but
2034 * effectively the active
2035 * session count should still
2036 * be the same and hence upon
2037 * successful reassoc
2038 * decrement the active session
2039 * count here.
2040 */
Varun Reddy Yeturud5939f82015-12-24 18:14:02 -08002041 if (!hdd_is_roam_sync_in_progress
2042 (pRoamInfo))
2043 cds_decr_session_set_pcl
2044 (pAdapter->device_mode,
2045 pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002046 hddLog(LOG1,
2047 FL("ft_carrier_on is %d, sending roamed indication"),
2048 ft_carrier_on);
2049 chan =
2050 ieee80211_get_channel
2051 (pAdapter->wdev.wiphy,
2052 (int)pRoamInfo->pBssDesc->
2053 channelId);
2054 hddLog(LOG1,
2055 "assocReqlen %d assocRsplen %d",
2056 assocReqlen,
2057 assocRsplen);
Naveen Rawat14298b92015-11-25 16:27:41 -08002058
2059 hdd_notice(
2060 "Reassoc Req IE dump");
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302061 QDF_TRACE_HEX_DUMP(
Anurag Chouhan6d760662016-02-20 16:05:43 +05302062 QDF_MODULE_ID_HDD,
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302063 QDF_TRACE_LEVEL_DEBUG,
Naveen Rawat14298b92015-11-25 16:27:41 -08002064 pFTAssocReq,
2065 assocReqlen);
2066
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002067 cfg80211_roamed(dev, chan,
2068 pRoamInfo->
2069 bssid.bytes,
2070 pFTAssocReq,
2071 assocReqlen,
2072 pFTAssocRsp,
2073 assocRsplen,
2074 GFP_KERNEL);
Prashanth Bhattabfc25292015-11-05 11:16:21 -08002075 wlan_hdd_send_roam_auth_event(
2076 pHddCtx,
2077 pRoamInfo->bssid.bytes,
2078 pFTAssocReq,
2079 assocReqlen,
2080 pFTAssocRsp,
2081 assocRsplen,
2082 pRoamInfo);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002083 }
2084 if (sme_get_ftptk_state
2085 (WLAN_HDD_GET_HAL_CTX(pAdapter),
2086 pAdapter->sessionId)) {
2087 sme_set_ftptk_state
2088 (WLAN_HDD_GET_HAL_CTX
2089 (pAdapter),
2090 pAdapter->sessionId,
2091 false);
2092 pRoamInfo->fAuthRequired =
2093 false;
2094
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302095 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002096 roam_info.bssid,
2097 pRoamInfo->bssid.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302098 QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302099 qdf_mem_copy(pHddStaCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002100 roam_info.peerMac,
2101 pRoamInfo->peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302102 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002103 pHddStaCtx->roam_info.roamId =
2104 roamId;
2105 pHddStaCtx->roam_info.
2106 roamStatus = roamStatus;
2107 pHddStaCtx->roam_info.
2108 deferKeyComplete = true;
2109 }
2110 } else if (!hddDisconInProgress) {
2111 hddLog(LOG1,
2112 FL("ft_carrier_on is %d, sending connect indication"),
2113 ft_carrier_on);
2114 cfg80211_connect_result(dev,
2115 pRoamInfo->
2116 bssid.bytes,
2117 pFTAssocReq,
2118 assocReqlen,
2119 pFTAssocRsp,
2120 assocRsplen,
2121 WLAN_STATUS_SUCCESS,
2122 GFP_KERNEL);
2123 }
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08002124 } else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002125 /*
2126 * wpa supplicant expecting WPA/RSN IE in
2127 * connect result.
2128 */
2129 csr_roam_get_wpa_rsn_req_ie(WLAN_HDD_GET_HAL_CTX
2130 (pAdapter),
2131 pAdapter->sessionId,
2132 &reqRsnLength,
2133 reqRsnIe);
2134
2135 csr_roam_get_wpa_rsn_rsp_ie(WLAN_HDD_GET_HAL_CTX
2136 (pAdapter),
2137 pAdapter->sessionId,
2138 &rspRsnLength,
2139 rspRsnIe);
2140 if (!hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002141 if (ft_carrier_on)
2142 hdd_send_re_assoc_event(dev,
2143 pAdapter,
2144 pRoamInfo,
2145 reqRsnIe,
2146 reqRsnLength);
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07002147 else {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002148 hddLog(LOG1,
2149 FL("sending connect indication to nl80211:for bssid "
2150 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302151 " result:%d and Status:%d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002152 MAC_ADDR_ARRAY
2153 (pRoamInfo->bssid.bytes),
2154 roamResult, roamStatus);
2155
2156 /* inform connect result to nl80211 */
2157 cfg80211_connect_result(dev,
2158 pRoamInfo->
2159 bssid.bytes,
2160 reqRsnIe,
2161 reqRsnLength,
2162 rspRsnIe,
2163 rspRsnLength,
2164 WLAN_STATUS_SUCCESS,
2165 GFP_KERNEL);
2166 }
2167 }
2168 }
2169 if (!hddDisconInProgress) {
2170 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002171 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002172 bss);
2173
2174 /*
2175 * Perform any WMM-related association
2176 * processing.
2177 */
2178 hdd_wmm_assoc(pAdapter, pRoamInfo,
2179 eCSR_BSS_TYPE_INFRASTRUCTURE);
2180
2181 /*
2182 * Start the Queue - Start tx queues before
2183 * hdd_roam_register_sta, since
2184 * hdd_roam_register_sta will flush any cached
2185 * data frames immediately.
2186 */
2187 hddLog(LOG1, FL("Enabling queues"));
2188 wlan_hdd_netif_queue_control(pAdapter,
2189 WLAN_WAKE_ALL_NETIF_QUEUE,
2190 WLAN_CONTROL_PATH);
2191
2192 /*
2193 * Register the Station with TL after associated
2194 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302195 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002196 pRoamInfo,
2197 pHddStaCtx->
2198 conn_info.
2199 staId[0],
2200 NULL,
2201 pRoamInfo->
2202 pBssDesc);
2203 }
2204 } else {
2205 /*
2206 * wpa supplicant expecting WPA/RSN IE in connect result
2207 * in case of reassociation also need to indicate it to
2208 * supplicant.
2209 */
2210 csr_roam_get_wpa_rsn_req_ie(
2211 WLAN_HDD_GET_HAL_CTX(pAdapter),
2212 pAdapter->sessionId,
2213 &reqRsnLength, reqRsnIe);
2214
2215 hdd_send_re_assoc_event(dev, pAdapter, pRoamInfo,
2216 reqRsnIe, reqRsnLength);
2217 /* Reassoc successfully */
2218 if (pRoamInfo->fAuthRequired) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302219 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002220 hdd_change_peer_state(pAdapter,
2221 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002222 OL_TXRX_PEER_STATE_CONN,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002223#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2224 pRoamInfo->roamSynchInProgress
2225#else
2226 false
2227#endif
2228 );
2229 hdd_conn_set_authenticated(pAdapter, false);
2230 } else {
2231 hddLog(LOG2,
2232 FL("staId: %d Changing TL state to AUTHENTICATED"),
2233 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302234 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002235 hdd_change_peer_state(pAdapter,
2236 pHddStaCtx->conn_info.staId[0],
Dhanashri Atreb08959a2016-03-01 17:28:03 -08002237 OL_TXRX_PEER_STATE_AUTH,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002238#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2239 pRoamInfo->roamSynchInProgress
2240#else
2241 false
2242#endif
2243 );
2244 hdd_conn_set_authenticated(pAdapter, true);
2245 }
2246
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302247 if (QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002248 /*
2249 * Perform any WMM-related association
2250 * processing
2251 */
2252 hdd_wmm_assoc(pAdapter, pRoamInfo,
2253 eCSR_BSS_TYPE_INFRASTRUCTURE);
2254 }
2255
2256 /* Start the tx queues */
2257#ifdef WLAN_FEATURE_ROAM_OFFLOAD
2258 if (pRoamInfo->roamSynchInProgress)
2259 hddLog(LOG3, "LFR3:netif_tx_wake_all_queues");
2260#endif
2261 hddLog(LOG1, FL("Enabling queues"));
2262 wlan_hdd_netif_queue_control(pAdapter,
2263 WLAN_WAKE_ALL_NETIF_QUEUE,
2264 WLAN_CONTROL_PATH);
2265 }
2266
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302267 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002268 hddLog(LOGE,
2269 "STA register with TL failed. status(=%d) [%08X]",
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302270 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002271 }
2272#ifdef WLAN_FEATURE_11W
Anurag Chouhan600c3a02016-03-01 10:33:54 +05302273 qdf_mem_zero(&pAdapter->hdd_stats.hddPmfStats,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002274 sizeof(pAdapter->hdd_stats.hddPmfStats));
2275#endif
2276 } else {
2277 hdd_wext_state_t *pWextState =
2278 WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2279 if (pRoamInfo)
2280 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302281 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002282 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
2283 roamResult, roamStatus);
2284 else
2285 pr_info("wlan: connection failed with " MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302286 " result:%d and Status:%d\n",
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002287 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2288 roamResult, roamStatus);
2289
2290 /*
2291 * CR465478: Only send up a connection failure result when CSR
2292 * has completed operation - with a ASSOCIATION_FAILURE status.
2293 */
2294 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2295 && !hddDisconInProgress) {
2296 if (pRoamInfo)
2297 hddLog(LOGE,
2298 FL("send connect failure to nl80211: for bssid "
2299 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302300 " result:%d and Status:%d reasoncode %d"),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002301 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
Abhishek Singhac2be142015-12-03 16:16:25 +05302302 roamResult, roamStatus,
2303 pRoamInfo->reasonCode);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002304 else
2305 hddLog(LOGE,
2306 FL("connect failed: for bssid "
2307 MAC_ADDRESS_STR
Abhishek Singhac2be142015-12-03 16:16:25 +05302308 " result:%d and Status:%d "),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002309 MAC_ADDR_ARRAY(pWextState->req_bssId.bytes),
2310 roamResult, roamStatus);
2311
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002312 /* inform association failure event to nl80211 */
2313 if (eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL ==
2314 roamResult) {
2315 if (pRoamInfo)
2316 cfg80211_connect_result(dev,
2317 pRoamInfo->bssid.bytes,
2318 NULL, 0, NULL, 0,
2319 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2320 GFP_KERNEL);
2321 else
2322 cfg80211_connect_result(dev,
2323 pWextState->req_bssId.bytes,
2324 NULL, 0, NULL, 0,
2325 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
2326 GFP_KERNEL);
2327 } else {
2328 if (pRoamInfo) {
2329 eCsrAuthType authType =
2330 pWextState->roamProfile.AuthType.
2331 authType[0];
Abhishek Singhac2be142015-12-03 16:16:25 +05302332 eCsrEncryptionType encryption_type =
2333 pWextState->roamProfile.
2334 EncryptionType.encryptionType[0];
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002335 bool isWep =
Abhishek Singhac2be142015-12-03 16:16:25 +05302336 (((authType ==
2337 eCSR_AUTH_TYPE_OPEN_SYSTEM) ||
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002338 (authType ==
Abhishek Singhac2be142015-12-03 16:16:25 +05302339 eCSR_AUTH_TYPE_SHARED_KEY)) &&
2340 ((encryption_type ==
2341 eCSR_ENCRYPT_TYPE_WEP40) ||
2342 (encryption_type ==
2343 eCSR_ENCRYPT_TYPE_WEP104) ||
2344 (encryption_type ==
2345 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY) ||
2346 (encryption_type ==
2347 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002348 /*
2349 * In case of OPEN-WEP or SHARED-WEP
2350 * authentication, send exact protocol
2351 * reason code. This enables user
2352 * applications to reconnect the station
2353 * with correct configuration.
2354 */
2355 cfg80211_connect_result(dev,
2356 pRoamInfo->bssid.bytes, NULL, 0,
2357 NULL, 0,
Abhishek Singhac2be142015-12-03 16:16:25 +05302358 (isWep &&
2359 pRoamInfo->reasonCode) ?
2360 pRoamInfo->reasonCode :
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002361 WLAN_STATUS_UNSPECIFIED_FAILURE,
2362 GFP_KERNEL);
2363 } else
2364 cfg80211_connect_result(dev,
2365 pWextState->req_bssId.bytes,
2366 NULL, 0, NULL, 0,
2367 WLAN_STATUS_UNSPECIFIED_FAILURE,
2368 GFP_KERNEL);
2369 }
Abhishek Singhac2be142015-12-03 16:16:25 +05302370 hdd_clear_roam_profile_ie(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002371 }
2372
2373 if (pRoamInfo) {
2374 if ((eSIR_SME_JOIN_TIMEOUT_RESULT_CODE ==
2375 pRoamInfo->statusCode)
2376 || (eSIR_SME_AUTH_TIMEOUT_RESULT_CODE ==
2377 pRoamInfo->statusCode)
2378 || (eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE ==
2379 pRoamInfo->statusCode)) {
2380 wlan_hdd_cfg80211_update_bss_list(pAdapter,
2381 pRoamInfo);
2382 }
2383 }
2384
2385 /*
2386 * Set connection state to eConnectionState_NotConnected only
2387 * when CSR has completed operation - with a
2388 * ASSOCIATION_FAILURE status.
2389 */
2390 if (eCSR_ROAM_ASSOCIATION_FAILURE == roamStatus
2391 && !hddDisconInProgress) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002392 hdd_conn_set_connection_state(pAdapter,
2393 eConnectionState_NotConnected);
2394 }
2395 hdd_wmm_init(pAdapter);
2396
2397 hddLog(LOG1, FL("Disabling queues"));
2398 wlan_hdd_netif_queue_control(pAdapter,
2399 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2400 WLAN_CONTROL_PATH);
2401 }
2402
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302403 if (QDF_STATUS_SUCCESS != cds_check_and_restart_sap(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002404 roamResult, pHddStaCtx))
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302405 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002406
Govind Singh24db1ed2015-12-18 15:54:59 +05302407 if (NULL != pRoamInfo && NULL != pRoamInfo->pBssDesc) {
2408 cds_force_sap_on_scc(roamResult,
2409 pRoamInfo->pBssDesc->channelId);
2410 } else {
2411 hdd_err("pRoamInfo profile is not set properly");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302412 return QDF_STATUS_E_FAILURE;
Govind Singh24db1ed2015-12-18 15:54:59 +05302413 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002414
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302415 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002416}
2417
2418/**
2419 * hdd_roam_ibss_indication_handler() - update the status of the IBSS
2420 * @pAdapter: pointer to adapter
2421 * @pRoamInfo: pointer to roam info
2422 * @roamId: roam id
2423 * @roamStatus: roam status
2424 * @roamResult: roam result
2425 *
2426 * Here we update the status of the Ibss when we receive information that we
2427 * have started/joined an ibss session.
2428 *
2429 * Return: none
2430 */
2431static void hdd_roam_ibss_indication_handler(hdd_adapter_t *pAdapter,
2432 tCsrRoamInfo *pRoamInfo,
2433 uint32_t roamId,
2434 eRoamCmdStatus roamStatus,
2435 eCsrRoamResult roamResult)
2436{
2437 hddLog(LOG1, "%s: id %d, status %d, result %d",
2438 pAdapter->dev->name, roamId, roamStatus, roamResult);
2439
2440 switch (roamResult) {
2441 /* both IBSS Started and IBSS Join should come in here. */
2442 case eCSR_ROAM_RESULT_IBSS_STARTED:
2443 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
2444 case eCSR_ROAM_RESULT_IBSS_COALESCED:
2445 {
2446 hdd_context_t *pHddCtx =
2447 (hdd_context_t *) pAdapter->pHddCtx;
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302448 hdd_station_ctx_t *hdd_sta_ctx =
2449 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Anurag Chouhan6d760662016-02-20 16:05:43 +05302450 struct qdf_mac_addr broadcastMacAddr =
2451 QDF_MAC_ADDR_BROADCAST_INITIALIZER;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002452
2453 if (NULL == pRoamInfo) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05302454 QDF_ASSERT(0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002455 return;
2456 }
2457
2458 /* When IBSS Started comes from CSR, we need to move
2459 * connection state to IBSS Disconnected (meaning no peers
2460 * are in the IBSS).
2461 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002462 hdd_conn_set_connection_state(pAdapter,
2463 eConnectionState_IbssDisconnected);
2464 /* notify wmm */
2465 hdd_wmm_connect(pAdapter, pRoamInfo,
2466 eCSR_BSS_TYPE_IBSS);
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302467
2468 hdd_sta_ctx->broadcast_ibss_staid = pRoamInfo->staId;
2469
2470 pHddCtx->sta_to_adapter[pRoamInfo->staId] =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002471 pAdapter;
2472 hdd_roam_register_sta(pAdapter, pRoamInfo,
Chandrasekaran, Manishekar34e325a2015-12-18 12:07:22 +05302473 pRoamInfo->staId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002474 &broadcastMacAddr,
2475 pRoamInfo->pBssDesc);
2476
2477 if (pRoamInfo->pBssDesc) {
2478 struct cfg80211_bss *bss;
2479#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2480 struct ieee80211_channel *chan;
2481 int chan_no;
2482 unsigned int freq;
2483#endif
2484 /* we created the IBSS, notify supplicant */
2485 hddLog(LOG1,
2486 FL("%s: created ibss " MAC_ADDRESS_STR),
2487 pAdapter->dev->name,
2488 MAC_ADDR_ARRAY(pRoamInfo->pBssDesc->bssId));
2489
2490 /* we must first give cfg80211 the BSS information */
2491 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter,
2492 pRoamInfo);
2493 if (NULL == bss) {
2494 hddLog(LOGE,
2495 FL("%s: unable to create IBSS entry"),
2496 pAdapter->dev->name);
2497 return;
2498 }
2499 hddLog(LOG1, FL("Enabling queues"));
2500 wlan_hdd_netif_queue_control(pAdapter,
2501 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2502 WLAN_CONTROL_PATH);
2503
2504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
2505 chan_no = pRoamInfo->pBssDesc->channelId;
2506
2507 if (chan_no <= 14)
2508 freq = ieee80211_channel_to_frequency(chan_no,
2509 IEEE80211_BAND_2GHZ);
2510 else
2511 freq = ieee80211_channel_to_frequency(chan_no,
2512 IEEE80211_BAND_5GHZ);
2513
2514 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, freq);
2515
2516 if (chan)
2517 cfg80211_ibss_joined(pAdapter->dev,
2518 bss->bssid, chan,
2519 GFP_KERNEL);
2520 else
2521 hddLog(LOGE, FL("%s: chanId: %d, can't find channel"),
2522 pAdapter->dev->name,
2523 (int)pRoamInfo->pBssDesc->channelId);
2524#else
2525 cfg80211_ibss_joined(pAdapter->dev, bss->bssid,
2526 GFP_KERNEL);
2527#endif
2528 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002529 pHddCtx->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002530 bss);
2531 }
Krunal Soni2c68f232015-10-26 20:52:51 -07002532 if (eCSR_ROAM_RESULT_IBSS_STARTED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002533 cds_incr_active_session(pAdapter->device_mode,
Krunal Soni2c68f232015-10-26 20:52:51 -07002534 pAdapter->sessionId);
2535 } else if (eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS == roamResult ||
2536 eCSR_ROAM_RESULT_IBSS_COALESCED == roamResult) {
Tushnim Bhattacharyyaca50b322015-12-28 17:14:36 -08002537 cds_update_connection_info(pAdapter->sessionId);
Krunal Soni2c68f232015-10-26 20:52:51 -07002538 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002539 break;
2540 }
2541
2542 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
2543 {
2544 hddLog(LOGE,
2545 FL("%s: unable to create IBSS"), pAdapter->dev->name);
2546 break;
2547 }
2548
2549 default:
2550 hddLog(LOGE, FL("%s: unexpected result %d"),
2551 pAdapter->dev->name, (int)roamResult);
2552 break;
2553 }
2554
2555 return;
2556}
2557
2558/**
2559 * roam_save_ibss_station() - Save the IBSS peer MAC address in the adapter
2560 * @pHddStaCtx: pointer to global HDD station context
2561 * @staId: station id
2562 * @peerMacAddress: pointer to peer MAC address
2563 *
2564 * This information is passed to iwconfig later. The peer that joined
2565 * last is passed as information to iwconfig.
2566 *
2567 * Return:
2568 * true if we add MAX_IBSS_PEERS or less STA
2569 * false otherwise.
2570 */
2571static bool roam_save_ibss_station(hdd_station_ctx_t *pHddStaCtx, uint8_t staId,
Anurag Chouhan6d760662016-02-20 16:05:43 +05302572 struct qdf_mac_addr *peerMacAddress)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002573{
2574 bool fSuccess = false;
2575 int idx = 0;
2576
2577 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2578 if (0 == pHddStaCtx->conn_info.staId[idx]) {
2579 pHddStaCtx->conn_info.staId[idx] = staId;
2580
Anurag Chouhanc5548422016-02-24 18:33:27 +05302581 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002582 peerMacAddress[idx], peerMacAddress);
2583
2584 fSuccess = true;
2585 break;
2586 }
2587 }
2588
2589 return fSuccess;
2590}
2591
2592/**
2593 * roam_remove_ibss_station() - Remove the IBSS peer MAC address in the adapter
2594 * @pAdapter: pointer to adapter
2595 * @staId: station id
2596 *
2597 * Return:
2598 * true if we remove MAX_IBSS_PEERS or less STA
2599 * false otherwise.
2600 */
2601static bool roam_remove_ibss_station(hdd_adapter_t *pAdapter, uint8_t staId)
2602{
2603 bool fSuccess = false;
2604 int idx = 0;
2605 uint8_t valid_idx = 0;
2606 uint8_t del_idx = 0;
2607 uint8_t empty_slots = 0;
2608 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2609
2610 for (idx = 0; idx < MAX_IBSS_PEERS; idx++) {
2611 if (staId == pHddStaCtx->conn_info.staId[idx]) {
2612 pHddStaCtx->conn_info.staId[idx] = 0;
2613
Anurag Chouhanc5548422016-02-24 18:33:27 +05302614 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002615 peerMacAddress[idx]);
2616
2617 fSuccess = true;
2618
2619 /*
2620 * Note the deleted Index, if its 0 we need special
2621 * handling.
2622 */
2623 del_idx = idx;
2624
2625 empty_slots++;
2626 } else {
2627 if (pHddStaCtx->conn_info.staId[idx] != 0) {
2628 valid_idx = idx;
2629 } else {
2630 /* Found an empty slot */
2631 empty_slots++;
2632 }
2633 }
2634 }
2635
2636 if (MAX_IBSS_PEERS == empty_slots) {
2637 /* Last peer departed, set the IBSS state appropriately */
2638 pHddStaCtx->conn_info.connState =
2639 eConnectionState_IbssDisconnected;
2640 hddLog(LOGE, "Last IBSS Peer Departed!!!");
2641 }
2642 /* Find next active staId, to have a valid sta trigger for TL. */
2643 if (fSuccess == true) {
2644 if (del_idx == 0) {
2645 if (pHddStaCtx->conn_info.staId[valid_idx] != 0) {
2646 pHddStaCtx->conn_info.staId[0] =
2647 pHddStaCtx->conn_info.staId[valid_idx];
Anurag Chouhanc5548422016-02-24 18:33:27 +05302648 qdf_copy_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002649 peerMacAddress[0],
2650 &pHddStaCtx->conn_info.
2651 peerMacAddress[valid_idx]);
2652
2653 pHddStaCtx->conn_info.staId[valid_idx] = 0;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302654 qdf_zero_macaddr(&pHddStaCtx->conn_info.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002655 peerMacAddress[valid_idx]);
2656 }
2657 }
2658 }
2659 return fSuccess;
2660}
2661
2662/**
2663 * roam_ibss_connect_handler() - IBSS connection handler
2664 * @pAdapter: pointer to adapter
2665 * @pRoamInfo: pointer to roam info
2666 *
2667 * We update the status of the IBSS to connected in this function.
2668 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302669 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002670 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302671static QDF_STATUS roam_ibss_connect_handler(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002672 tCsrRoamInfo *pRoamInfo)
2673{
2674 struct cfg80211_bss *bss;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002675 /*
2676 * Set the internal connection state to show 'IBSS Connected' (IBSS with
2677 * a partner stations).
2678 */
2679 hdd_conn_set_connection_state(pAdapter, eConnectionState_IbssConnected);
2680
2681 /* Save the connection info from CSR... */
2682 hdd_conn_save_connect_info(pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS);
2683
2684 /* Send the bssid address to the wext. */
2685 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2686 /* add bss_id to cfg80211 data base */
2687 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
2688 if (NULL == bss) {
2689 hddLog(LOGE,
2690 FL("%s: unable to create IBSS entry"),
2691 pAdapter->dev->name);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302692 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002693 }
2694 cfg80211_put_bss(
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002695 WLAN_HDD_GET_CTX(pAdapter)->wiphy,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002696 bss);
2697
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302698 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002699}
2700
2701/**
2702 * hdd_roam_mic_error_indication_handler() - MIC error indication handler
2703 * @pAdapter: pointer to adapter
2704 * @pRoamInfo: pointer to roam info
2705 * @roamId: roam id
2706 * @roamStatus: roam status
2707 * @roamResult: roam result
2708 *
2709 * This function indicates the Mic failure to the supplicant
2710 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302711 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002712 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302713static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002714hdd_roam_mic_error_indication_handler(hdd_adapter_t *pAdapter,
2715 tCsrRoamInfo *pRoamInfo,
2716 uint32_t roamId,
2717 eRoamCmdStatus roamStatus,
2718 eCsrRoamResult roamResult)
2719{
2720 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2721
2722 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
2723 TKIP_COUNTER_MEASURE_STOPED ==
2724 pHddStaCtx->WextState.mTKIPCounterMeasures) {
2725 struct iw_michaelmicfailure msg;
2726 union iwreq_data wreq;
2727 memset(&msg, '\0', sizeof(msg));
2728 msg.src_addr.sa_family = ARPHRD_ETHER;
2729 memcpy(msg.src_addr.sa_data,
2730 pRoamInfo->u.pMICFailureInfo->taMacAddr,
2731 sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
2732 hddLog(LOG1, "MIC MAC " MAC_ADDRESS_STR,
2733 MAC_ADDR_ARRAY(msg.src_addr.sa_data));
2734
2735 if (pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
2736 msg.flags = IW_MICFAILURE_GROUP;
2737 else
2738 msg.flags = IW_MICFAILURE_PAIRWISE;
2739 memset(&wreq, 0, sizeof(wreq));
2740 wreq.data.length = sizeof(msg);
2741 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq,
2742 (char *)&msg);
2743 /* inform mic failure to nl80211 */
2744 cfg80211_michael_mic_failure(pAdapter->dev,
2745 pRoamInfo->u.pMICFailureInfo->
2746 taMacAddr,
2747 ((pRoamInfo->u.pMICFailureInfo->
2748 multicast ==
2749 eSIR_TRUE) ?
2750 NL80211_KEYTYPE_GROUP :
2751 NL80211_KEYTYPE_PAIRWISE),
2752 pRoamInfo->u.pMICFailureInfo->
2753 keyId,
2754 pRoamInfo->u.pMICFailureInfo->TSC,
2755 GFP_KERNEL);
2756
2757 }
2758
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302759 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002760}
2761
2762/**
2763 * roam_roam_connect_status_update_handler() - IBSS connect status update
2764 * @pAdapter: pointer to adapter
2765 * @pRoamInfo: pointer to roam info
2766 * @roamId: roam id
2767 * @roamStatus: roam status
2768 * @roamResult: roam result
2769 *
2770 * The Ibss connection status is updated regularly here in this function.
2771 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302772 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002773 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302774static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002775roam_roam_connect_status_update_handler(hdd_adapter_t *pAdapter,
2776 tCsrRoamInfo *pRoamInfo,
2777 uint32_t roamId,
2778 eRoamCmdStatus roamStatus,
2779 eCsrRoamResult roamResult)
2780{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302781 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002782
2783 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2784 switch (roamResult) {
2785 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
2786 {
2787 hdd_station_ctx_t *pHddStaCtx =
2788 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2789 struct station_info staInfo;
2790
2791 pr_info("IBSS New Peer indication from SME "
2792 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2793 MAC_ADDRESS_STR " and stationID= %d",
2794 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2795 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2796 pRoamInfo->staId);
2797
2798 if (!roam_save_ibss_station
2799 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
2800 pRoamInfo->staId,
2801 &pRoamInfo->peerMac)) {
2802 hddLog(LOGW, "Max reached: Can't register new IBSS peer");
2803 break;
2804 }
2805
2806 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
2807
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002808 /* Register the Station with TL for the new peer. */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302809 qdf_status = hdd_roam_register_sta(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002810 pRoamInfo,
2811 pRoamInfo->staId,
2812 &pRoamInfo->peerMac,
2813 pRoamInfo->pBssDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302814 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002815 hddLog(LOGE,
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302816 "Cannot register STA with TL for IBSS. Failed with qdf_status = %d [%08X]",
2817 qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002818 }
2819 pHddStaCtx->ibss_sta_generation++;
2820 memset(&staInfo, 0, sizeof(staInfo));
2821 staInfo.filled = 0;
2822 staInfo.generation = pHddStaCtx->ibss_sta_generation;
2823
2824 cfg80211_new_sta(pAdapter->dev,
2825 (const u8 *)pRoamInfo->peerMac.bytes,
2826 &staInfo, GFP_KERNEL);
2827
2828 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY ==
2829 pHddStaCtx->ibss_enc_key.encType
2830 || eCSR_ENCRYPT_TYPE_WEP104_STATICKEY ==
2831 pHddStaCtx->ibss_enc_key.encType
2832 || eCSR_ENCRYPT_TYPE_TKIP ==
2833 pHddStaCtx->ibss_enc_key.encType
2834 || eCSR_ENCRYPT_TYPE_AES ==
2835 pHddStaCtx->ibss_enc_key.encType) {
2836 pHddStaCtx->ibss_enc_key.keyDirection =
2837 eSIR_TX_RX;
Anurag Chouhanc5548422016-02-24 18:33:27 +05302838 qdf_copy_macaddr(&pHddStaCtx->ibss_enc_key.peerMac,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002839 &pRoamInfo->peerMac);
2840
2841 hddLog(LOG2, "New peer joined set PTK encType=%d",
2842 pHddStaCtx->ibss_enc_key.encType);
2843
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302844 qdf_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002845 sme_roam_set_key(WLAN_HDD_GET_HAL_CTX
2846 (pAdapter),
2847 pAdapter->sessionId,
2848 &pHddStaCtx->ibss_enc_key,
2849 &roamId);
2850
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302851 if (QDF_STATUS_SUCCESS != qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002852 hddLog(LOGE,
2853 FL("sme_roam_set_key failed, status=%d"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302854 qdf_status);
2855 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002856 }
2857 }
2858 hddLog(LOG1, FL("Enabling queues"));
2859 wlan_hdd_netif_queue_control(pAdapter,
2860 WLAN_START_ALL_NETIF_QUEUE_N_CARRIER,
2861 WLAN_CONTROL_PATH);
2862 break;
2863 }
2864
2865 case eCSR_ROAM_RESULT_IBSS_CONNECT:
2866 {
2867
2868 roam_ibss_connect_handler(pAdapter, pRoamInfo);
2869
2870 break;
2871 }
2872 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
2873 {
2874 hdd_station_ctx_t *pHddStaCtx =
2875 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2876
2877 if (!roam_remove_ibss_station(pAdapter, pRoamInfo->staId))
2878 hddLog(LOGW,
2879 "IBSS peer departed by cannot find peer in our registration table with TL");
2880
2881 pr_info("IBSS Peer Departed from SME "
2882 "with peerMac " MAC_ADDRESS_STR " BSSID: "
2883 MAC_ADDRESS_STR " and stationID= %d",
2884 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
2885 MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId.bytes),
2886 pRoamInfo->staId);
2887
2888 hdd_roam_deregister_sta(pAdapter, pRoamInfo->staId);
2889
2890 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
2891 pHddStaCtx->ibss_sta_generation++;
2892
2893 cfg80211_del_sta(pAdapter->dev,
2894 (const u8 *)&pRoamInfo->peerMac.bytes,
2895 GFP_KERNEL);
2896 break;
2897 }
2898 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
2899 {
2900 hddLog(LOG3,
2901 "Received eCSR_ROAM_RESULT_IBSS_INACTIVE from SME");
2902 /* Stop only when we are inactive */
2903 hddLog(LOG1, FL("Disabling queues"));
2904 wlan_hdd_netif_queue_control(pAdapter,
2905 WLAN_NETIF_TX_DISABLE_N_CARRIER,
2906 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002907 hdd_conn_set_connection_state(pAdapter,
2908 eConnectionState_NotConnected);
2909
2910 /* Send the bssid address to the wext. */
2911 hdd_send_association_event(pAdapter->dev, pRoamInfo);
2912 break;
2913 }
2914 default:
2915 break;
2916
2917 }
2918
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302919 return QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002920}
2921
2922#ifdef FEATURE_WLAN_TDLS
2923/**
2924 * hdd_roam_register_tdlssta() - register new TDLS station
2925 * @pAdapter: pointer to adapter
2926 * @peerMac: pointer to peer MAC address
2927 * @staId: station identifier
2928 * @ucastSig: unicast signature
2929 *
2930 * Construct the staDesc and register with TL the new STA.
2931 * This is called as part of ADD_STA in the TDLS setup.
2932 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302933 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002934 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302935QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002936 const uint8_t *peerMac, uint16_t staId,
2937 uint8_t ucastSig)
2938{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302939 QDF_STATUS qdf_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002940 struct ol_txrx_desc_type staDesc = { 0 };
Dhanashri Atre182b0272016-02-17 15:35:07 -08002941 struct ol_txrx_ops txrx_ops;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002942
2943 /*
2944 * TDLS sta in BSS should be set as STA type TDLS and STA MAC should
2945 * be peer MAC, here we are working on direct Link
2946 */
2947 staDesc.sta_id = staId;
2948
2949 /* set the QoS field appropriately .. */
2950 (hdd_wmm_is_active(pAdapter)) ? (staDesc.is_qos_enabled = 1)
2951 : (staDesc.is_qos_enabled = 0);
2952
Dhanashri Atre50141c52016-04-07 13:15:29 -07002953 /* Register the vdev transmit and receive functions */
2954 qdf_mem_zero(&txrx_ops, sizeof(txrx_ops));
2955 txrx_ops.rx.rx = hdd_rx_packet_cbk;
2956 ol_txrx_vdev_register(
2957 ol_txrx_get_vdev_from_vdev_id(pAdapter->sessionId),
2958 pAdapter, &txrx_ops);
2959 pAdapter->tx_fn = txrx_ops.tx.tx;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002960
2961 /* Register the Station with TL... */
Dhanashri Atre182b0272016-02-17 15:35:07 -08002962 qdf_status = ol_txrx_register_peer(&staDesc);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302963 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002964 hddLog(LOGE, FL("ol_txrx_register_peer() failed to register. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302965 qdf_status, qdf_status);
2966 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002967 }
2968
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302969 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002970}
2971
2972/**
2973 * hdd_roam_deregister_tdlssta() - deregister new TDLS station
2974 * @pAdapter: pointer to adapter
2975 * @staId: station identifier
2976 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302977 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002978 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302979static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002980 uint8_t staId)
2981{
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302982 QDF_STATUS qdf_status;
2983 qdf_status = ol_txrx_clear_peer(staId);
2984 if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002985 hddLog(LOGW, FL("ol_txrx_clear_peer() failed for staID %d. Status=%d [0x%08X]"),
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302986 staId, qdf_status, qdf_status);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002987 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05302988 return qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08002989}
2990
2991/**
2992 * hdd_roam_tdls_status_update_handler() - TDLS status update handler
2993 * @pAdapter: pointer to adapter
2994 * @pRoamInfo: pointer to roam info
2995 * @roamId: roam id
2996 * @roamStatus: roam status
2997 * @roamResult: roam result
2998 *
2999 * HDD interface between SME and TL to ensure TDLS client registration with
3000 * TL in case of new TDLS client is added and deregistration at the time
3001 * TDLS client is deleted.
3002 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303003 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003004 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303005static QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003006hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter,
3007 tCsrRoamInfo *pRoamInfo,
3008 uint32_t roamId,
3009 eRoamCmdStatus roamStatus,
3010 eCsrRoamResult roamResult)
3011{
3012 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
3013 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
3014 tSmeTdlsPeerStateParams smeTdlsPeerStateParams;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303015 QDF_STATUS status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003016 uint8_t staIdx;
3017 hddTdlsPeer_t *curr_peer;
3018 uint32_t reason;
3019
3020 hddLog(LOG2,
3021 ("hdd_tdlsStatusUpdate: %s staIdx %d " MAC_ADDRESS_STR),
3022 roamResult ==
3023 eCSR_ROAM_RESULT_ADD_TDLS_PEER ? "ADD_TDLS_PEER" : roamResult
3024 ==
3025 eCSR_ROAM_RESULT_DELETE_TDLS_PEER ? "DEL_TDLS_PEER" :
3026 roamResult ==
3027 eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND ? "DEL_TDLS_PEER_IND"
3028 : roamResult ==
3029 eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND ?
3030 "DEL_ALL_TDLS_PEER_IND" : roamResult ==
3031 eCSR_ROAM_RESULT_UPDATE_TDLS_PEER ? "UPDATE_TDLS_PEER" :
3032 roamResult ==
3033 eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP ?
3034 "LINK_ESTABLISH_REQ_RSP" : roamResult ==
3035 eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER ? "TDLS_SHOULD_DISCOVER"
3036 : roamResult ==
3037 eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN ? "TDLS_SHOULD_TEARDOWN"
3038 : roamResult ==
3039 eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED ?
3040 "TDLS_SHOULD_PEER_DISCONNECTED" : "UNKNOWN", pRoamInfo->staId,
3041 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes));
3042
3043 if (!pHddTdlsCtx) {
3044 hddLog(LOG1,
3045 FL("TDLS ctx is null, ignore roamResult (%d)"),
3046 roamResult);
3047 return status;
3048 }
3049
3050 switch (roamResult) {
3051 case eCSR_ROAM_RESULT_ADD_TDLS_PEER:
3052 {
3053 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3054 hddLog(LOGE, FL("Add Sta failed. status code(=%d)"),
3055 pRoamInfo->statusCode);
3056 } else {
3057 /*
3058 * Check if there is available index for this new TDLS
3059 * STA.
3060 */
3061 for (staIdx = 0;
3062 staIdx < pHddCtx->max_num_tdls_sta;
3063 staIdx++) {
3064 if (0 ==
3065 pHddCtx->tdlsConnInfo[staIdx].
3066 staId) {
3067 pHddCtx->tdlsConnInfo[staIdx].
3068 sessionId =
3069 pRoamInfo->sessionId;
3070 pHddCtx->tdlsConnInfo[staIdx].
3071 staId = pRoamInfo->staId;
3072
3073 hddLog(LOGW,
3074 ("TDLS: STA IDX at %d is %d "
3075 "of mac "
3076 MAC_ADDRESS_STR),
3077 staIdx,
3078 pHddCtx->
3079 tdlsConnInfo[staIdx].
3080 staId,
3081 MAC_ADDR_ARRAY
3082 (pRoamInfo->peerMac.bytes));
3083
Anurag Chouhanc5548422016-02-24 18:33:27 +05303084 qdf_copy_macaddr(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003085 tdlsConnInfo
3086 [staIdx].
3087 peerMac,
3088 &pRoamInfo->
3089 peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303090 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003091 break;
3092 }
3093 }
3094 if (staIdx < pHddCtx->max_num_tdls_sta) {
3095 if (-1 ==
3096 wlan_hdd_tdls_set_sta_id(pAdapter,
3097 pRoamInfo->
3098 peerMac.bytes,
3099 pRoamInfo->
3100 staId)) {
3101 hddLog(LOGE,
3102 "wlan_hdd_tdls_set_sta_id() failed");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303103 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003104 }
3105
3106 (WLAN_HDD_GET_CTX(pAdapter))->
3107 sta_to_adapter[pRoamInfo->staId] =
3108 pAdapter;
3109 /*
3110 * store the ucast signature,
3111 * if required for further reference.
3112 */
3113
3114 wlan_hdd_tdls_set_signature(pAdapter,
3115 pRoamInfo->
3116 peerMac.bytes,
3117 pRoamInfo->
3118 ucastSig);
3119 } else {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303120 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003121 hddLog(LOGE,
3122 FL("no available slot in conn_info. staId %d cannot be stored"),
3123 pRoamInfo->staId);
3124 }
3125 pAdapter->tdlsAddStaStatus = status;
3126 }
3127 complete(&pAdapter->tdls_add_station_comp);
3128 break;
3129 }
3130 case eCSR_ROAM_RESULT_UPDATE_TDLS_PEER:
3131 {
3132 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3133 hddLog(LOGE,
3134 FL("Add Sta failed. status code(=%d)"),
3135 pRoamInfo->statusCode);
3136 }
3137 /* store the ucast signature which will be used later when
3138 * registering to TL
3139 */
3140 pAdapter->tdlsAddStaStatus = pRoamInfo->statusCode;
3141 complete(&pAdapter->tdls_add_station_comp);
3142 break;
3143 }
3144 case eCSR_ROAM_RESULT_LINK_ESTABLISH_REQ_RSP:
3145 {
3146 if (eSIR_SME_SUCCESS != pRoamInfo->statusCode) {
3147 hddLog(LOGE,
3148 FL("Link Establish Request failed. status(=%d)"),
3149 pRoamInfo->statusCode);
3150 }
3151 complete(&pAdapter->tdls_link_establish_req_comp);
3152 break;
3153 }
3154 case eCSR_ROAM_RESULT_DELETE_TDLS_PEER:
3155 {
3156 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3157 staIdx++) {
3158 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3159 pRoamInfo->sessionId)
3160 && pRoamInfo->staId ==
3161 pHddCtx->tdlsConnInfo[staIdx].staId) {
3162 hddLog(LOGW,
3163 ("HDD: del STA IDX = %x"),
3164 pRoamInfo->staId);
3165
3166 curr_peer =
3167 wlan_hdd_tdls_find_peer(pAdapter,
3168 pRoamInfo->
3169 peerMac.bytes,
3170 true);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303171 if (NULL != curr_peer) {
3172 hdd_info("Current status for peer " MAC_ADDRESS_STR " is %d",
3173 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3174 curr_peer->link_status);
3175 if (TDLS_IS_CONNECTED(curr_peer)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003176 hdd_roam_deregister_tdlssta
3177 (pAdapter,
3178 pRoamInfo->staId);
3179 wlan_hdd_tdls_decrement_peer_count
3180 (pAdapter);
Agrawal Ashishdd2075b2015-10-30 13:05:27 +05303181 } else if (eTDLS_LINK_CONNECTING ==
3182 curr_peer->link_status) {
3183 hdd_roam_deregister_tdlssta
3184 (pAdapter,
3185 pRoamInfo->staId);
3186 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003187 }
3188 wlan_hdd_tdls_reset_peer(pAdapter,
3189 pRoamInfo->
3190 peerMac.bytes);
3191
3192 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3193 pHddCtx->tdlsConnInfo[staIdx].
3194 sessionId = 255;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303195 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003196 tdlsConnInfo[staIdx].
3197 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303198 QDF_MAC_ADDR_SIZE);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303199 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003200 break;
3201 }
3202 }
3203 complete(&pAdapter->tdls_del_station_comp);
3204 }
3205 break;
3206 case eCSR_ROAM_RESULT_TEARDOWN_TDLS_PEER_IND:
3207 {
3208 hddLog(LOGE,
3209 FL("Sending teardown to supplicant with reason code %u"),
3210 pRoamInfo->reasonCode);
3211
3212 curr_peer =
3213 wlan_hdd_tdls_find_peer(pAdapter,
3214 pRoamInfo->peerMac.bytes, true);
3215 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer,
3216 pRoamInfo->reasonCode);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303217 hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_BSS_DISCONNECT,
3218 curr_peer->peerMac);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303219 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003220 break;
3221 }
3222 case eCSR_ROAM_RESULT_DELETE_ALL_TDLS_PEER_IND:
3223 {
3224 /* 0 staIdx is assigned to AP we dont want to touch that */
3225 for (staIdx = 0; staIdx < pHddCtx->max_num_tdls_sta;
3226 staIdx++) {
3227 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId ==
3228 pRoamInfo->sessionId)
3229 && pHddCtx->tdlsConnInfo[staIdx].staId) {
3230 hddLog(LOGW,
3231 ("hdd_tdlsStatusUpdate: staIdx %d "
3232 MAC_ADDRESS_STR),
3233 pHddCtx->tdlsConnInfo[staIdx].
3234 staId,
3235 MAC_ADDR_ARRAY(pHddCtx->
3236 tdlsConnInfo
3237 [staIdx].
3238 peerMac.
3239 bytes));
3240 wlan_hdd_tdls_reset_peer(pAdapter,
3241 pHddCtx->
3242 tdlsConnInfo
3243 [staIdx].
3244 peerMac.bytes);
3245 hdd_roam_deregister_tdlssta(pAdapter,
3246 pHddCtx->
3247 tdlsConnInfo
3248 [staIdx].
3249 staId);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303250 qdf_mem_zero(&smeTdlsPeerStateParams,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003251 sizeof
3252 (smeTdlsPeerStateParams));
3253 smeTdlsPeerStateParams.vdevId =
3254 pHddCtx->tdlsConnInfo[staIdx].
3255 sessionId;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303256 qdf_mem_copy(&smeTdlsPeerStateParams.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003257 peerMacAddr,
3258 &pHddCtx->
3259 tdlsConnInfo[staIdx].
3260 peerMac.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303261 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003262 smeTdlsPeerStateParams.peerState =
3263 eSME_TDLS_PEER_STATE_TEARDOWN;
3264
3265 hddLog(LOG1,
3266 FL("calling sme_update_tdls_peer_state for staIdx %d "
3267 MAC_ADDRESS_STR),
3268 pHddCtx->tdlsConnInfo[staIdx].
3269 staId,
3270 MAC_ADDR_ARRAY(pHddCtx->
3271 tdlsConnInfo
3272 [staIdx].
3273 peerMac.
3274 bytes));
3275 status =
3276 sme_update_tdls_peer_state(
3277 pHddCtx->hHal,
3278 &smeTdlsPeerStateParams);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303279 if (QDF_STATUS_SUCCESS != status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003280 hddLog(LOGE,
3281 FL("sme_update_tdls_peer_state failed for "
3282 MAC_ADDRESS_STR),
3283 MAC_ADDR_ARRAY
3284 (pHddCtx->
3285 tdlsConnInfo[staIdx].
3286 peerMac.bytes));
3287 }
3288 wlan_hdd_tdls_decrement_peer_count
3289 (pAdapter);
3290
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303291 qdf_mem_zero(&pHddCtx->
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003292 tdlsConnInfo[staIdx].
3293 peerMac,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303294 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003295 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
3296 pHddCtx->tdlsConnInfo[staIdx].
3297 sessionId = 255;
3298
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303299 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003300 }
3301 }
3302 break;
3303 }
3304 case eCSR_ROAM_RESULT_TDLS_SHOULD_DISCOVER:
3305 {
3306 /* ignore TDLS_SHOULD_DISCOVER if any concurrency detected */
Anurag Chouhan6d760662016-02-20 16:05:43 +05303307 if (((1 << QDF_STA_MODE) != pHddCtx->concurrency_mode) ||
3308 (pHddCtx->no_of_active_sessions[QDF_STA_MODE] > 1)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003309 hddLog(LOG2,
3310 FL("concurrency detected. ignore SHOULD_DISCOVER concurrency_mode: 0x%x, active_sessions: %d"),
3311 pHddCtx->concurrency_mode,
Anurag Chouhan6d760662016-02-20 16:05:43 +05303312 pHddCtx->no_of_active_sessions[QDF_STA_MODE]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303313 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003314 break;
3315 }
3316
3317 curr_peer =
3318 wlan_hdd_tdls_get_peer(pAdapter,
3319 pRoamInfo->peerMac.bytes);
3320 if (!curr_peer) {
3321 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303322 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003323 } else {
3324 if (eTDLS_LINK_CONNECTED ==
3325 curr_peer->link_status) {
3326 hddLog(LOGE,
3327 FL("TDLS link status is connected, ignore SHOULD_DISCOVER"));
3328 } else {
3329 /*
3330 * If external control is enabled then initiate
3331 * TDLS only if forced peer is set otherwise
3332 * ignore should Discover trigger from fw.
3333 */
3334 if (pHddCtx->config->
3335 fTDLSExternalControl
3336 && (false ==
3337 curr_peer->isForcedPeer)) {
3338 hddLog(LOG2,
3339 FL
3340 ("TDLS ExternalControl enabled but curr_peer is not forced, ignore SHOULD_DISCOVER"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303341 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003342 break;
3343 } else {
3344 hddLog(LOG2,
3345 FL
3346 ("initiate TDLS setup on SHOULD_DISCOVER, fTDLSExternalControl: %d, curr_peer->isForcedPeer: %d, reason: %d"),
3347 pHddCtx->config->
3348 fTDLSExternalControl,
3349 curr_peer->isForcedPeer,
3350 pRoamInfo->reasonCode);
3351 }
3352 wlan_hdd_tdls_pre_setup_init_work
3353 (pHddTdlsCtx, curr_peer);
3354 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303355 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003356 }
3357 break;
3358 }
3359
3360 case eCSR_ROAM_RESULT_TDLS_SHOULD_TEARDOWN:
3361 {
3362 curr_peer =
3363 wlan_hdd_tdls_find_peer(pAdapter,
3364 pRoamInfo->peerMac.bytes, true);
3365 if (!curr_peer) {
3366 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303367 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003368 } else {
3369 if (eTDLS_LINK_CONNECTED ==
3370 curr_peer->link_status) {
3371 hddLog(LOGE,
3372 FL
3373 ("Received SHOULD_TEARDOWN for peer "
3374 MAC_ADDRESS_STR
3375 " staId: %d, reason: %d"),
3376 MAC_ADDR_ARRAY(pRoamInfo->
3377 peerMac.bytes),
3378 pRoamInfo->staId,
3379 pRoamInfo->reasonCode);
3380
3381 if (pRoamInfo->reasonCode ==
3382 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3383 pRoamInfo->reasonCode ==
3384 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3385 pRoamInfo->reasonCode ==
3386 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3387 pRoamInfo->reasonCode ==
3388 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3389 reason =
3390 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3391 } else
3392 reason =
3393 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3394
3395 wlan_hdd_tdls_indicate_teardown
3396 (pHddTdlsCtx->pAdapter, curr_peer,
3397 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303398 hdd_send_wlan_tdls_teardown_event(
3399 eTDLS_TEARDOWN_BSS_DISCONNECT,
3400 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003401 } else {
3402 hddLog(LOGE,
3403 FL
3404 ("TDLS link is not connected, ignore SHOULD_TEARDOWN, reason: %d"),
3405 pRoamInfo->reasonCode);
3406 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303407 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003408 }
3409 break;
3410 }
3411
3412 case eCSR_ROAM_RESULT_TDLS_SHOULD_PEER_DISCONNECTED:
3413 {
3414 curr_peer =
3415 wlan_hdd_tdls_find_peer(pAdapter,
3416 pRoamInfo->peerMac.bytes, true);
3417 if (!curr_peer) {
3418 hddLog(LOGE, FL("curr_peer is null"));
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303419 status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003420 } else {
3421 if (eTDLS_LINK_CONNECTED ==
3422 curr_peer->link_status) {
3423 hddLog(LOGE,
3424 FL
3425 ("Received SHOULD_PEER_DISCONNECTED for peer "
3426 MAC_ADDRESS_STR
3427 " staId: %d, reason: %d"),
3428 MAC_ADDR_ARRAY(pRoamInfo->peerMac.bytes),
3429 pRoamInfo->staId,
3430 pRoamInfo->reasonCode);
3431
3432 if (pRoamInfo->reasonCode ==
3433 eWNI_TDLS_TEARDOWN_REASON_RSSI ||
3434 pRoamInfo->reasonCode ==
3435 eWNI_TDLS_DISCONNECTED_REASON_PEER_DELETE ||
3436 pRoamInfo->reasonCode ==
3437 eWNI_TDLS_TEARDOWN_REASON_PTR_TIMEOUT ||
3438 pRoamInfo->reasonCode ==
3439 eWNI_TDLS_TEARDOWN_REASON_NO_RESPONSE) {
3440 reason =
3441 eSIR_MAC_TDLS_TEARDOWN_PEER_UNREACHABLE;
3442 } else
3443 reason =
3444 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON;
3445
3446 wlan_hdd_tdls_indicate_teardown
3447 (pHddTdlsCtx->pAdapter, curr_peer,
3448 reason);
Abhishek Singh4ef5fe02016-04-27 12:21:24 +05303449 hdd_send_wlan_tdls_teardown_event(
3450 eTDLS_TEARDOWN_BSS_DISCONNECT,
3451 curr_peer->peerMac);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003452 } else {
3453 hddLog(LOGE,
3454 FL
3455 ("TDLS link is not connected, ignore SHOULD_PEER_DISCONNECTED, reason: %d"),
3456 pRoamInfo->reasonCode);
3457 }
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303458 status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003459 }
3460 break;
3461 }
3462 default:
3463 {
3464 break;
3465 }
3466 }
3467
3468 return status;
3469}
3470#endif
3471
3472#ifdef WLAN_FEATURE_11W
3473/**
3474 * hdd_indicate_unprot_mgmt_frame() - indicate unprotected management frame
3475 * @pAdapter: pointer to the adapter
3476 * @nFrameLength: Length of the unprotected frame being passed
3477 * @pbFrames: Pointer to the frame buffer
3478 * @frameType: 802.11 frame type
3479 *
3480 * This function forwards the unprotected management frame to the supplicant.
3481 *
3482 * Return: nothing
3483 */
3484static void
3485hdd_indicate_unprot_mgmt_frame(hdd_adapter_t *pAdapter, uint32_t nFrameLength,
3486 uint8_t *pbFrames, uint8_t frameType)
3487{
3488 uint8_t type = 0;
3489 uint8_t subType = 0;
3490
3491 hddLog(LOG1, FL("Frame Type = %d Frame Length = %d"),
3492 frameType, nFrameLength);
3493
3494 /* Sanity Checks */
3495 if (NULL == pAdapter) {
3496 hddLog(LOGE, FL("pAdapter is NULL"));
3497 return;
3498 }
3499
3500 if (NULL == pAdapter->dev) {
3501 hddLog(LOGE, FL("pAdapter->dev is NULL"));
3502 return;
3503 }
3504
3505 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic) {
3506 hddLog(LOGE, FL("pAdapter has invalid magic"));
3507 return;
3508 }
3509
3510 if (!nFrameLength) {
3511 hddLog(LOGE, FL("Frame Length is Invalid ZERO"));
3512 return;
3513 }
3514
3515 if (NULL == pbFrames) {
3516 hddLog(LOGE, FL("pbFrames is NULL"));
3517 return;
3518 }
3519
3520 type = WLAN_HDD_GET_TYPE_FRM_FC(pbFrames[0]);
3521 subType = WLAN_HDD_GET_SUBTYPE_FRM_FC(pbFrames[0]);
3522
3523 /* Get pAdapter from Destination mac address of the frame */
3524 if (type == SIR_MAC_MGMT_FRAME && subType == SIR_MAC_MGMT_DISASSOC) {
3525#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3526 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3527 nFrameLength);
3528#else
3529 cfg80211_send_unprot_disassoc(pAdapter->dev, pbFrames,
3530 nFrameLength);
3531#endif
3532 pAdapter->hdd_stats.hddPmfStats.numUnprotDisassocRx++;
3533 } else if (type == SIR_MAC_MGMT_FRAME &&
3534 subType == SIR_MAC_MGMT_DEAUTH) {
3535#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
3536 cfg80211_rx_unprot_mlme_mgmt(pAdapter->dev, pbFrames,
3537 nFrameLength);
3538#else
3539 cfg80211_send_unprot_deauth(pAdapter->dev, pbFrames,
3540 nFrameLength);
3541#endif
3542 pAdapter->hdd_stats.hddPmfStats.numUnprotDeauthRx++;
3543 } else {
3544 hddLog(LOGE, FL("Frame type %d and subtype %d are not valid"),
3545 type, subType);
3546 return;
3547 }
3548}
3549#endif
3550
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003551#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003552/**
3553 * hdd_indicate_tsm_ie() - send traffic stream metrics ie
3554 * @pAdapter: pointer to adapter
3555 * @tid: traffic identifier
3556 * @state: state
3557 * @measInterval: measurement interval
3558 *
3559 * This function sends traffic stream metrics IE information to
3560 * the supplicant via wireless event.
3561 *
3562 * Return: none
3563 */
3564static void
3565hdd_indicate_tsm_ie(hdd_adapter_t *pAdapter, uint8_t tid,
3566 uint8_t state, uint16_t measInterval)
3567{
3568 union iwreq_data wrqu;
3569 char buf[IW_CUSTOM_MAX + 1];
3570 int nBytes = 0;
3571
3572 if (NULL == pAdapter)
3573 return;
3574
3575 /* create the event */
3576 memset(&wrqu, '\0', sizeof(wrqu));
3577 memset(buf, '\0', sizeof(buf));
3578
3579 hddLog(LOG1, "TSM Ind tid(%d) state(%d) MeasInt(%d)",
3580 tid, state, measInterval);
3581
3582 nBytes =
3583 snprintf(buf, IW_CUSTOM_MAX, "TSMIE=%d:%d:%d", tid, state,
3584 measInterval);
3585
3586 wrqu.data.pointer = buf;
3587 wrqu.data.length = nBytes;
3588 /* send the event */
3589 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3590}
3591
3592/**
3593 * hdd_indicate_cckm_pre_auth() - send cckm preauth indication
3594 * @pAdapter: pointer to adapter
3595 * @pRoamInfo: pointer to roam info
3596 *
3597 * This function sends cckm preauth indication to the supplicant
3598 * via wireless custom event.
3599 *
3600 * Return: none
3601 */
3602static void
3603hdd_indicate_cckm_pre_auth(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo)
3604{
3605 union iwreq_data wrqu;
3606 char buf[IW_CUSTOM_MAX + 1];
3607 char *pos = buf;
3608 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3609
3610 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3611 return;
3612
3613 /* create the event */
3614 memset(&wrqu, '\0', sizeof(wrqu));
3615 memset(buf, '\0', sizeof(buf));
3616
3617 /* Timestamp0 is lower 32 bits and Timestamp1 is upper 32 bits */
3618 hddLog(LOG1,
3619 "CCXPREAUTHNOTIFY=" MAC_ADDRESS_STR " %d:%d",
3620 MAC_ADDR_ARRAY(pRoamInfo->bssid.bytes),
3621 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3622
3623 nBytes = snprintf(pos, freeBytes, "CCXPREAUTHNOTIFY=");
3624 pos += nBytes;
3625 freeBytes -= nBytes;
3626
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303627 qdf_mem_copy(pos, pRoamInfo->bssid.bytes, QDF_MAC_ADDR_SIZE);
Anurag Chouhan6d760662016-02-20 16:05:43 +05303628 pos += QDF_MAC_ADDR_SIZE;
3629 freeBytes -= QDF_MAC_ADDR_SIZE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003630
3631 nBytes = snprintf(pos, freeBytes, " %u:%u",
3632 pRoamInfo->timestamp[0], pRoamInfo->timestamp[1]);
3633 freeBytes -= nBytes;
3634
3635 wrqu.data.pointer = buf;
3636 wrqu.data.length = (IW_CUSTOM_MAX - freeBytes);
3637
3638 /* send the event */
3639 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3640}
3641
3642/**
3643 * hdd_indicate_ese_adj_ap_rep_ind() - send adjacent AP report indication
3644 * @pAdapter: pointer to adapter
3645 * @pRoamInfo: pointer to roam info
3646 *
3647 * Return: none
3648 */
3649static void
3650hdd_indicate_ese_adj_ap_rep_ind(hdd_adapter_t *pAdapter,
3651 tCsrRoamInfo *pRoamInfo)
3652{
3653 union iwreq_data wrqu;
3654 char buf[IW_CUSTOM_MAX + 1];
3655 int nBytes = 0;
3656
3657 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3658 return;
3659
3660 /* create the event */
3661 memset(&wrqu, '\0', sizeof(wrqu));
3662 memset(buf, '\0', sizeof(buf));
3663
3664 hddLog(LOG1, "CCXADJAPREP=%u", pRoamInfo->tsmRoamDelay);
3665
3666 nBytes =
3667 snprintf(buf, IW_CUSTOM_MAX, "CCXADJAPREP=%u",
3668 pRoamInfo->tsmRoamDelay);
3669
3670 wrqu.data.pointer = buf;
3671 wrqu.data.length = nBytes;
3672
3673 /* send the event */
3674 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3675}
3676
3677/**
3678 * hdd_indicate_ese_bcn_report_no_results() - beacon report no scan results
3679 * @pAdapter: pointer to adapter
3680 * @measurementToken: measurement token
3681 * @flag: flag
3682 * @numBss: number of bss
3683 *
3684 * If the measurement is none and no scan results found,
3685 * indicate the supplicant about measurement done.
3686 *
3687 * Return: none
3688 */
3689void
3690hdd_indicate_ese_bcn_report_no_results(const hdd_adapter_t *pAdapter,
3691 const uint16_t measurementToken,
3692 const bool flag, const uint8_t numBss)
3693{
3694 union iwreq_data wrqu;
3695 char buf[IW_CUSTOM_MAX];
3696 char *pos = buf;
3697 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3698
3699 memset(&wrqu, '\0', sizeof(wrqu));
3700 memset(buf, '\0', sizeof(buf));
3701
3702 hddLog(LOG1, FL("CCXBCNREP=%d %d %d"), measurementToken,
3703 flag, numBss);
3704
3705 nBytes =
3706 snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d", measurementToken,
3707 flag, numBss);
3708
3709 wrqu.data.pointer = buf;
3710 wrqu.data.length = nBytes;
3711 /* send the event */
3712 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buf);
3713}
3714
3715/**
3716 * hdd_indicate_ese_bcn_report_ind() - send beacon report indication
3717 * @pAdapter: pointer to adapter
3718 * @pRoamInfo: pointer to roam info
3719 *
3720 * If the measurement is none and no scan results found,
3721 * indicate the supplicant about measurement done.
3722 *
3723 * Return: none
3724 */
3725static void
3726hdd_indicate_ese_bcn_report_ind(const hdd_adapter_t *pAdapter,
3727 const tCsrRoamInfo *pRoamInfo)
3728{
3729 union iwreq_data wrqu;
3730 char buf[IW_CUSTOM_MAX];
3731 char *pos = buf;
3732 int nBytes = 0, freeBytes = IW_CUSTOM_MAX;
3733 uint8_t i = 0, len = 0;
3734 uint8_t tot_bcn_ieLen = 0; /* total size of the beacon report data */
3735 uint8_t lastSent = 0, sendBss = 0;
3736 int bcnRepFieldSize =
3737 sizeof(pRoamInfo->pEseBcnReportRsp->bcnRepBssInfo[0].
3738 bcnReportFields);
3739 uint8_t ieLenByte = 1;
3740 /*
3741 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3742 */
3743#define ESEBCNREPHEADER_LEN (18)
3744
3745 if ((NULL == pAdapter) || (NULL == pRoamInfo))
3746 return;
3747
3748 /*
3749 * Custom event can pass maximum of 256 bytes of data,
3750 * based on the IE len we need to identify how many BSS info can
3751 * be filled in to custom event data.
3752 */
3753 /*
3754 * meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len bcn_rep_data
3755 * bcn_rep_data will have bcn_rep_fields,ie_len,ie without any spaces
3756 * CCXBCNREP=meas_tok<sp>flag<sp>no_of_bss<sp>tot_bcn_ie_len = 18 bytes
3757 */
3758
3759 if ((pRoamInfo->pEseBcnReportRsp->flag >> 1)
3760 && (!pRoamInfo->pEseBcnReportRsp->numBss)) {
3761 hddLog(LOG1,
3762 "Measurement Done but no scan results");
3763 /* If the measurement is none and no scan results found,
3764 indicate the supplicant about measurement done */
3765 hdd_indicate_ese_bcn_report_no_results(
3766 pAdapter,
3767 pRoamInfo->pEseBcnReportRsp->
3768 measurementToken,
3769 pRoamInfo->pEseBcnReportRsp->flag,
3770 pRoamInfo->pEseBcnReportRsp->numBss);
3771 } else {
3772 while (lastSent < pRoamInfo->pEseBcnReportRsp->numBss) {
3773 memset(&wrqu, '\0', sizeof(wrqu));
3774 memset(buf, '\0', sizeof(buf));
3775 tot_bcn_ieLen = 0;
3776 sendBss = 0;
3777 pos = buf;
3778 freeBytes = IW_CUSTOM_MAX;
3779
3780 for (i = lastSent;
3781 i < pRoamInfo->pEseBcnReportRsp->numBss; i++) {
3782 len =
3783 bcnRepFieldSize + ieLenByte +
3784 pRoamInfo->pEseBcnReportRsp->
3785 bcnRepBssInfo[i].ieLen;
3786 if ((len + tot_bcn_ieLen) >
3787 (IW_CUSTOM_MAX - ESEBCNREPHEADER_LEN)) {
3788 break;
3789 }
3790 tot_bcn_ieLen += len;
3791 sendBss++;
3792 hddLog(LOG1, "i(%d) sizeof bcnReportFields(%d) IeLength(%d) Length of Ie(%d) totLen(%d)",
3793 i, bcnRepFieldSize, 1,
3794 pRoamInfo->pEseBcnReportRsp->
3795 bcnRepBssInfo[i].ieLen, tot_bcn_ieLen);
3796 }
3797
3798 hddLog(LOG1, "Sending %d BSS Info",
3799 sendBss);
3800 hddLog(LOG1, "CCXBCNREP=%d %d %d %d",
3801 pRoamInfo->pEseBcnReportRsp->measurementToken,
3802 pRoamInfo->pEseBcnReportRsp->flag, sendBss,
3803 tot_bcn_ieLen);
3804
3805 nBytes = snprintf(pos, freeBytes, "CCXBCNREP=%d %d %d ",
3806 pRoamInfo->pEseBcnReportRsp->
3807 measurementToken,
3808 pRoamInfo->pEseBcnReportRsp->flag,
3809 sendBss);
3810 pos += nBytes;
3811 freeBytes -= nBytes;
3812
3813 /* Copy total Beacon report data length */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303814 qdf_mem_copy(pos, (char *)&tot_bcn_ieLen,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003815 sizeof(tot_bcn_ieLen));
3816 pos += sizeof(tot_bcn_ieLen);
3817 freeBytes -= sizeof(tot_bcn_ieLen);
3818
3819 for (i = 0; i < sendBss; i++) {
3820 hddLog(LOG1,
3821 "ChanNum(%d) Spare(%d) MeasDuration(%d)"
3822 " PhyType(%d) RecvSigPower(%d) ParentTSF(%u)"
3823 " TargetTSF[0](%u) TargetTSF[1](%u) BeaconInterval(%u)"
3824 " CapabilityInfo(%d) BSSID(%02X:%02X:%02X:%02X:%02X:%02X)",
3825 pRoamInfo->pEseBcnReportRsp->
3826 bcnRepBssInfo[i +
3827 lastSent].bcnReportFields.
3828 ChanNum,
3829 pRoamInfo->pEseBcnReportRsp->
3830 bcnRepBssInfo[i +
3831 lastSent].bcnReportFields.
3832 Spare,
3833 pRoamInfo->pEseBcnReportRsp->
3834 bcnRepBssInfo[i +
3835 lastSent].bcnReportFields.
3836 MeasDuration,
3837 pRoamInfo->pEseBcnReportRsp->
3838 bcnRepBssInfo[i +
3839 lastSent].bcnReportFields.
3840 PhyType,
3841 pRoamInfo->pEseBcnReportRsp->
3842 bcnRepBssInfo[i +
3843 lastSent].bcnReportFields.
3844 RecvSigPower,
3845 pRoamInfo->pEseBcnReportRsp->
3846 bcnRepBssInfo[i +
3847 lastSent].bcnReportFields.
3848 ParentTsf,
3849 pRoamInfo->pEseBcnReportRsp->
3850 bcnRepBssInfo[i +
3851 lastSent].bcnReportFields.
3852 TargetTsf[0],
3853 pRoamInfo->pEseBcnReportRsp->
3854 bcnRepBssInfo[i +
3855 lastSent].bcnReportFields.
3856 TargetTsf[1],
3857 pRoamInfo->pEseBcnReportRsp->
3858 bcnRepBssInfo[i +
3859 lastSent].bcnReportFields.
3860 BcnInterval,
3861 pRoamInfo->pEseBcnReportRsp->
3862 bcnRepBssInfo[i +
3863 lastSent].bcnReportFields.
3864 CapabilityInfo,
3865 pRoamInfo->pEseBcnReportRsp->
3866 bcnRepBssInfo[i +
3867 lastSent].bcnReportFields.
3868 Bssid[0],
3869 pRoamInfo->pEseBcnReportRsp->
3870 bcnRepBssInfo[i +
3871 lastSent].bcnReportFields.
3872 Bssid[1],
3873 pRoamInfo->pEseBcnReportRsp->
3874 bcnRepBssInfo[i +
3875 lastSent].bcnReportFields.
3876 Bssid[2],
3877 pRoamInfo->pEseBcnReportRsp->
3878 bcnRepBssInfo[i +
3879 lastSent].bcnReportFields.
3880 Bssid[3],
3881 pRoamInfo->pEseBcnReportRsp->
3882 bcnRepBssInfo[i +
3883 lastSent].bcnReportFields.
3884 Bssid[4],
3885 pRoamInfo->pEseBcnReportRsp->
3886 bcnRepBssInfo[i +
3887 lastSent].bcnReportFields.
3888 Bssid[5]);
3889
3890 /* bcn report fields are copied */
3891 len =
3892 sizeof(pRoamInfo->pEseBcnReportRsp->
3893 bcnRepBssInfo[i +
3894 lastSent].
3895 bcnReportFields);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303896 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003897 (char *)&pRoamInfo->
3898 pEseBcnReportRsp->bcnRepBssInfo[i +
3899 lastSent].
3900 bcnReportFields, len);
3901 pos += len;
3902 freeBytes -= len;
3903
3904 /* Add 1 byte of ie len */
3905 len =
3906 pRoamInfo->pEseBcnReportRsp->
3907 bcnRepBssInfo[i + lastSent].ieLen;
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303908 qdf_mem_copy(pos, (char *)&len, sizeof(len));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003909 pos += sizeof(len);
3910 freeBytes -= sizeof(len);
3911
3912 /* copy IE from scan results */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05303913 qdf_mem_copy(pos,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003914 (char *)pRoamInfo->
3915 pEseBcnReportRsp->bcnRepBssInfo[i +
3916 lastSent].
3917 pBuf, len);
3918 pos += len;
3919 freeBytes -= len;
3920 }
3921
3922 wrqu.data.pointer = buf;
3923 wrqu.data.length = IW_CUSTOM_MAX - freeBytes;
3924
3925 /* send the event */
3926 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu,
3927 buf);
3928 lastSent += sendBss;
3929 }
3930 }
3931}
3932
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08003933#endif /* FEATURE_WLAN_ESE */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003934
3935/**
Komal Seelam98760ba2015-12-15 11:05:18 +05303936 * hdd_is_8021x_sha256_auth_type() - check authentication type to 8021x_sha256
3937 * @pHddStaCtx: Station Context
3938 *
3939 * API to check if the connection authentication type is 8021x_sha256.
3940 *
3941 * Return: bool
3942 */
3943#ifdef WLAN_FEATURE_11W
3944static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3945{
3946 return eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
3947 pHddStaCtx->conn_info.authType;
3948}
3949#else
3950static inline bool hdd_is_8021x_sha256_auth_type(hdd_station_ctx_t *pHddStaCtx)
3951{
3952 return false;
3953}
3954#endif
3955
3956/**
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003957 * hdd_sme_roam_callback() - hdd sme roam callback
3958 * @pContext: pointer to adapter context
3959 * @pRoamInfo: pointer to roam info
3960 * @roamId: roam id
3961 * @roamStatus: roam status
3962 * @roamResult: roam result
3963 *
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303964 * Return: QDF_STATUS enumeration
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003965 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303966QDF_STATUS
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003967hdd_sme_roam_callback(void *pContext, tCsrRoamInfo *pRoamInfo, uint32_t roamId,
3968 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult)
3969{
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05303970 QDF_STATUS qdf_ret_status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003971 hdd_adapter_t *pAdapter = (hdd_adapter_t *) pContext;
3972 hdd_wext_state_t *pWextState = NULL;
3973 hdd_station_ctx_t *pHddStaCtx = NULL;
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303974 QDF_STATUS status = QDF_STATUS_SUCCESS;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003975 hdd_context_t *pHddCtx = NULL;
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05303976 struct hdd_chan_change_params chan_change;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003977
3978 hddLog(LOG2,
3979 "CSR Callback: status= %d result= %d roamID=%d",
3980 roamStatus, roamResult, roamId);
3981
3982 /* Sanity check */
3983 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)) {
3984 hddLog(LOGP, "invalid adapter or adapter has invalid magic");
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05303985 return QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003986 }
3987
3988 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
3989 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
3990
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +05303991 MTRACE(qdf_trace(QDF_MODULE_ID_HDD, TRACE_CODE_HDD_RX_SME_MSG,
Sreelakshmi Konamkic88f5372015-12-22 12:50:15 +05303992 pAdapter->sessionId, roamStatus));
3993
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003994 switch (roamStatus) {
3995 case eCSR_ROAM_SESSION_OPENED:
Sreelakshmi Konamki6f3a8652015-09-25 10:58:15 +05303996 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
3997 complete(&pAdapter->session_open_comp_var);
Peng Xu66162de2016-02-11 17:01:20 -08003998 hdd_debug("session %d opened", pAdapter->sessionId);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003999 break;
4000
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004001 /*
4002 * We did pre-auth,then we attempted a 11r or ese reassoc.
4003 * reassoc failed due to failure, timeout, reject from ap
4004 * in any case tell the OS, our carrier is off and mark
4005 * interface down.
4006 */
4007 case eCSR_ROAM_FT_REASSOC_FAILED:
4008 hddLog(LOGE,
4009 FL
4010 ("Reassoc Failed with roamStatus: %d roamResult: %d SessionID: %d"),
4011 roamStatus, roamResult, pAdapter->sessionId);
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304012 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004013 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4014 roamStatus, roamResult);
4015 /*
4016 * Check if Mcast/Bcast Filters are set, if yes
4017 * clear the filters here.
4018 */
4019 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set ==
4020 true) {
4021 (WLAN_HDD_GET_CTX(pAdapter))->
4022 hdd_mcastbcast_filter_set = false;
4023 }
4024 pHddStaCtx->ft_carrier_on = false;
4025 pHddStaCtx->hdd_ReassocScenario = false;
4026 hddLog(LOG1,
4027 FL("hdd_ReassocScenario set to: %d, ReAssoc Failed, session: %d"),
4028 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4029 break;
4030
4031 case eCSR_ROAM_FT_START:
4032 /*
4033 * When we roam for ESE and 11r, we dont want the OS to be
4034 * informed that the link is down. So mark the link ready for
4035 * ft_start. After this the eCSR_ROAM_SHOULD_ROAM will
4036 * be received. Where in we will not mark the link down
4037 * Also we want to stop tx at this point when we will be
4038 * doing disassoc at this time. This saves 30-60 msec
4039 * after reassoc.
4040 */
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004041 hddLog(LOG1, FL("Disabling queues"));
Deepak Dhamdherea2df6bb2015-10-29 15:11:06 -07004042 wlan_hdd_netif_queue_control(pAdapter,
4043 WLAN_NETIF_TX_DISABLE,
4044 WLAN_CONTROL_PATH);
4045 status = hdd_roam_deregister_sta(pAdapter,
4046 pHddStaCtx->conn_info.staId[0]);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304047 if (!QDF_IS_STATUS_SUCCESS(status))
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304048 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004049 pHddStaCtx->ft_carrier_on = true;
4050 pHddStaCtx->hdd_ReassocScenario = true;
4051 hddLog(LOG1,
4052 FL("hdd_ReassocScenario set to: %d, due to eCSR_ROAM_FT_START, session: %d"),
4053 pHddStaCtx->hdd_ReassocScenario, pAdapter->sessionId);
4054 break;
Varun Reddy Yeturuf907f912016-03-21 15:06:22 -07004055 case eCSR_ROAM_DISABLE_QUEUES:
4056 hdd_info("Disabling queues");
4057 wlan_hdd_netif_queue_control(pAdapter,
4058 WLAN_NETIF_TX_DISABLE,
4059 WLAN_CONTROL_PATH);
4060 break;
4061 case eCSR_ROAM_ENABLE_QUEUES:
4062 hdd_info("Enabling queues");
4063 wlan_hdd_netif_queue_control(pAdapter,
4064 WLAN_WAKE_ALL_NETIF_QUEUE,
4065 WLAN_CONTROL_PATH);
4066 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004067
4068 case eCSR_ROAM_SHOULD_ROAM:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004069 /* notify apps that we can't pass traffic anymore */
4070 hddLog(LOG1, FL("Disabling queues"));
4071 wlan_hdd_netif_queue_control(pAdapter,
4072 WLAN_NETIF_TX_DISABLE,
4073 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004074 if (pHddStaCtx->ft_carrier_on == false) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004075 wlan_hdd_netif_queue_control(pAdapter,
4076 WLAN_NETIF_CARRIER_OFF,
4077 WLAN_CONTROL_PATH);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004078 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004079 break;
4080 case eCSR_ROAM_LOSTLINK:
4081 if (roamResult == eCSR_ROAM_RESULT_LOSTLINK) {
4082 hddLog(LOG2, "Roaming started due to connection lost");
4083 hddLog(LOG1, FL("Disabling queues"));
4084 wlan_hdd_netif_queue_control(pAdapter,
4085 WLAN_NETIF_TX_DISABLE_N_CARRIER,
4086 WLAN_CONTROL_PATH);
4087 break;
4088 }
4089 case eCSR_ROAM_DISASSOCIATED:
4090 {
4091 hddLog(LOG1, "****eCSR_ROAM_DISASSOCIATED****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304092 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004093 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4094 roamStatus, roamResult);
4095 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
4096 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
4097 if (pHddCtx->hdd_mcastbcast_filter_set == true) {
4098 hdd_conf_mcastbcast_filter(pHddCtx, false);
4099
4100 if (true ==
4101 pHddCtx->sus_res_mcastbcast_filter_valid) {
4102 pHddCtx->configuredMcastBcastFilter =
4103 pHddCtx->sus_res_mcastbcast_filter;
4104 pHddCtx->
4105 sus_res_mcastbcast_filter_valid =
4106 false;
4107 }
4108
4109 hddLog(LOG1,
4110 "offload: disassociation happening, restoring configuredMcastBcastFilter");
4111 hddLog(LOG1,
4112 "McastBcastFilter = %d",
4113 pHddCtx->configuredMcastBcastFilter);
4114 hddLog(LOG1,
4115 "offload: already called mcastbcast filter");
4116 (WLAN_HDD_GET_CTX(pAdapter))->
4117 hdd_mcastbcast_filter_set = false;
4118 }
4119 /* Call to clear any MC Addr List filter applied after
4120 * successful connection.
4121 */
4122 wlan_hdd_set_mc_addr_list(pAdapter, false);
4123 }
4124 break;
4125 case eCSR_ROAM_IBSS_LEAVE:
4126 hddLog(LOG1, "****eCSR_ROAM_IBSS_LEAVE****");
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304127 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004128 hdd_dis_connect_handler(pAdapter, pRoamInfo, roamId,
4129 roamStatus, roamResult);
4130 break;
4131 case eCSR_ROAM_ASSOCIATION_COMPLETION:
4132 hddLog(LOG1, "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
4133 /*
4134 * To Do - address probable memory leak with WEP encryption upon
4135 * successful association.
4136 */
4137 if (eCSR_ROAM_RESULT_ASSOCIATED != roamResult) {
4138 /* Clear saved connection information in HDD */
4139 hdd_conn_remove_connect_info(
4140 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter));
4141 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304142 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004143 hdd_association_completion_handler(pAdapter, pRoamInfo,
4144 roamId, roamStatus,
4145 roamResult);
4146#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4147 if (pRoamInfo)
4148 pRoamInfo->roamSynchInProgress = false;
4149#endif
4150 break;
4151 case eCSR_ROAM_ASSOCIATION_FAILURE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304152 qdf_ret_status = hdd_association_completion_handler(pAdapter,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004153 pRoamInfo,
4154 roamId,
4155 roamStatus,
4156 roamResult);
4157 break;
4158 case eCSR_ROAM_IBSS_IND:
4159 hdd_roam_ibss_indication_handler(pAdapter, pRoamInfo, roamId,
4160 roamStatus, roamResult);
4161 break;
4162
4163 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304164 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004165 roam_roam_connect_status_update_handler(pAdapter,
4166 pRoamInfo,
4167 roamId,
4168 roamStatus,
4169 roamResult);
4170 break;
4171
4172 case eCSR_ROAM_MIC_ERROR_IND:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304173 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004174 hdd_roam_mic_error_indication_handler(pAdapter,
4175 pRoamInfo,
4176 roamId,
4177 roamStatus,
4178 roamResult);
4179 break;
4180
4181 case eCSR_ROAM_SET_KEY_COMPLETE:
4182 {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304183 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004184 hdd_roam_set_key_complete_handler(pAdapter, pRoamInfo,
4185 roamId, roamStatus,
4186 roamResult);
4187 if (eCSR_ROAM_RESULT_AUTHENTICATED == roamResult) {
4188 pHddStaCtx->hdd_ReassocScenario = false;
4189 hddLog(LOG1,
4190 FL("hdd_ReassocScenario set to: %d, set key complete, session: %d"),
4191 pHddStaCtx->hdd_ReassocScenario,
4192 pAdapter->sessionId);
4193 }
4194 }
4195#ifdef WLAN_FEATURE_ROAM_OFFLOAD
4196 if (pRoamInfo != NULL)
4197 pRoamInfo->roamSynchInProgress = false;
4198#endif
4199 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004200
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004201 case eCSR_ROAM_FT_RESPONSE:
4202 hdd_send_ft_event(pAdapter);
4203 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004204
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004205 case eCSR_ROAM_PMK_NOTIFY:
Komal Seelam98760ba2015-12-15 11:05:18 +05304206 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType
4207 || hdd_is_8021x_sha256_auth_type(pHddStaCtx)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004208 /* notify the supplicant of a new candidate */
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304209 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004210 wlan_hdd_cfg80211_pmksa_candidate_notify(
4211 pAdapter, pRoamInfo, 1, false);
4212 }
4213 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004214
4215#ifdef FEATURE_WLAN_LFR_METRICS
4216 case eCSR_ROAM_PREAUTH_INIT_NOTIFY:
4217 /* This event is to notify pre-auth initiation */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304218 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004219 wlan_hdd_cfg80211_roam_metrics_preauth(pAdapter,
4220 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304221 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004222 }
4223 break;
4224 case eCSR_ROAM_PREAUTH_STATUS_SUCCESS:
4225 /*
4226 * This event will notify pre-auth completion in case of success
4227 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304228 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004229 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4230 pRoamInfo, 1)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304231 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004232 }
4233 break;
4234 case eCSR_ROAM_PREAUTH_STATUS_FAILURE:
4235 /*
4236 * This event will notify pre-auth completion incase of failure.
4237 */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304238 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004239 wlan_hdd_cfg80211_roam_metrics_preauth_status(pAdapter,
4240 pRoamInfo, 0)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304241 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004242 }
4243 break;
4244 case eCSR_ROAM_HANDOVER_SUCCESS:
4245 /* This event is to notify handover success.
4246 It will be only invoked on success */
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304247 if (QDF_STATUS_SUCCESS !=
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004248 wlan_hdd_cfg80211_roam_metrics_handover(pAdapter,
4249 pRoamInfo)) {
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304250 qdf_ret_status = QDF_STATUS_E_FAILURE;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004251 }
4252 break;
4253#endif
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004254 case eCSR_ROAM_REMAIN_CHAN_READY:
4255 hdd_remain_chan_ready_handler(pAdapter, pRoamInfo->roc_scan_id);
4256 break;
4257 case eCSR_ROAM_SEND_ACTION_CNF:
4258 hdd_send_action_cnf(pAdapter,
4259 (roamResult ==
4260 eCSR_ROAM_RESULT_NONE) ? true : false);
4261 break;
4262#ifdef FEATURE_WLAN_TDLS
4263 case eCSR_ROAM_TDLS_STATUS_UPDATE:
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304264 qdf_ret_status =
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004265 hdd_roam_tdls_status_update_handler(pAdapter, pRoamInfo,
4266 roamId,
4267 roamStatus,
4268 roamResult);
4269 break;
4270 case eCSR_ROAM_RESULT_MGMT_TX_COMPLETE_IND:
4271 wlan_hdd_tdls_mgmt_completion_callback(pAdapter,
4272 pRoamInfo->reasonCode);
4273 break;
4274#endif
4275#ifdef WLAN_FEATURE_11W
4276 case eCSR_ROAM_UNPROT_MGMT_FRAME_IND:
4277 hdd_indicate_unprot_mgmt_frame(pAdapter,
4278 pRoamInfo->nFrameLength,
4279 pRoamInfo->pbFrames,
4280 pRoamInfo->frameType);
4281 break;
4282#endif
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004283#ifdef FEATURE_WLAN_ESE
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004284 case eCSR_ROAM_TSM_IE_IND:
4285 hdd_indicate_tsm_ie(pAdapter, pRoamInfo->tsmIe.tsid,
4286 pRoamInfo->tsmIe.state,
4287 pRoamInfo->tsmIe.msmt_interval);
4288 break;
4289
4290 case eCSR_ROAM_CCKM_PREAUTH_NOTIFY:
4291 {
4292 if (eCSR_AUTH_TYPE_CCKM_WPA ==
4293 pHddStaCtx->conn_info.authType
4294 || eCSR_AUTH_TYPE_CCKM_RSN ==
4295 pHddStaCtx->conn_info.authType) {
4296 hdd_indicate_cckm_pre_auth(pAdapter, pRoamInfo);
4297 }
4298 break;
4299 }
4300
4301 case eCSR_ROAM_ESE_ADJ_AP_REPORT_IND:
4302 {
4303 hdd_indicate_ese_adj_ap_rep_ind(pAdapter, pRoamInfo);
4304 break;
4305 }
4306
4307 case eCSR_ROAM_ESE_BCN_REPORT_IND:
4308 {
4309 hdd_indicate_ese_bcn_report_ind(pAdapter, pRoamInfo);
4310 break;
4311 }
Srinivas Girigowda515a9ef2015-12-11 11:00:48 -08004312#endif /* FEATURE_WLAN_ESE */
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304313 case eCSR_ROAM_STA_CHANNEL_SWITCH:
4314 hdd_info("channel switch for session:%d to channel:%d",
4315 pAdapter->sessionId, pRoamInfo->chan_info.chan_id);
4316
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304317 chan_change.chan = pRoamInfo->chan_info.chan_id;
4318 chan_change.chan_params.ch_width =
4319 pRoamInfo->chan_info.ch_width;
4320 chan_change.chan_params.sec_ch_offset =
4321 pRoamInfo->chan_info.sec_ch_offset;
4322 chan_change.chan_params.center_freq_seg0 =
4323 pRoamInfo->chan_info.band_center_freq1;
4324 chan_change.chan_params.center_freq_seg1 =
4325 pRoamInfo->chan_info.band_center_freq2;
4326
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304327 status = hdd_chan_change_notify(pAdapter, pAdapter->dev,
Manishekar Chandrasekaranec267592016-05-26 19:10:04 +05304328 chan_change);
Manishekar Chandrasekarancb052172016-04-22 12:19:04 +05304329 if (QDF_IS_STATUS_ERROR(status))
4330 hdd_err("channel change notification failed");
4331
4332 status = cds_set_hw_mode_on_channel_switch(pAdapter->sessionId);
4333 if (QDF_IS_STATUS_ERROR(status))
4334 hdd_info("set hw mode change not done");
4335 break;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004336 default:
4337 break;
4338 }
Anurag Chouhanf04e84f2016-03-03 10:12:12 +05304339 return qdf_ret_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004340}
4341
4342/**
4343 * hdd_translate_rsn_to_csr_auth_type() - Translate RSN to CSR auth type
4344 * @auth_suite: auth suite
4345 *
4346 * Return: eCsrAuthType enumeration
4347 */
4348eCsrAuthType hdd_translate_rsn_to_csr_auth_type(uint8_t auth_suite[4])
4349{
4350 eCsrAuthType auth_type;
4351 /* is the auth type supported? */
4352 if (memcmp(auth_suite, ccp_rsn_oui01, 4) == 0) {
4353 auth_type = eCSR_AUTH_TYPE_RSN;
4354 } else if (memcmp(auth_suite, ccp_rsn_oui02, 4) == 0) {
4355 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08004356 } else if (memcmp(auth_suite, ccp_rsn_oui04, 4) == 0) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004357 /* Check for 11r FT Authentication with PSK */
4358 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
4359 } else if (memcmp(auth_suite, ccp_rsn_oui03, 4) == 0) {
4360 /* Check for 11R FT Authentication with 802.1X */
4361 auth_type = eCSR_AUTH_TYPE_FT_RSN;
4362 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004363#ifdef FEATURE_WLAN_ESE
4364 if (memcmp(auth_suite, ccp_rsn_oui06, 4) == 0) {
4365 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
4366 } else
4367#endif /* FEATURE_WLAN_ESE */
4368#ifdef WLAN_FEATURE_11W
4369 if (memcmp(auth_suite, ccp_rsn_oui07, 4) == 0) {
4370 auth_type = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4371 } else if (memcmp(auth_suite, ccp_rsn_oui08, 4) == 0) {
4372 auth_type = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4373 } else
4374#endif
4375 {
4376 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4377 }
4378 return auth_type;
4379}
4380
4381/**
4382 * hdd_translate_wpa_to_csr_auth_type() - Translate WPA to CSR auth type
4383 * @auth_suite: auth suite
4384 *
4385 * Return: eCsrAuthType enumeration
4386 */
4387eCsrAuthType hdd_translate_wpa_to_csr_auth_type(uint8_t auth_suite[4])
4388{
4389 eCsrAuthType auth_type;
4390 /* is the auth type supported? */
4391 if (memcmp(auth_suite, ccp_wpa_oui01, 4) == 0) {
4392 auth_type = eCSR_AUTH_TYPE_WPA;
4393 } else if (memcmp(auth_suite, ccp_wpa_oui02, 4) == 0) {
4394 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
4395 } else
4396#ifdef FEATURE_WLAN_ESE
4397 if (memcmp(auth_suite, ccp_wpa_oui06, 4) == 0) {
4398 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
4399 } else
4400#endif /* FEATURE_WLAN_ESE */
4401 {
4402 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4403 }
4404 hddLog(LOG1, FL("auth_type: %d"), auth_type);
4405 return auth_type;
4406}
4407
4408/**
4409 * hdd_translate_rsn_to_csr_encryption_type() -
4410 * Translate RSN to CSR encryption type
4411 * @cipher_suite: cipher suite
4412 *
4413 * Return: eCsrEncryptionType enumeration
4414 */
4415eCsrEncryptionType
4416hdd_translate_rsn_to_csr_encryption_type(uint8_t cipher_suite[4])
4417{
4418 eCsrEncryptionType cipher_type;
4419
4420 if (memcmp(cipher_suite, ccp_rsn_oui04, 4) == 0)
4421 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4422 else if (memcmp(cipher_suite, ccp_rsn_oui02, 4) == 0)
4423 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4424 else if (memcmp(cipher_suite, ccp_rsn_oui00, 4) == 0)
4425 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4426 else if (memcmp(cipher_suite, ccp_rsn_oui01, 4) == 0)
4427 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4428 else if (memcmp(cipher_suite, ccp_rsn_oui05, 4) == 0)
4429 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4430 else
4431 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4432
4433 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4434 return cipher_type;
4435}
4436
4437/**
4438 * hdd_translate_wpa_to_csr_encryption_type() -
4439 * Translate WPA to CSR encryption type
4440 * @cipher_suite: cipher suite
4441 *
4442 * Return: eCsrEncryptionType enumeration
4443 */
4444eCsrEncryptionType
4445hdd_translate_wpa_to_csr_encryption_type(uint8_t cipher_suite[4])
4446{
4447 eCsrEncryptionType cipher_type;
4448
4449 if (memcmp(cipher_suite, ccp_wpa_oui04, 4) == 0)
4450 cipher_type = eCSR_ENCRYPT_TYPE_AES;
4451 else if (memcmp(cipher_suite, ccp_wpa_oui02, 4) == 0)
4452 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
4453 else if (memcmp(cipher_suite, ccp_wpa_oui00, 4) == 0)
4454 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
4455 else if (memcmp(cipher_suite, ccp_wpa_oui01, 4) == 0)
4456 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4457 else if (memcmp(cipher_suite, ccp_wpa_oui05, 4) == 0)
4458 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4459 else
4460 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
4461
4462 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
4463 return cipher_type;
4464}
4465
4466/**
4467 * hdd_process_genie() - process gen ie
4468 * @pAdapter: pointer to adapter
4469 * @bssid: pointer to mac address
4470 * @pEncryptType: pointer to encryption type
4471 * @mcEncryptType: pointer to multicast encryption type
4472 * @pAuthType: pointer to auth type
4473 *
4474 * Return: 0 on success, error number otherwise
4475 */
4476static int32_t hdd_process_genie(hdd_adapter_t *pAdapter,
4477 u8 *bssid,
4478 eCsrEncryptionType *pEncryptType,
4479 eCsrEncryptionType *mcEncryptType,
4480 eCsrAuthType *pAuthType,
4481#ifdef WLAN_FEATURE_11W
4482 uint8_t *pMfpRequired, uint8_t *pMfpCapable,
4483#endif
4484 uint16_t gen_ie_len, uint8_t *gen_ie)
4485{
4486 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304487 QDF_STATUS result;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004488 tDot11fIERSN dot11RSNIE;
4489 tDot11fIEWPA dot11WPAIE;
4490 uint32_t i;
4491 uint8_t *pRsnIe;
4492 uint16_t RSNIeLen;
4493 tPmkidCacheInfo PMKIDCache[4]; /* Local transfer memory */
4494 bool updatePMKCache = false;
4495
4496 /*
4497 * Clear struct of tDot11fIERSN and tDot11fIEWPA specifically
4498 * setting present flag to 0.
4499 */
4500 memset(&dot11WPAIE, 0, sizeof(tDot11fIEWPA));
4501 memset(&dot11RSNIE, 0, sizeof(tDot11fIERSN));
4502
4503 /* Type check */
4504 if (gen_ie[0] == DOT11F_EID_RSN) {
4505 /* Validity checks */
4506 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN) ||
4507 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN)) {
4508 hddLog(LOGE, FL("Invalid DOT11F RSN IE length :%d"),
4509 gen_ie_len);
4510 return -EINVAL;
4511 }
4512 /* Skip past the EID byte and length byte */
4513 pRsnIe = gen_ie + 2;
4514 RSNIeLen = gen_ie_len - 2;
4515 /* Unpack the RSN IE */
4516 dot11f_unpack_ie_rsn((tpAniSirGlobal) halHandle,
4517 pRsnIe, RSNIeLen, &dot11RSNIE);
4518 /* Copy out the encryption and authentication types */
4519 hddLog(LOG1, FL("pairwise cipher suite count: %d"),
4520 dot11RSNIE.pwise_cipher_suite_count);
4521 hddLog(LOG1, FL("authentication suite count: %d"),
4522 dot11RSNIE.akm_suite_count);
4523 /*Here we have followed the apple base code,
4524 but probably I suspect we can do something different */
4525 /* dot11RSNIE.akm_suite_count */
4526 /* Just translate the FIRST one */
4527 *pAuthType =
4528 hdd_translate_rsn_to_csr_auth_type(
4529 dot11RSNIE.akm_suites[0]);
4530 /* dot11RSNIE.pwise_cipher_suite_count */
4531 *pEncryptType =
4532 hdd_translate_rsn_to_csr_encryption_type(
4533 dot11RSNIE.pwise_cipher_suites[0]);
4534 /* dot11RSNIE.gp_cipher_suite_count */
4535 *mcEncryptType =
4536 hdd_translate_rsn_to_csr_encryption_type(
4537 dot11RSNIE.gp_cipher_suite);
4538#ifdef WLAN_FEATURE_11W
4539 *pMfpRequired = (dot11RSNIE.RSN_Cap[0] >> 6) & 0x1;
4540 *pMfpCapable = (dot11RSNIE.RSN_Cap[0] >> 7) & 0x1;
4541#endif
4542 /* Set the PMKSA ID Cache for this interface */
4543 for (i = 0; i < dot11RSNIE.pmkid_count; i++) {
4544 if (is_zero_ether_addr(bssid)) {
4545 hddLog(LOGE, FL("MAC address is all zeroes"));
4546 break;
4547 }
4548 updatePMKCache = true;
4549 /*
4550 * For right now, I assume setASSOCIATE() has passed
4551 * in the bssid.
4552 */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304553 qdf_mem_copy(PMKIDCache[i].BSSID.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05304554 bssid, QDF_MAC_ADDR_SIZE);
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304555 qdf_mem_copy(PMKIDCache[i].PMKID,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004556 dot11RSNIE.pmkid[i], CSR_RSN_PMKID_SIZE);
4557 }
4558
4559 if (updatePMKCache) {
4560 /*
4561 * Calling csr_roam_set_pmkid_cache to configure the
4562 * PMKIDs into the cache.
4563 */
4564 hddLog(LOG1,
4565 FL("Calling sme_roam_set_pmkid_cache with cache entry %d."),
4566 i);
4567 /* Finally set the PMKSA ID Cache in CSR */
4568 result =
4569 sme_roam_set_pmkid_cache(halHandle,
4570 pAdapter->sessionId,
4571 PMKIDCache,
4572 dot11RSNIE.pmkid_count,
4573 false);
4574 }
4575 } else if (gen_ie[0] == DOT11F_EID_WPA) {
4576 /* Validity checks */
4577 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN) ||
4578 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN)) {
4579 hddLog(LOGE, FL("Invalid DOT11F WPA IE length :%d"),
4580 gen_ie_len);
4581 return -EINVAL;
4582 }
4583 /* Skip past the EID and length byte - and four byte WiFi OUI */
4584 pRsnIe = gen_ie + 2 + 4;
4585 RSNIeLen = gen_ie_len - (2 + 4);
4586 /* Unpack the WPA IE */
4587 dot11f_unpack_ie_wpa((tpAniSirGlobal) halHandle,
4588 pRsnIe, RSNIeLen, &dot11WPAIE);
4589 /* Copy out the encryption and authentication types */
4590 hddLog(LOG1, FL("WPA unicast cipher suite count: %d"),
4591 dot11WPAIE.unicast_cipher_count);
4592 hddLog(LOG1, FL("WPA authentication suite count: %d"),
4593 dot11WPAIE.auth_suite_count);
4594 /* dot11WPAIE.auth_suite_count */
4595 /* Just translate the FIRST one */
4596 *pAuthType =
4597 hdd_translate_wpa_to_csr_auth_type(
4598 dot11WPAIE.auth_suites[0]);
4599 /* dot11WPAIE.unicast_cipher_count */
4600 *pEncryptType =
4601 hdd_translate_wpa_to_csr_encryption_type(
4602 dot11WPAIE.unicast_ciphers[0]);
4603 /* dot11WPAIE.unicast_cipher_count */
4604 *mcEncryptType =
4605 hdd_translate_wpa_to_csr_encryption_type(
4606 dot11WPAIE.multicast_cipher);
4607 } else {
4608 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
4609 return -EINVAL;
4610 }
4611 return 0;
4612}
4613
4614/**
4615 * hdd_set_genie_to_csr() - set genie to csr
4616 * @pAdapter: pointer to adapter
4617 * @RSNAuthType: pointer to auth type
4618 *
4619 * Return: 0 on success, error number otherwise
4620 */
4621int hdd_set_genie_to_csr(hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
4622{
4623 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4624 uint32_t status = 0;
4625 eCsrEncryptionType RSNEncryptType;
4626 eCsrEncryptionType mcRSNEncryptType;
4627#ifdef WLAN_FEATURE_11W
4628 uint8_t RSNMfpRequired = 0;
4629 uint8_t RSNMfpCapable = 0;
4630#endif
4631 u8 bssid[ETH_ALEN]; /* MAC address of assoc peer */
4632 /* MAC address of assoc peer */
4633 /* But, this routine is only called when we are NOT associated. */
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304634 qdf_mem_copy(bssid,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004635 pWextState->roamProfile.BSSIDs.bssid,
4636 sizeof(bssid));
4637 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN
4638 || pWextState->WPARSNIE[0] == DOT11F_EID_WPA) {
4639 /* continue */
4640 } else {
4641 return 0;
4642 }
4643 /* The actual processing may eventually be more extensive than this. */
4644 /* Right now, just consume any PMKIDs that are sent in by the app. */
4645 status = hdd_process_genie(pAdapter, bssid,
4646 &RSNEncryptType,
4647 &mcRSNEncryptType, RSNAuthType,
4648#ifdef WLAN_FEATURE_11W
4649 &RSNMfpRequired, &RSNMfpCapable,
4650#endif
4651 pWextState->WPARSNIE[1] + 2,
4652 pWextState->WPARSNIE);
4653 if (status == 0) {
4654 /*
4655 * Now copy over all the security attributes
4656 * you have parsed out.
4657 */
4658 pWextState->roamProfile.EncryptionType.numEntries = 1;
4659 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
4660
4661 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; /* Use the cipher type in the RSN IE */
4662 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
4663 mcRSNEncryptType;
4664
Krunal Sonibe766b02016-03-10 13:00:44 -08004665 if ((QDF_IBSS_MODE == pAdapter->device_mode) &&
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004666 ((eCSR_ENCRYPT_TYPE_AES == mcRSNEncryptType) ||
4667 (eCSR_ENCRYPT_TYPE_TKIP == mcRSNEncryptType))) {
4668 /*
4669 * For wpa none supplicant sends the WPA IE with unicast
4670 * cipher as eCSR_ENCRYPT_TYPE_NONE ,where as the
4671 * multicast cipher as either AES/TKIP based on group
4672 * cipher configuration mentioned in the
4673 * wpa_supplicant.conf.
4674 */
4675
4676 /* Set the unicast cipher same as multicast cipher */
4677 pWextState->roamProfile.EncryptionType.encryptionType[0]
4678 = mcRSNEncryptType;
4679 }
4680#ifdef WLAN_FEATURE_11W
4681 hddLog(LOG1, FL("RSNMfpRequired = %d, RSNMfpCapable = %d"),
4682 RSNMfpRequired, RSNMfpCapable);
4683 pWextState->roamProfile.MFPRequired = RSNMfpRequired;
4684 pWextState->roamProfile.MFPCapable = RSNMfpCapable;
4685#endif
4686 hddLog(LOG1,
4687 FL("CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d"),
4688 *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
4689 }
4690 return 0;
4691}
4692
4693/**
4694 * hdd_set_csr_auth_type() - set csr auth type
4695 * @pAdapter: pointer to adapter
4696 * @RSNAuthType: auth type
4697 *
4698 * Return: 0 on success, error number otherwise
4699 */
4700int hdd_set_csr_auth_type(hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
4701{
4702 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4703 tCsrRoamProfile *pRoamProfile = &(pWextState->roamProfile);
4704 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004705
4706 pRoamProfile->AuthType.numEntries = 1;
4707 hddLog(LOG1, FL("pHddStaCtx->conn_info.authType = %d"),
4708 pHddStaCtx->conn_info.authType);
4709
4710 switch (pHddStaCtx->conn_info.authType) {
4711 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
4712#ifdef FEATURE_WLAN_ESE
4713 case eCSR_AUTH_TYPE_CCKM_WPA:
4714 case eCSR_AUTH_TYPE_CCKM_RSN:
4715#endif
4716 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
4717
4718 pRoamProfile->AuthType.authType[0] =
4719 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4720 } else if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
4721
4722#ifdef FEATURE_WLAN_ESE
4723 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
4724 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4725 == IW_AUTH_KEY_MGMT_802_1X)) {
4726 hddLog(LOG1,
4727 FL("set authType to CCKM WPA. AKM also 802.1X."));
4728 pRoamProfile->AuthType.authType[0] =
4729 eCSR_AUTH_TYPE_CCKM_WPA;
4730 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) {
4731 hddLog(LOG1,
4732 FL("Last chance to set authType to CCKM WPA."));
4733 pRoamProfile->AuthType.authType[0] =
4734 eCSR_AUTH_TYPE_CCKM_WPA;
4735 } else
4736#endif
4737 if ((pWextState->
4738 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4739 == IW_AUTH_KEY_MGMT_802_1X) {
4740 pRoamProfile->AuthType.authType[0] =
4741 eCSR_AUTH_TYPE_WPA;
4742 } else
4743 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4744 == IW_AUTH_KEY_MGMT_PSK) {
4745 pRoamProfile->AuthType.authType[0] =
4746 eCSR_AUTH_TYPE_WPA_PSK;
4747 } else {
4748 pRoamProfile->AuthType.authType[0] =
4749 eCSR_AUTH_TYPE_WPA_NONE;
4750 }
4751 }
4752 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
4753#ifdef FEATURE_WLAN_ESE
4754 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
4755 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4756 == IW_AUTH_KEY_MGMT_802_1X)) {
4757 hddLog(LOG1,
4758 FL("set authType to CCKM RSN. AKM also 802.1X."));
4759 pRoamProfile->AuthType.authType[0] =
4760 eCSR_AUTH_TYPE_CCKM_RSN;
4761 } else if (RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) {
4762 hddLog(LOG1,
4763 FL("Last chance to set authType to CCKM RSN."));
4764 pRoamProfile->AuthType.authType[0] =
4765 eCSR_AUTH_TYPE_CCKM_RSN;
4766 } else
4767#endif
4768
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004769 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
4770 ((pWextState->
4771 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4772 == IW_AUTH_KEY_MGMT_802_1X)) {
4773 pRoamProfile->AuthType.authType[0] =
4774 eCSR_AUTH_TYPE_FT_RSN;
4775 } else if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK)
4776 &&
4777 ((pWextState->
4778 authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4779 == IW_AUTH_KEY_MGMT_PSK)) {
4780 pRoamProfile->AuthType.authType[0] =
4781 eCSR_AUTH_TYPE_FT_RSN_PSK;
4782 } else
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004783
4784#ifdef WLAN_FEATURE_11W
4785 if (RSNAuthType == eCSR_AUTH_TYPE_RSN_PSK_SHA256) {
4786 pRoamProfile->AuthType.authType[0] =
4787 eCSR_AUTH_TYPE_RSN_PSK_SHA256;
4788 } else if (RSNAuthType ==
4789 eCSR_AUTH_TYPE_RSN_8021X_SHA256) {
4790 pRoamProfile->AuthType.authType[0] =
4791 eCSR_AUTH_TYPE_RSN_8021X_SHA256;
4792 } else
4793#endif
4794
4795 if ((pWextState->
4796 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
4797 == IW_AUTH_KEY_MGMT_802_1X) {
4798 pRoamProfile->AuthType.authType[0] =
4799 eCSR_AUTH_TYPE_RSN;
4800 } else
4801 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
4802 == IW_AUTH_KEY_MGMT_PSK) {
4803 pRoamProfile->AuthType.authType[0] =
4804 eCSR_AUTH_TYPE_RSN_PSK;
4805 } else {
4806 pRoamProfile->AuthType.authType[0] =
4807 eCSR_AUTH_TYPE_UNKNOWN;
4808 }
4809 }
4810 break;
4811
4812 case eCSR_AUTH_TYPE_SHARED_KEY:
4813
4814 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
4815 break;
4816 default:
4817
4818#ifdef FEATURE_WLAN_ESE
4819 hddLog(LOG1, FL("In default, unknown auth type."));
4820#endif /* FEATURE_WLAN_ESE */
4821 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
4822 break;
4823 }
4824
4825 hddLog(LOG1, FL("Set roam Authtype to %d"),
4826 pWextState->roamProfile.AuthType.authType[0]);
4827
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004828 return 0;
4829}
4830
4831/**
4832 * __iw_set_essid() - This function sets the ssid received from wpa_supplicant
4833 * to the CSR roam profile.
4834 *
4835 * @dev: Pointer to the net device.
4836 * @info: Pointer to the iw_request_info.
4837 * @wrqu: Pointer to the iwreq_data.
4838 * @extra: Pointer to the data.
4839 *
4840 * Return: 0 for success, error number on failure
4841 */
4842static int __iw_set_essid(struct net_device *dev,
4843 struct iw_request_info *info,
4844 union iwreq_data *wrqu, char *extra)
4845{
4846 unsigned long rc;
4847 uint32_t status = 0;
4848 hdd_wext_state_t *pWextState;
4849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4850 hdd_context_t *hdd_ctx;
4851 uint32_t roamId;
4852 tCsrRoamProfile *pRoamProfile;
4853 eMib_dot11DesiredBssType connectedBssType;
4854 eCsrAuthType RSNAuthType;
4855 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
4856 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
4857 int ret;
4858
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08004859 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004860
4861 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
4862 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05304863 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004864 return ret;
4865
Krunal Sonibe766b02016-03-10 13:00:44 -08004866 if (pAdapter->device_mode != QDF_STA_MODE &&
4867 pAdapter->device_mode != QDF_P2P_CLIENT_MODE) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004868 hddLog(LOGW, FL("device mode %s(%d) is not allowed"),
4869 hdd_device_mode_to_string(pAdapter->device_mode),
4870 pAdapter->device_mode);
4871 return -EINVAL;
4872 }
4873
4874 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
4875
4876 if (pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
4877 hddLog(LOG2, FL("Counter measure is in progress"));
4878 return -EBUSY;
4879 }
4880 if (SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length)
4881 return -EINVAL;
4882
4883 pRoamProfile = &pWextState->roamProfile;
4884 if (hdd_conn_get_connected_bss_type(pHddStaCtx, &connectedBssType) ||
4885 (eMib_dot11DesiredBssType_independent ==
4886 pHddStaCtx->conn_info.connDot11DesiredBssType)) {
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304887 QDF_STATUS qdf_status;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004888
4889 /* Need to issue a disconnect to CSR. */
4890 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304891 qdf_status = sme_roam_disconnect(hHal, pAdapter->sessionId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004892 eCSR_DISCONNECT_REASON_UNSPECIFIED);
4893
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304894 if (QDF_STATUS_SUCCESS == qdf_status) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004895 rc = wait_for_completion_timeout(&pAdapter->
4896 disconnect_comp_var,
4897 msecs_to_jiffies
4898 (WLAN_WAIT_TIME_DISCONNECT));
4899 if (!rc)
4900 hddLog(LOGE, FL("Disconnect event timed out"));
4901 }
4902 }
4903
4904 /*
4905 * when cfg80211 defined, wpa_supplicant wext driver uses
4906 * zero-length, null-string ssid for force disconnection.
4907 * after disconnection (if previously connected) and cleaning ssid,
4908 * driver MUST return success.
4909 */
4910 if (0 == wrqu->essid.length)
4911 return 0;
4912
4913 status = hdd_wmm_get_uapsd_mask(pAdapter,
4914 &pWextState->roamProfile.uapsd_mask);
Anurag Chouhanfb54ab02016-02-18 18:00:46 +05304915 if (QDF_STATUS_SUCCESS != status)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004916 pWextState->roamProfile.uapsd_mask = 0;
4917
4918 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
4919
4920 pWextState->roamProfile.SSIDs.SSIDList->SSID.length =
4921 wrqu->essid.length;
4922
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304923 qdf_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004924 sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05304925 qdf_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08004926 ssId), extra, wrqu->essid.length);
4927 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion
4928 || IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion) {
4929
4930 /* set gen ie */
4931 hdd_set_genie_to_csr(pAdapter, &RSNAuthType);
4932
4933 /* set auth */
4934 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
4935 }
4936#ifdef FEATURE_WLAN_WAPI
4937 hddLog(LOG1, FL("Setting WAPI AUTH Type and Encryption Mode values"));
4938 if (pAdapter->wapi_info.nWapiMode) {
4939 switch (pAdapter->wapi_info.wapiAuthMode) {
4940 case WAPI_AUTH_MODE_PSK:
4941 {
4942 hddLog(LOG1, FL("WAPI AUTH TYPE: PSK: %d"),
4943 pAdapter->wapi_info.wapiAuthMode);
4944 pRoamProfile->AuthType.numEntries = 1;
4945 pRoamProfile->AuthType.authType[0] =
4946 eCSR_AUTH_TYPE_WAPI_WAI_PSK;
4947 break;
4948 }
4949 case WAPI_AUTH_MODE_CERT:
4950 {
4951 hddLog(LOG1, FL("WAPI AUTH TYPE: CERT: %d"),
4952 pAdapter->wapi_info.wapiAuthMode);
4953 pRoamProfile->AuthType.numEntries = 1;
4954 pRoamProfile->AuthType.authType[0] =
4955 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
4956 break;
4957 }
4958 } /* End of switch */
4959 if (pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
4960 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT) {
4961 hddLog(LOG1, FL("WAPI PAIRWISE/GROUP ENCRYPTION: WPI"));
4962 pRoamProfile->EncryptionType.numEntries = 1;
4963 pRoamProfile->EncryptionType.encryptionType[0] =
4964 eCSR_ENCRYPT_TYPE_WPI;
4965 pRoamProfile->mcEncryptionType.numEntries = 1;
4966 pRoamProfile->mcEncryptionType.encryptionType[0] =
4967 eCSR_ENCRYPT_TYPE_WPI;
4968 }
4969 }
4970#endif /* FEATURE_WLAN_WAPI */
4971 /* if previous genIE is not NULL, update AssocIE */
4972 if (0 != pWextState->genIE.length) {
4973 memset(&pWextState->assocAddIE, 0,
4974 sizeof(pWextState->assocAddIE));
4975 memcpy(pWextState->assocAddIE.addIEdata,
4976 pWextState->genIE.addIEdata, pWextState->genIE.length);
4977 pWextState->assocAddIE.length = pWextState->genIE.length;
4978 pWextState->roamProfile.pAddIEAssoc =
4979 pWextState->assocAddIE.addIEdata;
4980 pWextState->roamProfile.nAddIEAssocLength =
4981 pWextState->assocAddIE.length;
4982
4983 /* clear previous genIE after use it */
4984 memset(&pWextState->genIE, 0, sizeof(pWextState->genIE));
4985 }
4986
4987 /*
4988 * Assumes it is not WPS Association by default, except when
4989 * pAddIEAssoc has WPS IE.
4990 */
4991 pWextState->roamProfile.bWPSAssociation = false;
4992
4993 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
4994 pWextState->roamProfile.
4995 nAddIEAssocLength))
4996 pWextState->roamProfile.bWPSAssociation = true;
4997
4998 /* Disable auto BMPS entry by PMC until DHCP is done */
4999 sme_set_dhcp_till_power_active_flag(WLAN_HDD_GET_HAL_CTX(pAdapter),
5000 true);
5001
5002 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
5003
5004 if (eCSR_BSS_TYPE_START_IBSS == pRoamProfile->BSSType) {
5005 hdd_select_cbmode(pAdapter,
5006 (WLAN_HDD_GET_CTX(pAdapter))->config->
5007 AdHocChannel5G);
5008 }
Agrawal Ashish6b015762016-05-05 11:22:18 +05305009 /*
5010 * Change conn_state to connecting before sme_roam_connect(),
5011 * because sme_roam_connect() has a direct path to call
5012 * hdd_sme_roam_callback(), which will change the conn_state
5013 * If direct path, conn_state will be accordingly changed to
5014 * NotConnected or Associated by either
5015 * hdd_association_completion_handler() or hdd_dis_connect_handler()
5016 * in sme_RoamCallback()if sme_RomConnect is to be queued,
5017 * Connecting state will remain until it is completed.
5018 *
5019 * If connection state is not changed,
5020 * connection state will remain in eConnectionState_NotConnected state.
5021 * In hdd_association_completion_handler, "hddDisconInProgress" is
5022 * set to true if conn state is eConnectionState_NotConnected.
5023 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
5024 * informed of connect result indication which is an issue.
5025 */
5026 if (QDF_STA_MODE == pAdapter->device_mode ||
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305027 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)
Agrawal Ashish6b015762016-05-05 11:22:18 +05305028 hdd_conn_set_connection_state(pAdapter,
5029 eConnectionState_Connecting);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305030
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005031 status = sme_roam_connect(hHal, pAdapter->sessionId,
5032 &(pWextState->roamProfile), &roamId);
Agrawal Ashish6b015762016-05-05 11:22:18 +05305033 if ((QDF_STATUS_SUCCESS != status) &&
5034 (QDF_STA_MODE == pAdapter->device_mode ||
5035 QDF_P2P_CLIENT_MODE == pAdapter->device_mode)) {
5036 hdd_err("sme_roam_connect (session %d) failed with status %d. -> NotConnected",
5037 pAdapter->sessionId, status);
5038 /* change back to NotAssociated */
5039 hdd_conn_set_connection_state(pAdapter,
5040 eConnectionState_NotConnected);
5041 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005042 pRoamProfile->ChannelInfo.ChannelList = NULL;
5043 pRoamProfile->ChannelInfo.numOfChannels = 0;
5044
5045 EXIT();
5046 return status;
5047}
5048
5049/**
5050 * iw_set_essid() - set essid handler function
5051 * @dev: Pointer to the net device.
5052 * @info: Pointer to the iw_request_info.
5053 * @wrqu: Pointer to the iwreq_data.
5054 * @extra: Pointer to the data.
5055 *
5056 * Return: 0 for success, error number on failure
5057 */
5058int iw_set_essid(struct net_device *dev,
5059 struct iw_request_info *info,
5060 union iwreq_data *wrqu, char *extra)
5061{
5062 int ret;
5063
5064 cds_ssr_protect(__func__);
5065 ret = __iw_set_essid(dev, info, wrqu, extra);
5066 cds_ssr_unprotect(__func__);
5067
5068 return ret;
5069}
5070
5071/**
5072 * __iw_get_essid() - This function returns the essid to the wpa_supplicant
5073 * @dev: pointer to the net device
5074 * @info: pointer to the iw request info
5075 * @dwrq: pointer to iw_point
5076 * @extra: pointer to the data
5077 *
5078 * Return: 0 on success, error number otherwise
5079 */
5080static int __iw_get_essid(struct net_device *dev,
5081 struct iw_request_info *info,
5082 struct iw_point *dwrq, char *extra)
5083{
5084 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5085 hdd_context_t *hdd_ctx;
5086 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5087 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5088 int ret;
5089
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005090 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005091
5092 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5093 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305094 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005095 return ret;
5096
5097 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
5098 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
5099 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected
5100 || pHddStaCtx->conn_info.connState ==
5101 eConnectionState_IbssDisconnected)
5102 && wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0)) {
5103 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
5104 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId,
5105 dwrq->length);
5106 dwrq->flags = 1;
5107 } else {
5108 memset(extra, 0, dwrq->length);
5109 dwrq->length = 0;
5110 dwrq->flags = 0;
5111 }
5112 EXIT();
5113 return 0;
5114}
5115
5116/**
5117 * iw_get_essid() - get essid handler function
5118 * @dev: Pointer to the net device.
5119 * @info: Pointer to the iw_request_info.
5120 * @wrqu: Pointer to the iwreq_data.
5121 * @extra: Pointer to the data.
5122 *
5123 * Return: 0 for success, error number on failure
5124 */
5125int iw_get_essid(struct net_device *dev,
5126 struct iw_request_info *info,
5127 struct iw_point *wrqu, char *extra)
5128{
5129 int ret;
5130
5131 cds_ssr_protect(__func__);
5132 ret = __iw_get_essid(dev, info, wrqu, extra);
5133 cds_ssr_unprotect(__func__);
5134
5135 return ret;
5136}
5137
5138/**
5139 * __iw_set_auth() -
5140 * This function sets the auth type received from the wpa_supplicant
5141 * @dev: pointer to the net device
5142 * @info: pointer to the iw request info
5143 * @wrqu: pointer to iwreq_data
5144 * @extra: pointer to the data
5145 *
5146 * Return: 0 on success, error number otherwise
5147 */
5148static int __iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5149 union iwreq_data *wrqu, char *extra)
5150{
5151 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5152 hdd_context_t *hdd_ctx;
5153 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5154 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
5155 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5156 eCsrEncryptionType mcEncryptionType;
5157 eCsrEncryptionType ucEncryptionType;
5158 int ret;
5159
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005160 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005161
5162 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5163 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305164 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005165 return ret;
5166
5167 switch (wrqu->param.flags & IW_AUTH_INDEX) {
5168 case IW_AUTH_WPA_VERSION:
5169 pWextState->wpaVersion = wrqu->param.value;
5170 break;
5171
5172 case IW_AUTH_CIPHER_PAIRWISE:
5173 {
5174 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5175 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5176 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5177 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5178 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5179 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5180 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5181 if ((IW_AUTH_KEY_MGMT_802_1X
5182 ==
5183 (pWextState->
5184 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5185 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5186 pHddStaCtx->conn_info.authType))
5187 /*Dynamic WEP key */
5188 ucEncryptionType =
5189 eCSR_ENCRYPT_TYPE_WEP40;
5190 else
5191 /*Static WEP key */
5192 ucEncryptionType =
5193 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5194 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5195 if ((IW_AUTH_KEY_MGMT_802_1X
5196 ==
5197 (pWextState->
5198 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5199 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5200 pHddStaCtx->conn_info.authType))
5201 /*Dynamic WEP key */
5202 ucEncryptionType =
5203 eCSR_ENCRYPT_TYPE_WEP104;
5204 else
5205 /*Static WEP key */
5206 ucEncryptionType =
5207 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5208 } else {
5209 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5210 wrqu->param.value);
5211 return -EINVAL;
5212 }
5213
5214 pRoamProfile->EncryptionType.numEntries = 1;
5215 pRoamProfile->EncryptionType.encryptionType[0] =
5216 ucEncryptionType;
5217 }
5218 break;
5219 case IW_AUTH_CIPHER_GROUP:
5220 {
5221 if (wrqu->param.value & IW_AUTH_CIPHER_NONE) {
5222 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
5223 } else if (wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
5224 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
5225 } else if (wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
5226 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
5227 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
5228 if ((IW_AUTH_KEY_MGMT_802_1X
5229 ==
5230 (pWextState->
5231 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5232 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5233 pHddStaCtx->conn_info.authType))
5234 mcEncryptionType =
5235 eCSR_ENCRYPT_TYPE_WEP40;
5236 else
5237 mcEncryptionType =
5238 eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
5239 } else if (wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
5240 /* Dynamic WEP keys won't work with shared keys */
5241 if ((IW_AUTH_KEY_MGMT_802_1X
5242 ==
5243 (pWextState->
5244 authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
5245 && (eCSR_AUTH_TYPE_OPEN_SYSTEM ==
5246 pHddStaCtx->conn_info.authType)) {
5247 mcEncryptionType =
5248 eCSR_ENCRYPT_TYPE_WEP104;
5249 } else {
5250 mcEncryptionType =
5251 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
5252 }
5253 } else {
5254 hddLog(LOGW, FL("value %d UNKNOWN IW_AUTH_CIPHER"),
5255 wrqu->param.value);
5256 return -EINVAL;
5257 }
5258
5259 pRoamProfile->mcEncryptionType.numEntries = 1;
5260 pRoamProfile->mcEncryptionType.encryptionType[0] =
5261 mcEncryptionType;
5262 }
5263 break;
5264
5265 case IW_AUTH_80211_AUTH_ALG:
5266 {
5267 /* Save the auth algo here and set auth type to SME Roam profile
5268 in the iw_set_ap_address */
5269 if (wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
5270 pHddStaCtx->conn_info.authType =
5271 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5272
5273 else if (wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
5274 pHddStaCtx->conn_info.authType =
5275 eCSR_AUTH_TYPE_SHARED_KEY;
5276
5277 else if (wrqu->param.value & IW_AUTH_ALG_LEAP)
5278 /*Not supported */
5279 pHddStaCtx->conn_info.authType =
5280 eCSR_AUTH_TYPE_OPEN_SYSTEM;
5281 pWextState->roamProfile.AuthType.authType[0] =
5282 pHddStaCtx->conn_info.authType;
5283 }
5284 break;
5285
5286 case IW_AUTH_KEY_MGMT:
5287 {
5288#ifdef FEATURE_WLAN_ESE
5289#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
5290 /*Check for CCKM AKM type */
5291 if (wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
5292 hddLog(LOG1, FL("CCKM AKM Set %d"), wrqu->param.value);
5293 /* Set the CCKM bit in authKeyMgmt */
5294 /*
5295 * Right now, this breaks all ref to authKeyMgmt because
5296 * our code doesn't realize it is a "bitfield"
5297 */
5298 pWextState->authKeyMgmt |=
5299 IW_AUTH_KEY_MGMT_CCKM;
5300 /* Set the key management to 802.1X */
5301 /* pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X; */
5302 pWextState->isESEConnection = true;
5303 /*
5304 * This is test code. I need to actually KNOW whether
5305 * this is an RSN Assoc or WPA.
5306 */
5307 pWextState->collectedAuthType =
5308 eCSR_AUTH_TYPE_CCKM_RSN;
5309 } else if (wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
5310 /* Save the key management */
5311 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
5312 pWextState->collectedAuthType =
5313 eCSR_AUTH_TYPE_RSN;
5314 } else
5315 if (!(wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
5316 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE;
5317 /* Save the key management anyway */
5318 pWextState->authKeyMgmt = wrqu->param.value;
5319 } else { /* It must be IW_AUTH_KEY_MGMT_802_1X */
5320 /* Save the key management */
5321 pWextState->authKeyMgmt |=
5322 IW_AUTH_KEY_MGMT_802_1X;
5323 pWextState->collectedAuthType =
5324 eCSR_AUTH_TYPE_RSN;
5325 }
5326#else
5327 /* Save the key management */
5328 pWextState->authKeyMgmt = wrqu->param.value;
5329#endif /* FEATURE_WLAN_ESE */
5330 }
5331 break;
5332
5333 case IW_AUTH_TKIP_COUNTERMEASURES:
5334 {
5335 if (wrqu->param.value) {
5336 hddLog(LOG2,
5337 "Counter Measure started %d",
5338 wrqu->param.value);
5339 pWextState->mTKIPCounterMeasures =
5340 TKIP_COUNTER_MEASURE_STARTED;
5341 } else {
5342 hddLog(LOG2,
5343 "Counter Measure stopped=%d",
5344 wrqu->param.value);
5345 pWextState->mTKIPCounterMeasures =
5346 TKIP_COUNTER_MEASURE_STOPED;
5347 }
5348 }
5349 break;
5350 case IW_AUTH_DROP_UNENCRYPTED:
5351 case IW_AUTH_WPA_ENABLED:
5352 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
5353 case IW_AUTH_ROAMING_CONTROL:
5354 case IW_AUTH_PRIVACY_INVOKED:
5355
5356 default:
5357
5358 hddLog(LOGW, FL("called with unsupported auth type %d"),
5359 wrqu->param.flags & IW_AUTH_INDEX);
5360 break;
5361 }
5362
5363 EXIT();
5364 return 0;
5365}
5366
5367/**
5368 * iw_set_auth() - set auth callback function
5369 * @dev: Pointer to the net device.
5370 * @info: Pointer to the iw_request_info.
5371 * @wrqu: Pointer to the iwreq_data.
5372 * @extra: Pointer to the data.
5373 *
5374 * Return: 0 for success, error number on failure.
5375 */
5376int iw_set_auth(struct net_device *dev, struct iw_request_info *info,
5377 union iwreq_data *wrqu, char *extra)
5378{
5379 int ret;
5380
5381 cds_ssr_protect(__func__);
5382 ret = __iw_set_auth(dev, info, wrqu, extra);
5383 cds_ssr_unprotect(__func__);
5384
5385 return ret;
5386}
5387
5388/**
5389 * __iw_get_auth() -
5390 * This function returns the auth type to the wpa_supplicant
5391 * @dev: pointer to the net device
5392 * @info: pointer to the iw request info
5393 * @wrqu: pointer to iwreq_data
5394 * @extra: pointer to the data
5395 *
5396 * Return: 0 on success, error number otherwise
5397 */
5398static int __iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5399 union iwreq_data *wrqu, char *extra)
5400{
5401 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5402 hdd_context_t *hdd_ctx;
5403 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
5404 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
5405 int ret;
5406
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005407 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005408
5409 hdd_ctx = WLAN_HDD_GET_CTX(pAdapter);
5410 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305411 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005412 return ret;
5413
5414 switch (pRoamProfile->negotiatedAuthType) {
5415 case eCSR_AUTH_TYPE_WPA_NONE:
5416 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5417 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
5418 break;
5419 case eCSR_AUTH_TYPE_WPA:
5420 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5421 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
5422 break;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005423
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005424 case eCSR_AUTH_TYPE_FT_RSN:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005425 case eCSR_AUTH_TYPE_RSN:
5426 wrqu->param.flags = IW_AUTH_WPA_VERSION;
5427 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
5428 break;
5429 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
5430 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5431 break;
5432 case eCSR_AUTH_TYPE_SHARED_KEY:
5433 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
5434 break;
5435 case eCSR_AUTH_TYPE_UNKNOWN:
5436 hddLog(LOG1, FL("called with unknown auth type"));
5437 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5438 break;
5439 case eCSR_AUTH_TYPE_AUTOSWITCH:
5440 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5441 break;
5442 case eCSR_AUTH_TYPE_WPA_PSK:
5443 hddLog(LOG1, FL("called with WPA PSK auth type"));
5444 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5445 return -EIO;
Deepak Dhamdhere9f09e752016-01-09 23:17:25 -08005446
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005447 case eCSR_AUTH_TYPE_FT_RSN_PSK:
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005448 case eCSR_AUTH_TYPE_RSN_PSK:
5449#ifdef WLAN_FEATURE_11W
5450 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
5451 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
5452#endif
5453 hddLog(LOG1, FL("called with RSN PSK auth type"));
5454 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5455 return -EIO;
5456 default:
5457 hddLog(LOGE, FL("called with unknown auth type"));
5458 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
5459 return -EIO;
5460 }
5461 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE)) {
5462 switch (pRoamProfile->negotiatedUCEncryptionType) {
5463 case eCSR_ENCRYPT_TYPE_NONE:
5464 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5465 break;
5466 case eCSR_ENCRYPT_TYPE_WEP40:
5467 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5468 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5469 break;
5470 case eCSR_ENCRYPT_TYPE_TKIP:
5471 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5472 break;
5473 case eCSR_ENCRYPT_TYPE_WEP104:
5474 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5475 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5476 break;
5477 case eCSR_ENCRYPT_TYPE_AES:
5478 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5479 break;
5480 default:
5481 hddLog(LOG1, FL("called with unknown auth type %d"),
5482 pRoamProfile->negotiatedUCEncryptionType);
5483 return -EIO;
5484 }
5485 }
5486
5487 if (((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP)) {
5488 switch (pRoamProfile->negotiatedMCEncryptionType) {
5489 case eCSR_ENCRYPT_TYPE_NONE:
5490 wrqu->param.value = IW_AUTH_CIPHER_NONE;
5491 break;
5492 case eCSR_ENCRYPT_TYPE_WEP40:
5493 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
5494 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
5495 break;
5496 case eCSR_ENCRYPT_TYPE_TKIP:
5497 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
5498 break;
5499 case eCSR_ENCRYPT_TYPE_WEP104:
5500 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
5501 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
5502 break;
5503 case eCSR_ENCRYPT_TYPE_AES:
5504 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
5505 break;
5506 default:
5507 hddLog(LOG1, FL("called with unknown auth type %d"),
5508 pRoamProfile->negotiatedMCEncryptionType);
5509 return -EIO;
5510 }
5511 }
5512
5513 hddLog(LOG1, FL("called with auth type %d"),
5514 pRoamProfile->AuthType.authType[0]);
5515 EXIT();
5516 return 0;
5517}
5518
5519/**
5520 * iw_get_auth() - get auth callback function
5521 * @dev: Pointer to the net device.
5522 * @info: Pointer to the iw_request_info.
5523 * @wrqu: Pointer to the iwreq_data.
5524 * @extra: Pointer to the data.
5525 *
5526 * Return: 0 for success, error number on failure.
5527 */
5528int iw_get_auth(struct net_device *dev, struct iw_request_info *info,
5529 union iwreq_data *wrqu, char *extra)
5530{
5531 int ret;
5532
5533 cds_ssr_protect(__func__);
5534 ret = __iw_get_auth(dev, info, wrqu, extra);
5535 cds_ssr_unprotect(__func__);
5536
5537 return ret;
5538}
5539
5540/**
5541 * __iw_set_ap_address() - set ap address
5542 * @dev: pointer to the net device
5543 * @info: pointer to the iw request info
5544 * @wrqu: pointer to iwreq_data
5545 * @extra: pointer to the data
5546 *
5547 * This function updates the HDD global station context connection info
5548 * BSSID with the MAC address received from the wpa_supplicant.
5549 *
5550 * Return: 0 on success, error number otherwise
5551 */
5552static int __iw_set_ap_address(struct net_device *dev,
5553 struct iw_request_info *info,
5554 union iwreq_data *wrqu, char *extra)
5555{
5556
5557 hdd_adapter_t *adapter;
5558 hdd_context_t *hdd_ctx;
5559 hdd_station_ctx_t *pHddStaCtx =
5560 WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
5561 uint8_t *pMacAddress = NULL;
5562 int ret;
5563
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005564 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005565
5566 adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5567
5568 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5569 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305570 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005571 return ret;
5572
5573 pMacAddress = (uint8_t *) wrqu->ap_addr.sa_data;
5574 hddLog(LOG1, FL(" " MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pMacAddress));
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305575 qdf_mem_copy(pHddStaCtx->conn_info.bssId.bytes, pMacAddress,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305576 sizeof(struct qdf_mac_addr));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005577 EXIT();
5578
5579 return 0;
5580}
5581
5582/**
5583 * iw_set_ap_address() - set ap addresses callback function
5584 * @dev: Pointer to the net device.
5585 * @info: Pointer to the iw_request_info.
5586 * @wrqu: Pointer to the iwreq_data.
5587 * @extra: Pointer to the data.
5588 *
5589 * Return: 0 for success, error number on failure.
5590 */
5591int iw_set_ap_address(struct net_device *dev, struct iw_request_info *info,
5592 union iwreq_data *wrqu, char *extra)
5593{
5594 int ret;
5595
5596 cds_ssr_protect(__func__);
5597 ret = __iw_set_ap_address(dev, info, wrqu, extra);
5598 cds_ssr_unprotect(__func__);
5599
5600 return ret;
5601}
5602
5603/**
5604 * __iw_get_ap_address() - get ap address
5605 * @dev: pointer to the net device
5606 * @info: pointer to the iw request info
5607 * @wrqu: pointer to iwreq_data
5608 * @extra: pointer to the data
5609 *
5610 * This function returns currently associated BSSID.
5611 *
5612 * Return: 0 on success, error number otherwise
5613 */
5614static int __iw_get_ap_address(struct net_device *dev,
5615 struct iw_request_info *info,
5616 union iwreq_data *wrqu, char *extra)
5617{
5618 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
5619 hdd_context_t *hdd_ctx;
5620 hdd_station_ctx_t *pHddStaCtx =
5621 WLAN_HDD_GET_STATION_CTX_PTR(adapter);
5622 int ret;
5623
Jeff Johnsonb25dcb12016-02-11 17:46:42 -08005624 ENTER_DEV(dev);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005625
5626 hdd_ctx = WLAN_HDD_GET_CTX(adapter);
5627 ret = wlan_hdd_validate_context(hdd_ctx);
Abhishek Singh23edd1c2016-05-05 11:56:06 +05305628 if (ret)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005629 return ret;
5630
5631 if (pHddStaCtx->conn_info.connState == eConnectionState_Associated ||
5632 eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) {
Anurag Chouhan600c3a02016-03-01 10:33:54 +05305633 qdf_mem_copy(wrqu->ap_addr.sa_data,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005634 pHddStaCtx->conn_info.bssId.bytes,
Anurag Chouhan6d760662016-02-20 16:05:43 +05305635 QDF_MAC_ADDR_SIZE);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08005636 } else {
5637 memset(wrqu->ap_addr.sa_data, 0, sizeof(wrqu->ap_addr.sa_data));
5638 }
5639 EXIT();
5640 return 0;
5641}
5642
5643/**
5644 * iw_get_ap_address() - get ap addresses callback function
5645 * @dev: Pointer to the net device.
5646 * @info: Pointer to the iw_request_info.
5647 * @wrqu: Pointer to the iwreq_data.
5648 * @extra: Pointer to the data.
5649 *
5650 * Return: 0 for success, error number on failure.
5651 */
5652int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
5653 union iwreq_data *wrqu, char *extra)
5654{
5655 int ret;
5656
5657 cds_ssr_protect(__func__);
5658 ret = __iw_get_ap_address(dev, info, wrqu, extra);
5659 cds_ssr_unprotect(__func__);
5660
5661 return ret;
5662}