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