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