blob: 6359ba742c1163aa2098b68694006a289e34dcd3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
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
24 \file wlan_hdd_assoc.c
25 \brief WLAN Host Device Driver implementation
26
27 Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
28
29 Qualcomm Confidential and Proprietary.
30
31 ========================================================================*/
32/**=========================================================================
33 EDIT HISTORY FOR FILE
34
35
36 This section contains comments describing changes made to the module.
37 Notice that changes are listed in reverse chronological order.
38
39
40 $Header:$ $DateTime: $ $Author: $
41
42
43 when who what, where, why
44 -------- --- --------------------------------------------------------
45 05/06/09 Shailender Created module.
46 ==========================================================================*/
47
48#include "wlan_hdd_includes.h"
49#include <aniGlobal.h>
50#include "dot11f.h"
51#include "wlan_nlink_common.h"
52#include "wlan_btc_svc.h"
53#include "wlan_hdd_power.h"
54#ifdef CONFIG_CFG80211
55#include <linux/ieee80211.h>
56#include <linux/wireless.h>
57#include <net/cfg80211.h>
58#include "wlan_hdd_cfg80211.h"
59#include "csrInsideApi.h"
60#endif
61#if defined CONFIG_CFG80211
62#include "wlan_hdd_p2p.h"
63#endif
64#include "sme_Api.h"
65
66v_BOOL_t mibIsDot11DesiredBssTypeInfrastructure( hdd_adapter_t *pAdapter );
67
68struct ether_addr
69{
70 u_char ether_addr_octet[6];
71};
72// These are needed to recognize WPA and RSN suite types
73#define HDD_WPA_OUI_SIZE 4
74v_U8_t ccpWpaOui00[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x00 };
75v_U8_t ccpWpaOui01[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x01 };
76v_U8_t ccpWpaOui02[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x02 };
77v_U8_t ccpWpaOui03[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x03 };
78v_U8_t ccpWpaOui04[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x04 };
79v_U8_t ccpWpaOui05[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x50, 0xf2, 0x05 };
80#ifdef FEATURE_WLAN_CCX
81v_U8_t ccpWpaOui06[ HDD_WPA_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM
82#endif /* FEATURE_WLAN_CCX */
83#define HDD_RSN_OUI_SIZE 4
84v_U8_t ccpRSNOui00[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x00 }; // group cipher
85v_U8_t ccpRSNOui01[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x01 }; // WEP-40 or RSN
86v_U8_t ccpRSNOui02[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x02 }; // TKIP or RSN-PSK
87v_U8_t ccpRSNOui03[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x03 }; // Reserved
88v_U8_t ccpRSNOui04[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x04 }; // AES-CCMP
89v_U8_t ccpRSNOui05[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x0F, 0xAC, 0x05 }; // WEP-104
90#ifdef FEATURE_WLAN_CCX
91v_U8_t ccpRSNOui06[ HDD_RSN_OUI_SIZE ] = { 0x00, 0x40, 0x96, 0x00 }; // CCKM
92#endif /* FEATURE_WLAN_CCX */
93
94#if defined(WLAN_FEATURE_VOWIFI_11R)
95// Offset where the EID-Len-IE, start.
96#define FT_ASSOC_RSP_IES_OFFSET 6
97#endif
98
99#define BEACON_FRAME_IES_OFFSET 12
100
101#ifdef WLAN_FEATURE_PACKET_FILTERING
Jeff Johnsone7245742012-09-05 17:12:55 -0700102extern void wlan_hdd_set_mc_addr_list(hdd_context_t *pHddCtx, v_U8_t set, v_U8_t sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -0700103#endif
104
Jeff Johnsond13512a2012-07-17 11:42:19 -0700105void hdd_ResetCountryCodeAfterDisAssoc(hdd_adapter_t *pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -0700106
107static inline v_VOID_t hdd_connSetConnectionState( hdd_station_ctx_t *pHddStaCtx, eConnectionState connState )
108{
109 // save the new connection state
110 pHddStaCtx->conn_info.connState = connState;
111}
112
113// returns FALSE if not connected.
114// returns TRUE for the two 'connected' states (Infra Associated or IBSS Connected ).
115// returns the connection state. Can specify NULL if you dont' want to get the actual state.
116
117static inline v_BOOL_t hdd_connGetConnectionState( hdd_station_ctx_t *pHddStaCtx,
118 eConnectionState *pConnState )
119{
120 v_BOOL_t fConnected;
121 eConnectionState connState;
122
123 // get the connection state.
124 connState = pHddStaCtx->conn_info.connState;
125 // Set the fConnected return variable based on the Connected State.
126 if ( eConnectionState_Associated == connState ||
127 eConnectionState_IbssConnected == connState )
128 {
129 fConnected = VOS_TRUE;
130 }
131 else
132 {
133 fConnected = VOS_FALSE;
134 }
135
136 if ( pConnState )
137 {
138 *pConnState = connState;
139 }
140
141 return( fConnected );
142}
143
144v_BOOL_t hdd_connIsConnected( hdd_station_ctx_t *pHddStaCtx )
145{
146 return( hdd_connGetConnectionState( pHddStaCtx, NULL ) );
147}
148
149//TODO - Not used anyhwere. Can be removed.
150#if 0
151//
152v_BOOL_t hdd_connIsConnectedInfra( hdd_adapter_t *pAdapter )
153{
154 v_BOOL_t fConnectedInfra = FALSE;
155 eConnectionState connState;
156
157 if ( hdd_connGetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connState ) )
158 {
159 if ( eConnectionState_Associated == connState )
160 {
161 fConnectedInfra = TRUE;
162 }
163 }
164
165 return( fConnectedInfra );
166}
167#endif
168
169static inline v_BOOL_t hdd_connGetConnectedCipherAlgo( hdd_station_ctx_t *pHddStaCtx, eCsrEncryptionType *pConnectedCipherAlgo )
170{
171 v_BOOL_t fConnected = VOS_FALSE;
172
173 fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL );
174
175 if ( pConnectedCipherAlgo )
176 {
177 *pConnectedCipherAlgo = pHddStaCtx->conn_info.ucEncryptionType;
178 }
179
180 return( fConnected );
181}
182
183inline v_BOOL_t hdd_connGetConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eMib_dot11DesiredBssType *pConnectedBssType )
184{
185 v_BOOL_t fConnected = VOS_FALSE;
186
187 fConnected = hdd_connGetConnectionState( pHddStaCtx, NULL );
188
189 if ( pConnectedBssType )
190 {
191 *pConnectedBssType = pHddStaCtx->conn_info.connDot11DesiredBssType;
192 }
193
194 return( fConnected );
195}
196
197static inline void hdd_connSaveConnectedBssType( hdd_station_ctx_t *pHddStaCtx, eCsrRoamBssType csrRoamBssType )
198{
199 switch( csrRoamBssType )
200 {
201 case eCSR_BSS_TYPE_INFRASTRUCTURE:
202 pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_infrastructure;
203 break;
204
205 case eCSR_BSS_TYPE_IBSS:
206 case eCSR_BSS_TYPE_START_IBSS:
207 pHddStaCtx->conn_info.connDot11DesiredBssType = eMib_dot11DesiredBssType_independent;
208 break;
209
210 /** We will never set the BssType to 'any' when attempting a connection
211 so CSR should never send this back to us.*/
212 case eCSR_BSS_TYPE_ANY:
213 default:
214 VOS_ASSERT( 0 );
215 break;
216 }
217
218}
219
220void hdd_connSaveConnectInfo( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, eCsrRoamBssType eBssType )
221{
222 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
223 eCsrEncryptionType encryptType = eCSR_ENCRYPT_TYPE_NONE;
224
225 VOS_ASSERT( pRoamInfo );
226
227 if ( pRoamInfo )
228 {
229 // Save the BSSID for the connection...
230 if ( eCSR_BSS_TYPE_INFRASTRUCTURE == eBssType )
231 {
232 VOS_ASSERT( pRoamInfo->pBssDesc );
233 vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,6 );
234
235 // Save the Station ID for this station from the 'Roam Info'.
236 //For IBSS mode, staId is assigned in NEW_PEER_IND
237 //For reassoc, the staID doesn't change and it may be invalid in this structure
238 //so no change here.
239 if( !pRoamInfo->fReassocReq )
240 {
241 pHddStaCtx->conn_info.staId [0]= pRoamInfo->staId;
242 }
243 }
244 else if ( eCSR_BSS_TYPE_IBSS == eBssType )
245 {
246 vos_mem_copy(pHddStaCtx->conn_info.bssId, pRoamInfo->bssid,sizeof(pRoamInfo->bssid) );
247 }
248 else
249 {
250 // can't happen. We need a valid IBSS or Infra setting in the BSSDescription
251 // or we can't function.
252 VOS_ASSERT( 0 );
253 }
254
255 // notify WMM
256 hdd_wmm_connect(pAdapter, pRoamInfo, eBssType);
257
258 if( !pRoamInfo->u.pConnectedProfile )
259 {
260 VOS_ASSERT( pRoamInfo->u.pConnectedProfile );
261 }
262 else
263 {
264 // Get Multicast Encryption Type
265 encryptType = pRoamInfo->u.pConnectedProfile->mcEncryptionType;
266 pHddStaCtx->conn_info.mcEncryptionType = encryptType;
267 // Get Unicast Encrytion Type
268 encryptType = pRoamInfo->u.pConnectedProfile->EncryptionType;
269 pHddStaCtx->conn_info.ucEncryptionType = encryptType;
270
271 pHddStaCtx->conn_info.authType = pRoamInfo->u.pConnectedProfile->AuthType;
272
273 pHddStaCtx->conn_info.operationChannel = pRoamInfo->u.pConnectedProfile->operationChannel;
274
275 // Save the ssid for the connection
276 vos_mem_copy( &pHddStaCtx->conn_info.SSID.SSID, &pRoamInfo->u.pConnectedProfile->SSID, sizeof( tSirMacSSid ) );
277 }
278 }
279
280 // save the connected BssType
281 hdd_connSaveConnectedBssType( pHddStaCtx, eBssType );
282
283}
284
285#if defined(WLAN_FEATURE_VOWIFI_11R)
286/*
287 * Send the 11R key information to the supplicant.
288 * Only then can the supplicant generate the PMK-R1.
289 * (BTW, the CCX supplicant also needs the Assoc Resp IEs
290 * for the same purpose.)
291 *
292 * Mainly the Assoc Rsp IEs are passed here. For the IMDA
293 * this contains the R1KHID, R0KHID and the MDID.
294 * For FT, this consists of the Reassoc Rsp FTIEs.
295 * This is the Assoc Response.
296 */
297static void hdd_SendFTAssocResponse(struct net_device *dev, hdd_adapter_t *pAdapter,
298 tCsrRoamInfo *pCsrRoamInfo)
299{
300 union iwreq_data wrqu;
301 char *buff;
302 unsigned int len = 0;
303 u8 *pFTAssocRsp = NULL;
304
305 if (pCsrRoamInfo->nAssocRspLength == 0)
306 {
307 hddLog(LOGE,
308 "%s: pCsrRoamInfo->nAssocRspLength=%d",
309 __func__, (int)pCsrRoamInfo->nAssocRspLength);
310 return;
311 }
312
313 pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
314 pCsrRoamInfo->nAssocReqLength);
315 if (pFTAssocRsp == NULL)
316 {
317 hddLog(LOGE, "%s: AssocReq or AssocRsp is NULL", __func__);
318 return;
319 }
320
321 // pFTAssocRsp needs to point to the IEs
322 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
323 hddLog(LOG1, "%s: AssocRsp is now at %02x%02x", __func__,
324 (unsigned int)pFTAssocRsp[0],
325 (unsigned int)pFTAssocRsp[1]);
326
327 // We need to send the IEs to the supplicant.
328 buff = kmalloc(IW_GENERIC_IE_MAX, GFP_ATOMIC);
329 if (buff == NULL)
330 {
331 hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__);
332 return;
333 }
334
335 // Send the Assoc Resp, the supplicant needs this for initial Auth.
336 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
337 wrqu.data.length = len;
338 memset(buff, 0, IW_GENERIC_IE_MAX);
339 memcpy(buff, pFTAssocRsp, len);
340 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, buff);
341
342 kfree(buff);
343}
344#endif /* WLAN_FEATURE_VOWIFI_11R */
345
346#ifdef WLAN_FEATURE_VOWIFI_11R
347
348/*---------------------------------------------------
349 *
350 * Send the FTIEs, RIC IEs during FT. This is eventually
351 * used to send the FT events to the supplicant
352 *
353 * At the reception of Auth2 we send the RIC followed
354 * by the auth response IEs to the supplicant.
355 * Once both are received in the supplicant, an FT
356 * event is generated to the supplicant.
357 *
358 *---------------------------------------------------
359 */
360void hdd_SendFTEvent(hdd_adapter_t *pAdapter)
361{
362 union iwreq_data wrqu;
363 //struct wpabuf *ric = NULL;
364 char *buff;
365 tANI_U16 auth_resp_len = 0;
366 tANI_U32 ric_ies_length = 0;
367 tANI_U16 str_len;
368 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
369
370 // We need to send the IEs to the supplicant.
371 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
372 vos_mem_zero(buff, IW_CUSTOM_MAX);
373 if (buff == NULL)
374 {
375 hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__);
376 return;
377 }
378
379 // Sme needs to send the RIC IEs first
380 str_len = strlcpy(buff, "RIC=", IW_CUSTOM_MAX);
381 sme_GetRICIEs( pHddCtx->hHal, (u8 *)&(buff[str_len]),
382 (IW_CUSTOM_MAX - str_len), &ric_ies_length );
383 if (ric_ies_length == 0)
384 {
385 hddLog(LOGW, "%s: RIC IEs is of length 0 not sending RIC Information for now", __func__);
386 }
387 else
388 {
389 wrqu.data.length = str_len + ric_ies_length;
390 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
391 }
392
393 // Sme needs to provide the Auth Resp
394 vos_mem_zero(buff, IW_CUSTOM_MAX);
395 str_len = strlcpy(buff, "AUTH=", IW_CUSTOM_MAX);
396 sme_GetFTPreAuthResponse(pHddCtx->hHal, (u8 *)&buff[str_len],
397 (IW_CUSTOM_MAX - str_len), &auth_resp_len);
398
399 if (auth_resp_len == 0)
400 {
401 hddLog(LOGE, "%s: AuthRsp FTIES is of length 0", __func__);
402 return;
403 }
404
405 wrqu.data.length = str_len + auth_resp_len;
406 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
407
408 kfree(buff);
409}
410
411#endif /* WLAN_FEATURE_VOWIFI_11R */
412
413#ifdef FEATURE_WLAN_CCX
414
415/*
416 * Send the CCX required "new AP Channel info" to the supplicant.
417 * (This keeps the supplicant "up to date" on the current channel.)
418 *
419 * The current (new AP) channel information is passed in.
420 */
421static void hdd_SendNewAPChannelInfo(struct net_device *dev, hdd_adapter_t *pAdapter,
422 tCsrRoamInfo *pCsrRoamInfo)
423{
424 union iwreq_data wrqu;
425 tSirBssDescription *descriptor = pCsrRoamInfo->pBssDesc;
426
427
428 if (descriptor == NULL)
429 {
430 hddLog(LOGE,
431 "%s: pCsrRoamInfo->pBssDesc=%p\n",
432 __func__, descriptor);
433 return;
434 }
435
436 // Send the Channel event, the supplicant needs this to generate the Adjacent AP report.
437 hddLog(LOGW, "%s: Sending up an SIOCGIWFREQ, channelId=%d\n", __func__, descriptor->channelId);
438 memset(&wrqu, '\0', sizeof(wrqu));
439 wrqu.freq.m = descriptor->channelId;
440 wrqu.freq.e = 0;
441 wrqu.freq.i = 0;
442 wireless_send_event(pAdapter->dev, SIOCGIWFREQ, &wrqu, NULL);
443}
444
445#endif /* FEATURE_WLAN_CCX */
446
447void hdd_SendUpdateBeaconIEsEvent(hdd_adapter_t *pAdapter, tCsrRoamInfo *pCsrRoamInfo)
448{
449 union iwreq_data wrqu;
450 u8 *pBeaconIes;
451 u8 currentLen = 0;
452 char *buff;
453 int totalIeLen = 0, currentOffset = 0, strLen;
454
455 memset(&wrqu, '\0', sizeof(wrqu));
456
457 if (0 == pCsrRoamInfo->nBeaconLength)
458 {
459 hddLog(LOGE, "%s: pCsrRoamInfo->nBeaconFrameLength = 0", __func__);
460 return;
461 }
462 pBeaconIes = (u8 *)(pCsrRoamInfo->pbFrames + BEACON_FRAME_IES_OFFSET);
463 if (pBeaconIes == NULL)
464 {
465 hddLog(LOGE, "%s: Beacon IEs is NULL", __func__);
466 return;
467 }
468
469 // pBeaconIes needs to point to the IEs
470 hddLog(LOG1, "%s: Beacon IEs is now at %02x%02x", __func__,
471 (unsigned int)pBeaconIes[0],
472 (unsigned int)pBeaconIes[1]);
473 hddLog(LOG1, "%s: Beacon IEs length = %d", __func__, pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET);
474
475 // We need to send the IEs to the supplicant.
476 buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
477 if (buff == NULL)
478 {
479 hddLog(LOGE, "%s: kmalloc unable to allocate memory", __func__);
480 return;
481 }
482 vos_mem_zero(buff, IW_CUSTOM_MAX);
483
484 strLen = strlcpy(buff,"BEACONIEs=", IW_CUSTOM_MAX);
485 currentLen = strLen + 1;
486
487 totalIeLen = pCsrRoamInfo->nBeaconLength - BEACON_FRAME_IES_OFFSET;
488 do
489 {
490 /* If the beacon size exceeds max CUSTOM event size, break it into chunks of CUSTOM event
491 * max size and send it to supplicant. Changes are done in supplicant to handle this */
492 vos_mem_zero(&buff[strLen + 1], IW_CUSTOM_MAX - (strLen + 1));
493 currentLen = VOS_MIN(totalIeLen, IW_CUSTOM_MAX - (strLen + 1) - 1);
494 vos_mem_copy(&buff[strLen + 1], pBeaconIes+currentOffset, currentLen);
495 currentOffset += currentLen;
496 totalIeLen -= currentLen;
497 wrqu.data.length = strLen + 1 + currentLen;
498 if (totalIeLen)
499 buff[strLen] = 1; // This tells supplicant more chunks are pending
500 else
501 buff[strLen] = 0; // For last chunk of beacon IE to supplicant
502
503 hddLog(LOG1, "%s: Beacon IEs length to supplicant = %d", __func__, currentLen);
504 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, buff);
505 } while (totalIeLen > 0);
506
507 kfree(buff);
508}
509
510static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRoamInfo)
511{
512 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
513 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
514 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
515 union iwreq_data wrqu;
516 int we_event;
517 char *msg;
518 int type = -1;
519
520#if defined (WLAN_FEATURE_VOWIFI_11R)
521 // Added to find the auth type on the fly at run time
522 // rather than with cfg to see if FT is enabled
523 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
524 tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile);
525#endif
526
527 memset(&wrqu, '\0', sizeof(wrqu));
528 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
529 we_event = SIOCGIWAP;
530
531 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */
532 {
533 memcpy(wrqu.ap_addr.sa_data, pCsrRoamInfo->pBssDesc->bssId, sizeof(pCsrRoamInfo->pBssDesc->bssId));
534 type = WLAN_STA_ASSOC_DONE_IND;
535
536 pr_info("wlan: connected to %02x:%02x:%02x:%02x:%02x:%02x\n",
537 wrqu.ap_addr.sa_data[0],
538 wrqu.ap_addr.sa_data[1],
539 wrqu.ap_addr.sa_data[2],
540 wrqu.ap_addr.sa_data[3],
541 wrqu.ap_addr.sa_data[4],
542 wrqu.ap_addr.sa_data[5]);
543 hdd_SendUpdateBeaconIEsEvent(pAdapter, pCsrRoamInfo);
544
545 /* Send IWEVASSOCRESPIE Event if WLAN_FEATURE_CIQ_METRICS is Enabled Or
546 * Send IWEVASSOCRESPIE Event if WLAN_FEATURE_VOWIFI_11R is Enabled
547 * and fFTEnable is TRUE */
548#ifdef WLAN_FEATURE_VOWIFI_11R
549 // Send FT Keys to the supplicant when FT is enabled
550 if ((pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN_PSK) ||
551 (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_FT_RSN)
552#ifdef FEATURE_WLAN_CCX
553 || (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) ||
554 (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA)
555#endif
556 )
557 {
558 hdd_SendFTAssocResponse(dev, pAdapter, pCsrRoamInfo);
559 }
560#endif
561 }
562 else if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState) // IBss Associated
563 {
564 memcpy(wrqu.ap_addr.sa_data, pHddStaCtx->conn_info.bssId, sizeof(wrqu.ap_addr.sa_data));
565 type = WLAN_STA_ASSOC_DONE_IND;
566 pr_info("wlan: new IBSS connection to %02x:%02x:%02x:%02x:%02x:%02x",
567 pHddStaCtx->conn_info.bssId[0],
568 pHddStaCtx->conn_info.bssId[1],
569 pHddStaCtx->conn_info.bssId[2],
570 pHddStaCtx->conn_info.bssId[3],
571 pHddStaCtx->conn_info.bssId[4],
572 pHddStaCtx->conn_info.bssId[5]);
573 }
574 else /* Not Associated */
575 {
576 pr_info("wlan: disconnected\n");
577 type = WLAN_STA_DISASSOC_DONE_IND;
578 memset(wrqu.ap_addr.sa_data,'\0',ETH_ALEN);
579 }
580
581 msg = NULL;
582 /*During the WLAN uninitialization,supplicant is stopped before the
583 driver so not sending the status of the connection to supplicant*/
584 if(pHddCtx->isLoadUnloadInProgress != TRUE)
585 {
586 wireless_send_event(dev, we_event, &wrqu, msg);
587#ifdef FEATURE_WLAN_CCX
588 if(eConnectionState_Associated == pHddStaCtx->conn_info.connState)/* Associated */
589 {
590 if ( (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_RSN) ||
591 (pRoamProfile->AuthType.authType[0] == eCSR_AUTH_TYPE_CCKM_WPA) )
592 hdd_SendNewAPChannelInfo(dev, pAdapter, pCsrRoamInfo);
593 }
594#endif
595 }
596 send_btc_nlink_msg(type, 0);
597}
598
599void hdd_connRemoveConnectInfo( hdd_station_ctx_t *pHddStaCtx )
600{
601 // Remove staId, bssId and peerMacAddress
602 pHddStaCtx->conn_info.staId [ 0 ] = 0;
603 vos_mem_zero( &pHddStaCtx->conn_info.bssId, sizeof( v_MACADDR_t ) );
604 vos_mem_zero( &pHddStaCtx->conn_info.peerMacAddress[ 0 ], sizeof( v_MACADDR_t ) );
605
606 // Clear all security settings
607 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
608 pHddStaCtx->conn_info.mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
609 pHddStaCtx->conn_info.ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
610
611 vos_mem_zero( &pHddStaCtx->conn_info.Keys, sizeof( tCsrKeys ) );
612
613 // Set not-connected state
614 pHddStaCtx->conn_info.connDot11DesiredBssType = eCSR_BSS_TYPE_ANY;
615 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_NotConnected );
616
617 vos_mem_zero( &pHddStaCtx->conn_info.SSID, sizeof( tCsrSSIDInfo ) );
618}
619/* TODO Revist this function. and data path */
620static VOS_STATUS hdd_roamDeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
621{
622 VOS_STATUS vosStatus;
623 hdd_disconnect_tx_rx(pAdapter);
624 vosStatus = WLANTL_ClearSTAClient( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext, staId );
625 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
626 {
627 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
628 "%s: WLANTL_ClearSTAClient() failed to for staID %d. "
629 "Status= %d [0x%08lX]",
630 __FUNCTION__, staId, vosStatus, vosStatus );
631 }
632 return( vosStatus );
633}
634
635
636static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
637 tANI_U32 roamId, eRoamCmdStatus roamStatus,
638 eCsrRoamResult roamResult )
639{
640 eHalStatus status = eHAL_STATUS_SUCCESS;
Jeff Johnson43971f52012-07-17 12:26:56 -0700641 VOS_STATUS vstatus;
Jeff Johnson295189b2012-06-20 16:38:30 -0700642 struct net_device *dev = pAdapter->dev;
643 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
644 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700645
646 // Sanity check
647 if(dev == NULL)
648 {
649 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
650 "%s: net_dev is released return", __func__);
651 return eHAL_STATUS_FAILURE;
652 }
653
Jeff Johnson295189b2012-06-20 16:38:30 -0700654 // notify apps that we can't pass traffic anymore
655 netif_tx_disable(dev);
656 netif_carrier_off(dev);
657
Jeff Johnsone7245742012-09-05 17:12:55 -0700658 INIT_COMPLETION(pAdapter->disconnect_comp_var);
659 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
Jeff Johnson295189b2012-06-20 16:38:30 -0700660 /* If only STA mode is on */
661 if((pHddCtx->concurrency_mode <= 1) && (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
662 {
663 pHddCtx->isAmpAllowed = VOS_TRUE;
664 }
665 hdd_clearRoamProfileIe( pAdapter );
666
667 // indicate 'disconnect' status to wpa_supplicant...
668 hdd_SendAssociationEvent(dev,pRoamInfo);
669#ifdef CONFIG_CFG80211
670 /* indicate disconnected event to nl80211 */
671 if(roamStatus != eCSR_ROAM_IBSS_LEAVE)
672 {
673 /*During the WLAN uninitialization,supplicant is stopped before the
674 driver so not sending the status of the connection to supplicant*/
675 if(pHddCtx->isLoadUnloadInProgress != TRUE)
676 {
677 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
678 "%s: sent disconnected event to nl80211",
679 __func__);
680 /* To avoid wpa_supplicant sending "HANGED" CMD to ICS UI */
681 if( eCSR_ROAM_LOSTLINK == roamStatus )
682 {
Jeff Johnsone7245742012-09-05 17:12:55 -0700683 /* TODO: Need to pass proper reason code
684 currently we are passing only one reason code.
685 Currently we are passing WLAN_REASON_DISASSOC_STA_HAS_LEFT
686 rather than WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY
687 to avoid the supplicant fast reconnect */
688
689 cfg80211_disconnected(dev, WLAN_REASON_DISASSOC_STA_HAS_LEFT, NULL, 0, GFP_KERNEL);
Jeff Johnson295189b2012-06-20 16:38:30 -0700690 }
691 else
692 {
693 cfg80211_disconnected(dev, WLAN_REASON_UNSPECIFIED, NULL, 0, GFP_KERNEL);
694 }
695
696 //If the Device Mode is Station
697 // and the P2P Client is Connected
698 //Enable BMPS
Jeff Johnsone7245742012-09-05 17:12:55 -0700699
700 // In case of JB, as Change-Iface may or maynot be called for p2p0
701 // Enable BMPS/IMPS in case P2P_CLIENT disconnected
702 if(((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
703 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -0700704 (vos_concurrent_sessions_running()))
705 {
706 //Enable BMPS only of other Session is P2P Client
707 hdd_context_t *pHddCtx = NULL;
708 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
709
710 if (NULL != pVosContext)
711 {
712 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
713
714 if(NULL != pHddCtx)
715 {
716 //Only P2P Client is there Enable Bmps back
717 if((0 == pHddCtx->no_of_sessions[VOS_STA_SAP_MODE]) &&
Jeff Johnsone7245742012-09-05 17:12:55 -0700718 (0 == pHddCtx->no_of_sessions[VOS_P2P_GO_MODE]))
Jeff Johnson295189b2012-06-20 16:38:30 -0700719 {
720 hdd_enable_bmps_imps(pHddCtx);
721 }
722 }
723 }
724 }
725 }
726 }
727#endif
728
729
730 //We should clear all sta register with TL, for now, only one.
Jeff Johnson43971f52012-07-17 12:26:56 -0700731 vstatus = hdd_roamDeregisterSTA( pAdapter, pHddStaCtx->conn_info.staId [0] );
732 if ( !VOS_IS_STATUS_SUCCESS(vstatus ) )
Jeff Johnson295189b2012-06-20 16:38:30 -0700733 {
734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
735 "hdd_roamDeregisterSTA() failed to for staID %d. "
736 "Status= %d [0x%x]",
737 pHddStaCtx->conn_info.staId[0], status, status );
738
739 status = eHAL_STATUS_FAILURE;
740 }
741
742 pHddCtx->sta_to_adapter[pHddStaCtx->conn_info.staId[0]] = NULL;
743 // Clear saved connection information in HDD
744 hdd_connRemoveConnectInfo( pHddStaCtx );
745
746 //Unblock anyone waiting for disconnect to complete
747 complete(&pAdapter->disconnect_comp_var);
748 return( status );
749}
750static VOS_STATUS hdd_roamRegisterSTA( hdd_adapter_t *pAdapter,
751 tCsrRoamInfo *pRoamInfo,
752 v_U8_t staId,
753 v_MACADDR_t *pPeerMacAddress,
754 tSirBssDescription *pBssDesc )
755{
756 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
757 WLAN_STADescType staDesc = {0};
758 eCsrEncryptionType connectedCipherAlgo;
759 v_BOOL_t fConnected;
760 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
761 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
762
763 // Get the Station ID from the one saved during the assocation.
764 staDesc.ucSTAId = staId;
765
766 if ( pHddStaCtx->conn_info.connDot11DesiredBssType == eMib_dot11DesiredBssType_infrastructure)
767 {
768 staDesc.wSTAType = WLAN_STA_INFRA;
769
770 // grab the bssid from the connection info in the adapter structure and hand that
771 // over to TL when registering.
772 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pHddStaCtx->conn_info.bssId,sizeof(pHddStaCtx->conn_info.bssId) );
773 }
774 else
775 {
776 // for an IBSS 'connect', setup the Station Descriptor for TL.
777 staDesc.wSTAType = WLAN_STA_IBSS;
778
779 // Note that for IBSS, the STA MAC address and BSSID are goign to be different where
780 // in infrastructure, they are the same (BSSID is the MAC address of the AP). So,
781 // for IBSS we have a second field to pass to TL in the STA descriptor that we don't
782 // pass when making an Infrastructure connection.
783 vos_mem_copy( staDesc.vSTAMACAddress.bytes, pPeerMacAddress->bytes,sizeof(pPeerMacAddress->bytes) );
784 vos_mem_copy( staDesc.vBSSIDforIBSS.bytes, pHddStaCtx->conn_info.bssId,6 );
785 }
786
787 vos_copy_macaddr( &staDesc.vSelfMACAddress, &pAdapter->macAddressCurrent );
788
789 // set the QoS field appropriately
790 if (hdd_wmm_is_active(pAdapter))
791 {
792 staDesc.ucQosEnabled = 1;
793 }
794 else
795 {
796 staDesc.ucQosEnabled = 0;
797 }
798
799 fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo );
800 if ( connectedCipherAlgo != eCSR_ENCRYPT_TYPE_NONE )
801 {
802 staDesc.ucProtectedFrame = 1;
803 }
804 else
805 {
806 staDesc.ucProtectedFrame = 0;
807
808 }
809
810#ifdef FEATURE_WLAN_CCX
811 staDesc.ucIsCcxSta = pRoamInfo->isCCXAssoc;
812#endif //FEATURE_WLAN_CCX
813
814#ifdef VOLANS_ENABLE_SW_REPLAY_CHECK
815 /* check whether replay check is valid for the station or not */
816 if( (eCSR_ENCRYPT_TYPE_TKIP == connectedCipherAlgo) || (eCSR_ENCRYPT_TYPE_AES == connectedCipherAlgo))
817 {
818 /* Encryption mode is either TKIP or AES
819 and replay check is valid for only these
820 two encryption modes */
821 staDesc.ucIsReplayCheckValid = VOS_TRUE;
822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
823 "HDD register TL ucIsReplayCheckValid %d: Replay check is needed for station", staDesc.ucIsReplayCheckValid);
824 }
825
826 else
827 {
828 /* For other encryption modes replay check is
829 not needed */
830 staDesc.ucIsReplayCheckValid = VOS_FALSE;
831 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
832 "HDD register TL ucIsReplayCheckValid %d", staDesc.ucIsReplayCheckValid);
833 }
834#endif
835
836#ifdef FEATURE_WLAN_WAPI
837 hddLog(LOG1, "%s: WAPI STA Registered: %d", __FUNCTION__, pAdapter->wapi_info.fIsWapiSta);
838 if (pAdapter->wapi_info.fIsWapiSta)
839 {
840 staDesc.ucIsWapiSta = 1;
841 }
842 else
843 {
844 staDesc.ucIsWapiSta = 0;
845 }
846#endif /* FEATURE_WLAN_WAPI */
847
848 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
849 "HDD register TL Sec_enabled= %d.", staDesc.ucProtectedFrame );
850
851#ifdef FEATURE_WLAN_INTEGRATED_SOC
852 // UMA is Not ready yet, Xlation will be done by TL
853 staDesc.ucSwFrameTXXlation = 1;
854#else
855 /* Enable UMA for TX translation only when there is no concurrent session active */
856 if (vos_concurrent_sessions_running())
857 {
858 staDesc.ucSwFrameTXXlation = 1;
859 }
860 else
861 {
862 staDesc.ucSwFrameTXXlation = 0;
863 }
864#endif
865 staDesc.ucSwFrameRXXlation = 1;
866 staDesc.ucAddRmvLLC = 1;
867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH, "HDD register TL QoS_enabled=%d",
868 staDesc.ucQosEnabled );
869 // Initialize signatures and state
870 staDesc.ucUcastSig = pRoamInfo->ucastSig;
871 staDesc.ucBcastSig = pRoamInfo->bcastSig;
872 staDesc.ucInitState = pRoamInfo->fAuthRequired ?
873 WLANTL_STA_CONNECTED : WLANTL_STA_AUTHENTICATED;
874 // Register the Station with TL...
875 vosStatus = WLANTL_RegisterSTAClient( pHddCtx->pvosContext,
876 hdd_rx_packet_cbk,
877 hdd_tx_complete_cbk,
878 hdd_tx_fetch_packet_cbk, &staDesc,
879 pBssDesc->rssi );
880
881 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
882 {
883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
884 "WLANTL_RegisterSTAClient() failed to register. Status= %d [0x%08lX]",
885 vosStatus, vosStatus );
886 return vosStatus;
887 }
888
889 // if ( WPA ), tell TL to go to 'connected' and after keys come to the driver,
890 // then go to 'authenticated'. For all other authentication types (those that do
891 // not require upper layer authentication) we can put TL directly into 'authenticated'
892 // state.
893
894 VOS_ASSERT( fConnected );
895
896 if ( !pRoamInfo->fAuthRequired )
897 {
898 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
899 "open/shared auth StaId= %d. Changing TL state to AUTHENTICATED at Join time", pHddStaCtx->conn_info.staId[ 0 ] );
900
901 // Connections that do not need Upper layer auth, transition TL directly
902 // to 'Authenticated' state.
903 vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, staDesc.ucSTAId,
904 WLANTL_STA_AUTHENTICATED );
905
906 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
907 }
908 else
909 {
910 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
911 "ULA auth StaId= %d. Changing TL state to CONNECTED at Join time", pHddStaCtx->conn_info.staId[ 0 ] );
912
913 vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, staDesc.ucSTAId,
914 WLANTL_STA_CONNECTED );
915
916 pHddStaCtx->conn_info.uIsAuthenticated = VOS_FALSE;
917 }
918 return( vosStatus );
919}
920
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700921#if defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700922static void hdd_SendReAssocEvent(struct net_device *dev, hdd_adapter_t *pAdapter,
923 tCsrRoamInfo *pCsrRoamInfo, v_U8_t *reqRsnIe, tANI_U32 reqRsnLength)
924{
925 unsigned int len = 0;
926 u8 *pFTAssocRsp = NULL;
927 v_U8_t rspRsnIe[IW_GENERIC_IE_MAX];
928 tANI_U32 rspRsnLength = 0;
929 struct ieee80211_channel *chan;
930
931 if (pCsrRoamInfo == NULL)
932 return;
933
934 if (pCsrRoamInfo->nAssocRspLength == 0)
935 return;
936
937 pFTAssocRsp = (u8 *)(pCsrRoamInfo->pbFrames + pCsrRoamInfo->nBeaconLength +
938 pCsrRoamInfo->nAssocReqLength);
939 if (pFTAssocRsp == NULL)
940 return;
941
942 //pFTAssocRsp needs to point to the IEs
943 pFTAssocRsp += FT_ASSOC_RSP_IES_OFFSET;
944 hddLog(LOG1, "%s: AssocRsp is now at %02x%02x\n", __func__,
945 (unsigned int)pFTAssocRsp[0],
946 (unsigned int)pFTAssocRsp[1]);
947
948 // Send the Assoc Resp, the supplicant needs this for initial Auth.
949 len = pCsrRoamInfo->nAssocRspLength - FT_ASSOC_RSP_IES_OFFSET;
950 rspRsnLength = len;
951 memset(rspRsnIe, 0, IW_GENERIC_IE_MAX);
952 memcpy(rspRsnIe, pFTAssocRsp, len);
953
954 chan = ieee80211_get_channel(pAdapter->wdev.wiphy, (int) pCsrRoamInfo->pBssDesc->channelId);
955 cfg80211_roamed(dev,chan,pCsrRoamInfo->bssid,
956 reqRsnIe, reqRsnLength,
957 rspRsnIe, rspRsnLength,GFP_KERNEL);
958}
959#endif /* FEATURE_WLAN_CCX */
960
961static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
962 tANI_U32 roamId, eRoamCmdStatus roamStatus,
963 eCsrRoamResult roamResult )
964{
965 struct net_device *dev = pAdapter->dev;
966 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
967 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
968 VOS_STATUS vosStatus;
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700969#if defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -0700970 int ft_carrier_on = FALSE;
971#endif
972 int status;
973
974 if ( eCSR_ROAM_RESULT_ASSOCIATED == roamResult )
975 {
976 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Associated );
977
978 // Save the connection info from CSR...
979 hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE );
980#ifdef FEATURE_WLAN_WAPI
981 if ( pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE ||
982 pRoamInfo->u.pConnectedProfile->AuthType == eCSR_AUTH_TYPE_WAPI_WAI_PSK )
983 {
984 pAdapter->wapi_info.fIsWapiSta = 1;
985 }
986 else
987 {
988 pAdapter->wapi_info.fIsWapiSta = 0;
989 }
990#endif /* FEATURE_WLAN_WAPI */
991
992 // indicate 'connect' status to userspace
993 hdd_SendAssociationEvent(dev,pRoamInfo);
994
995
996 // Initialize the Linkup event completion variable
997 INIT_COMPLETION(pAdapter->linkup_event_var);
998
999 /*
1000 Sometimes Switching ON the Carrier is taking time to activate the device properly. Before allowing any
1001 packet to go up to the application, device activation has to be ensured for proper queue mapping by the
1002 kernel. we have registered net device notifier for device change notification. With this we will come to
1003 know that the device is getting activated properly.
1004 */
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001005#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001006 if (pHddStaCtx->ft_carrier_on == FALSE)
1007 {
1008#endif
1009 // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable
1010 pAdapter->isLinkUpSvcNeeded = TRUE;
1011
1012 // Enable Linkup Event Servicing which allows the net device notifier to set the linkup event variable
1013 pAdapter->isLinkUpSvcNeeded = TRUE;
1014
1015 // Switch on the Carrier to activate the device
1016 netif_carrier_on(dev);
1017
1018 // Wait for the Link to up to ensure all the queues are set properly by the kernel
1019 status = wait_for_completion_interruptible_timeout(&pAdapter->linkup_event_var,
1020 msecs_to_jiffies(ASSOC_LINKUP_TIMEOUT));
1021 if(!status)
1022 {
1023 hddLog(VOS_TRACE_LEVEL_WARN, "%s: Warning:ASSOC_LINKUP_TIMEOUT", __func__);
1024 }
1025
1026 // Disable Linkup Event Servicing - no more service required from the net device notifier call
1027 pAdapter->isLinkUpSvcNeeded = FALSE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001028#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001029 }
1030 else {
1031 pHddStaCtx->ft_carrier_on = FALSE;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001032#if defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001033 ft_carrier_on = TRUE;
1034#endif /* FEATURE_WLAN_CCX */
1035 }
1036#endif
1037 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1038
1039 //For reassoc, the station is already registered, all we need is to change the state
1040 //of the STA in TL.
1041 //If authentication is required (WPA/WPA2/DWEP), change TL to CONNECTED instead of AUTHENTICATED
1042 if( !pRoamInfo->fReassocReq )
1043 {
1044#ifdef CONFIG_CFG80211
1045 v_U8_t reqRsnIe[DOT11F_IE_RSN_MAX_LEN];
1046 v_U8_t rspRsnIe[DOT11F_IE_RSN_MAX_LEN];
1047 tANI_U32 reqRsnLength = DOT11F_IE_RSN_MAX_LEN;
1048 tANI_U32 rspRsnLength = DOT11F_IE_RSN_MAX_LEN;
1049 struct cfg80211_bss *bss;
1050
1051 /* add bss_id to cfg80211 data base */
1052 bss = wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
1053 if (NULL == bss)
1054 {
1055 pr_err("wlan: Not able to create BSS entry\n");
1056 return eHAL_STATUS_FAILURE;
1057 }
1058
1059 /* wpa supplicant expecting WPA/RSN IE in connect result */
1060 csrRoamGetWpaRsnReqIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
1061 pAdapter->sessionId,
1062 &reqRsnLength,
1063 reqRsnIe);
1064
1065 csrRoamGetWpaRsnRspIE(WLAN_HDD_GET_HAL_CTX(pAdapter),
1066 pAdapter->sessionId,
1067 &rspRsnLength,
1068 rspRsnIe);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001069#if defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001070 if(ft_carrier_on)
1071 hdd_SendReAssocEvent(dev, pAdapter, pRoamInfo, reqRsnIe, reqRsnLength);
1072 else
1073#endif /* FEATURE_WLAN_CCX */
1074
1075 {
1076 /* inform connect result to nl80211 */
1077 cfg80211_connect_result(dev, pRoamInfo->bssid,
1078 reqRsnIe, reqRsnLength,
1079 rspRsnIe, rspRsnLength,
1080 WLAN_STATUS_SUCCESS,
1081 GFP_KERNEL);
1082
1083 cfg80211_put_bss(bss);
1084 }
1085#endif
1086
1087 // Register the Station with TL after associated...
1088 vosStatus = hdd_roamRegisterSTA( pAdapter,
1089 pRoamInfo,
1090 pHddStaCtx->conn_info.staId[ 0 ],
1091 NULL,
1092 pRoamInfo->pBssDesc );
1093 }
1094 else
1095 {
1096 //Reassoc successfully
1097 if( pRoamInfo->fAuthRequired )
1098 {
1099 vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
1100 WLANTL_STA_CONNECTED );
1101 pHddStaCtx->conn_info.uIsAuthenticated = VOS_FALSE;
1102 }
1103 else
1104 {
1105 vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
1106 WLANTL_STA_AUTHENTICATED );
1107 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
1108 }
1109 }
1110
1111 if ( VOS_IS_STATUS_SUCCESS( vosStatus ) )
1112 {
1113 // perform any WMM-related association processing
1114 hdd_wmm_assoc(pAdapter, pRoamInfo, eCSR_BSS_TYPE_INFRASTRUCTURE);
1115 }
1116 else
1117 {
1118 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1119 "Cannot register STA with TL. Failed with vosStatus = %d [%08lX]",
1120 vosStatus, vosStatus );
1121 }
1122
1123 // Start the Queue
1124 netif_tx_wake_all_queues(dev);
1125 }
1126 else
1127 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001128 hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
1129
1130 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson32d95a32012-09-10 13:15:23 -07001131 pr_info("wlan: connection failed with %02x:%02x:%02x:%02x:%02x:%02x"
1132 " reason:%d and Status:%d\n", pWextState->req_bssId[0],
1133 pWextState->req_bssId[1], pWextState->req_bssId[2],
1134 pWextState->req_bssId[3], pWextState->req_bssId[4],
1135 pWextState->req_bssId[5], roamResult, roamStatus);
Jeff Johnson295189b2012-06-20 16:38:30 -07001136
1137 /*Handle all failure conditions*/
1138 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_NotConnected);
1139 if((pHddCtx->concurrency_mode <= 1) && (pHddCtx->no_of_sessions[WLAN_HDD_INFRA_STATION] <=1))
1140 {
1141 pHddCtx->isAmpAllowed = VOS_TRUE;
1142 }
1143
1144 //If the Device Mode is Station
1145 // and the P2P Client is Connected
1146 //Enable BMPS
Jeff Johnsone7245742012-09-05 17:12:55 -07001147
1148 // In case of JB, as Change-Iface may or maynot be called for p2p0
1149 // Enable BMPS/IMPS in case P2P_CLIENT disconnected
1150 if(((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1151 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -07001152 (vos_concurrent_sessions_running()))
1153 {
1154 //Enable BMPS only of other Session is P2P Client
1155 hdd_context_t *pHddCtx = NULL;
1156 v_CONTEXT_t pVosContext = vos_get_global_context( VOS_MODULE_ID_HDD, NULL );
1157
1158 if (NULL != pVosContext)
1159 {
1160 pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
1161
1162 if(NULL != pHddCtx)
1163 {
1164 //Only P2P Client is there Enable Bmps back
1165 if((0 == pHddCtx->no_of_sessions[VOS_STA_SAP_MODE]) &&
Jeff Johnsone7245742012-09-05 17:12:55 -07001166 (0 == pHddCtx->no_of_sessions[VOS_P2P_GO_MODE]))
Jeff Johnson295189b2012-06-20 16:38:30 -07001167 {
1168 hdd_enable_bmps_imps(pHddCtx);
1169 }
1170 }
1171 }
1172 }
1173
1174#ifdef CONFIG_CFG80211
1175 /* inform association failure event to nl80211 */
Jeff Johnsone7245742012-09-05 17:12:55 -07001176 if(eCSR_ROAM_RESULT_ASSOC_FAIL_CON_CHANNEL == roamResult)
1177 {
1178 cfg80211_connect_result(dev, pWextState->req_bssId,
1179 NULL, 0, NULL, 0,
1180 WLAN_STATUS_ASSOC_DENIED_UNSPEC,
1181 GFP_KERNEL);
1182 }
1183 else
1184 {
1185 cfg80211_connect_result(dev, pWextState->req_bssId,
Jeff Johnson295189b2012-06-20 16:38:30 -07001186 NULL, 0, NULL, 0,
1187 WLAN_STATUS_UNSPECIFIED_FAILURE,
1188 GFP_KERNEL);
Jeff Johnsone7245742012-09-05 17:12:55 -07001189 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001190#endif
1191
1192 netif_tx_disable(dev);
1193 netif_carrier_off(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07001194
1195 if (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode)
1196 {
1197 /* Association failed; Reset the country code information
1198 * so that it re-initialize the valid channel list*/
1199 hdd_ResetCountryCodeAfterDisAssoc(pAdapter);
1200 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001201 }
1202
1203 return eHAL_STATUS_SUCCESS;
1204}
1205
1206/**============================================================================
1207 *
1208 @brief roamRoamIbssIndicationHandler() - Here we update the status of the
1209 Ibss when we receive information that we have started/joined an ibss session
1210 We always return SUCCESS.
1211
1212 ===========================================================================*/
1213static eHalStatus roamRoamIbssIndicationHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
1214 tANI_U32 roamId, eRoamCmdStatus roamStatus,
1215 eCsrRoamResult roamResult )
1216{
1217 switch( roamResult )
1218 {
1219 // both IBSS Started and IBSS Join should come in here.
1220 case eCSR_ROAM_RESULT_IBSS_STARTED:
1221 case eCSR_ROAM_RESULT_IBSS_JOIN_SUCCESS:
1222 {
1223 // we should have a pRoamInfo on this callback...
1224 VOS_ASSERT( pRoamInfo );
1225
1226 // When IBSS Started comes from CSR, we need to move connection state to
1227 // IBSS Disconnected (meaning no peers are in the IBSS).
1228 hdd_connSetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), eConnectionState_IbssDisconnected );
1229
1230 break;
1231 }
1232
1233 case eCSR_ROAM_RESULT_IBSS_START_FAILED:
1234 {
1235 VOS_ASSERT( pRoamInfo );
1236
1237 break;
1238 }
1239
1240 default:
1241 break;
1242 }
1243
1244 return( eHAL_STATUS_SUCCESS );
1245}
1246
1247/**============================================================================
1248 *
1249 @brief roamSaveIbssStation() - Save the IBSS peer MAC address in the adapter.
1250 This information is passed to iwconfig later. The peer that joined
1251 last is passed as information to iwconfig.
1252 If we add HDD_MAX_NUM_IBSS_STA or less STA we return success else we
1253 return FALSE.
1254
1255 ===========================================================================*/
1256static int roamSaveIbssStation( hdd_station_ctx_t *pHddStaCtx, v_U8_t staId, v_MACADDR_t *peerMacAddress )
1257{
1258 int fSuccess = FALSE;
1259 int idx = 0;
1260
1261 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
1262 {
1263 if ( 0 == pHddStaCtx->conn_info.staId[ idx ] )
1264 {
1265 pHddStaCtx->conn_info.staId[ idx ] = staId;
1266
1267 vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ], peerMacAddress );
1268
1269 fSuccess = TRUE;
1270 break;
1271 }
1272 }
1273
1274 return( fSuccess );
1275}
1276/**============================================================================
1277 *
1278 @brief roamRemoveIbssStation() - Remove the IBSS peer MAC address in the adapter.
1279 If we remove HDD_MAX_NUM_IBSS_STA or less STA we return success else we
1280 return FALSE.
1281
1282 ===========================================================================*/
1283static int roamRemoveIbssStation( hdd_station_ctx_t *pHddStaCtx, v_U8_t staId )
1284{
1285 int fSuccess = FALSE;
1286 int idx = 0;
1287 v_U8_t valid_idx = 0;
1288 v_U8_t del_idx = 0;
1289
1290 for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ )
1291 {
1292 if ( staId == pHddStaCtx->conn_info.staId[ idx ] )
1293 {
1294 pHddStaCtx->conn_info.staId[ idx ] = 0;
1295
1296 vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ] );
1297
1298 fSuccess = TRUE;
1299 // Note the deleted Index, if its 0 we need special handling
1300 del_idx = idx;
1301 }
1302 else
1303 {
1304 if (pHddStaCtx->conn_info.staId[idx] != 0)
1305 {
1306 valid_idx = idx;
1307 }
1308 }
1309 }
1310
1311 // Find next active staId, to have a valid sta trigger for TL.
1312 if (fSuccess == TRUE)
1313 {
1314 if (del_idx == 0)
1315 {
1316 if (pHddStaCtx->conn_info.staId[valid_idx] != 0)
1317 {
1318 pHddStaCtx->conn_info.staId[0] = pHddStaCtx->conn_info.staId[valid_idx];
1319 vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ 0 ],
1320 &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ]);
1321
1322 pHddStaCtx->conn_info.staId[valid_idx] = 0;
1323 vos_zero_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ valid_idx ] );
1324 }
1325 }
1326 }
1327 return( fSuccess );
1328}
1329
1330/**============================================================================
1331 *
1332 @brief roamIbssConnectHandler() : We update the status of the IBSS to
1333 connected in this function.
1334
1335 ===========================================================================*/
1336static eHalStatus roamIbssConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo )
1337{
1338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "IBSS Connect Indication from SME!!!" );
1339 // Set the internal connection state to show 'IBSS Connected' (IBSS with a partner stations)...
1340 hdd_connSetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), eConnectionState_IbssConnected );
1341
1342 // Save the connection info from CSR...
1343 hdd_connSaveConnectInfo( pAdapter, pRoamInfo, eCSR_BSS_TYPE_IBSS );
1344
1345 // Send the bssid address to the wext.
1346 hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo);
1347#ifdef CONFIG_CFG80211
1348 /* add bss_id to cfg80211 data base */
1349 wlan_hdd_cfg80211_update_bss_db(pAdapter, pRoamInfo);
1350 /* send ibss join indication to nl80211 */
1351 cfg80211_ibss_joined(pAdapter->dev, &pRoamInfo->bssid[0], GFP_KERNEL);
1352#endif
1353
1354 return( eHAL_STATUS_SUCCESS );
1355}
1356/**============================================================================
1357 *
1358 @brief hdd_RoamSetKeyCompleteHandler() - Update the security parameters.
1359
1360 ===========================================================================*/
1361static eHalStatus hdd_RoamSetKeyCompleteHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
1362 tANI_U32 roamId, eRoamCmdStatus roamStatus,
1363 eCsrRoamResult roamResult )
1364{
1365 eCsrEncryptionType connectedCipherAlgo;
1366 v_BOOL_t fConnected = FALSE;
1367 VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE;
1368 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1369 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1370 ENTER();
1371 // if ( WPA ), tell TL to go to 'authenticated' after the keys are set.
1372 // then go to 'authenticated'. For all other authentication types (those that do
1373 // not require upper layer authentication) we can put TL directly into 'authenticated'
1374 // state.
1375 fConnected = hdd_connGetConnectedCipherAlgo( pHddStaCtx, &connectedCipherAlgo );
1376 if( fConnected )
1377 {
1378 // TODO: Considering getting a state machine in HDD later.
1379 // This routuine is invoked twice. 1)set PTK 2)set GTK. The folloing if statement will be
1380 // TRUE when setting GTK. At this time we don't handle the state in detail.
1381 // Related CR: 174048 - TL not in authenticated state
1382 if(( eCSR_ROAM_RESULT_AUTHENTICATED == roamResult ) && (pRoamInfo != NULL) && !pRoamInfo->fAuthRequired)
1383 {
1384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_MED,
1385 "Key set for StaId= %d. Changing TL state to AUTHENTICATED", pHddStaCtx->conn_info.staId[ 0 ] );
1386
1387 // Connections that do not need Upper layer authentication, transition TL
1388 // to 'Authenticated' state after the keys are set.
1389 vosStatus = WLANTL_ChangeSTAState( pHddCtx->pvosContext, pHddStaCtx->conn_info.staId[ 0 ],
1390 WLANTL_STA_AUTHENTICATED );
1391
1392 pHddStaCtx->conn_info.uIsAuthenticated = VOS_TRUE;
1393 }
1394
1395 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1396 }
1397 else
1398 {
1399 // possible disassoc after issuing set key and waiting set key complete
1400 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
1401 }
1402
1403 EXIT();
1404 return( eHAL_STATUS_SUCCESS );
1405}
1406/**============================================================================
1407 *
1408 @brief hdd_RoamMicErrorIndicationHandler() - This function indicates the Mic failure to the supplicant.
1409 ===========================================================================*/
1410static eHalStatus hdd_RoamMicErrorIndicationHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
1411 tANI_U32 roamId, eRoamCmdStatus roamStatus, eCsrRoamResult roamResult )
1412{
1413 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1414
1415 if( eConnectionState_Associated == pHddStaCtx->conn_info.connState &&
1416 TKIP_COUNTER_MEASURE_STOPED == pHddStaCtx->WextState.mTKIPCounterMeasures )
1417 {
1418 struct iw_michaelmicfailure msg;
1419 union iwreq_data wreq;
1420 memset(&msg, '\0', sizeof(msg));
1421 msg.src_addr.sa_family = ARPHRD_ETHER;
1422 memcpy(msg.src_addr.sa_data, pRoamInfo->u.pMICFailureInfo->taMacAddr, sizeof(pRoamInfo->u.pMICFailureInfo->taMacAddr));
1423 hddLog(LOG1, "MIC MAC %02x:%02x:%02x:%02x:%02x:%02x",
1424 msg.src_addr.sa_data[0],
1425 msg.src_addr.sa_data[1],
1426 msg.src_addr.sa_data[2],
1427 msg.src_addr.sa_data[3],
1428 msg.src_addr.sa_data[4],
1429 msg.src_addr.sa_data[5]);
1430
1431 if(pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE)
1432 msg.flags = IW_MICFAILURE_GROUP;
1433 else
1434 msg.flags = IW_MICFAILURE_PAIRWISE;
1435 memset(&wreq, 0, sizeof(wreq));
1436 wreq.data.length = sizeof(msg);
1437 wireless_send_event(pAdapter->dev, IWEVMICHAELMICFAILURE, &wreq, (char *)&msg);
1438#ifdef CONFIG_CFG80211
1439 /* inform mic failure to nl80211 */
1440 cfg80211_michael_mic_failure(pAdapter->dev,
1441 pRoamInfo->u.pMICFailureInfo->taMacAddr,
1442 ((pRoamInfo->u.pMICFailureInfo->multicast == eSIR_TRUE) ?
1443 NL80211_KEYTYPE_GROUP :
1444 NL80211_KEYTYPE_PAIRWISE),
1445 pRoamInfo->u.pMICFailureInfo->keyId,
1446 pRoamInfo->u.pMICFailureInfo->TSC,
1447 GFP_KERNEL);
1448#endif
1449
1450 }
1451
1452 return( eHAL_STATUS_SUCCESS );
1453}
1454
1455/**============================================================================
1456 *
1457 @brief roamRoamConnectStatusUpdateHandler() - The Ibss connection status is
1458 updated regularly here in this function.
1459
1460 ===========================================================================*/
1461static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
1462 tANI_U32 roamId, eRoamCmdStatus roamStatus,
1463 eCsrRoamResult roamResult )
1464{
1465 VOS_STATUS vosStatus;
1466
1467 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1468 switch( roamResult )
1469 {
1470 case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
1471 {
1472 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1473 "IBSS New Peer indication from SME "
1474 "with peerMac %2x-%2x-%2x-%2x-%2x-%2x and stationID= %d",
1475 pRoamInfo->peerMac[0], pRoamInfo->peerMac[1], pRoamInfo->peerMac[2],
1476 pRoamInfo->peerMac[3], pRoamInfo->peerMac[4], pRoamInfo->peerMac[5],
1477 pRoamInfo->staId );
1478
1479 if ( !roamSaveIbssStation( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pRoamInfo->staId, (v_MACADDR_t *)pRoamInfo->peerMac ) )
1480 {
1481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1482 "New IBSS peer but we already have the max we can handle. Can't register this one" );
1483 break;
1484 }
1485
1486 pHddCtx->sta_to_adapter[pRoamInfo->staId] = pAdapter;
1487
1488 // Register the Station with TL for the new peer.
1489 vosStatus = hdd_roamRegisterSTA( pAdapter,
1490 pRoamInfo,
1491 pRoamInfo->staId,
1492 (v_MACADDR_t *)pRoamInfo->peerMac,
1493 pRoamInfo->pBssDesc );
1494 if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) )
1495 {
1496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1497 "Cannot register STA with TL for IBSS. Failed with vosStatus = %d [%08lX]",
1498 vosStatus, vosStatus );
1499 }
1500
1501 netif_carrier_on(pAdapter->dev);
1502 netif_tx_start_all_queues(pAdapter->dev);
1503 break;
1504 }
1505
1506 case eCSR_ROAM_RESULT_IBSS_CONNECT:
1507 {
1508
1509 roamIbssConnectHandler( pAdapter, pRoamInfo );
1510
1511 break;
1512 }
1513 case eCSR_ROAM_RESULT_IBSS_PEER_DEPARTED:
1514 {
1515
1516 if ( !roamRemoveIbssStation( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pRoamInfo->staId ) )
1517 {
1518 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1519 "IBSS peer departed by cannot find peer in our registration table with TL" );
1520 }
1521
1522 hdd_roamDeregisterSTA( pAdapter, pRoamInfo->staId );
1523
1524 pHddCtx->sta_to_adapter[pRoamInfo->staId] = NULL;
1525
1526 break;
1527 }
1528 case eCSR_ROAM_RESULT_IBSS_INACTIVE:
1529 {
1530 // Stop only when we are inactive
1531 netif_tx_disable(pAdapter->dev);
1532 netif_carrier_off(pAdapter->dev);
1533 hdd_connSetConnectionState( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), eConnectionState_NotConnected );
1534
1535 // Send the bssid address to the wext.
1536 hdd_SendAssociationEvent(pAdapter->dev, pRoamInfo);
1537 // clean up data path
1538 hdd_disconnect_tx_rx(pAdapter);
1539 break;
1540 }
1541 default:
1542 break;
1543
1544 }
1545
1546 return( eHAL_STATUS_SUCCESS );
1547}
1548
1549eHalStatus hdd_smeRoamCallback( void *pContext, tCsrRoamInfo *pRoamInfo, tANI_U32 roamId,
1550 eRoamCmdStatus roamStatus, eCsrRoamResult roamResult )
1551{
1552 eHalStatus halStatus = eHAL_STATUS_SUCCESS;
1553 hdd_adapter_t *pAdapter = (hdd_adapter_t *)pContext;
1554 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
1555 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1556
1557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1558 "CSR Callback: status= %d result= %d roamID=%ld",
1559 roamStatus, roamResult, roamId );
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001560
1561 /*Sanity check*/
1562 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
1563 {
1564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
1565 "pAdapter has invalid magic return");
1566 return eHAL_STATUS_FAILURE;
1567 }
1568
Jeff Johnson295189b2012-06-20 16:38:30 -07001569 switch( roamStatus )
1570 {
1571 case eCSR_ROAM_SESSION_OPENED:
1572 if(pAdapter != NULL)
1573 {
1574 set_bit(SME_SESSION_OPENED, &pAdapter->event_flags);
1575 complete(&pAdapter->session_open_comp_var);
1576 }
1577 break;
1578
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001579#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001580 /* We did pre-auth,then we attempted a 11r or ccx reassoc.
1581 * reassoc failed due to failure, timeout, reject from ap
1582 * in any case tell the OS, our carrier is off and mark
1583 * interface down */
1584 case eCSR_ROAM_FT_REASSOC_FAILED:
1585 hddLog(LOG1, FL("Reassoc Failed\n"));
1586 halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1587 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
1588 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set == TRUE) {
1589#ifdef FEATURE_WLAN_NON_INTEGRATED_SOC
1590#ifdef MSM_PLATFORM
1591 hdd_conf_mcastbcast_filter((WLAN_HDD_GET_CTX(pAdapter)), FALSE);
1592#endif
1593#endif
1594 (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE;
1595 }
1596 pHddStaCtx->ft_carrier_on = FALSE;
1597 break;
1598
1599 case eCSR_ROAM_FT_START:
1600 // When we roam for CCX and 11r, we dont want the
1601 // OS to be informed that the link is down. So mark
1602 // the link ready for ft_start. After this the
1603 // eCSR_ROAM_SHOULD_ROAM will be received.
1604 // Where in we will not mark the link down
1605 // Also we want to stop tx at this point when we will be
1606 // doing disassoc at this time. This saves 30-60 msec
1607 // after reassoc. We see old traffic from old connection on new channel
1608 {
1609 struct net_device *dev = pAdapter->dev;
1610 netif_tx_disable(dev);
1611 }
1612 pHddStaCtx->ft_carrier_on = TRUE;
1613 break;
1614#endif
1615
1616 case eCSR_ROAM_SHOULD_ROAM:
1617 // Dont need to do anything
1618 {
1619 VOS_STATUS status = VOS_STATUS_SUCCESS;
1620 struct net_device *dev = pAdapter->dev;
1621 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1622 // notify apps that we can't pass traffic anymore
1623 netif_tx_disable(dev);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001624#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001625 if (pHddStaCtx->ft_carrier_on == FALSE)
1626 {
1627#endif
1628 netif_carrier_off(dev);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001629#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_CCX) || defined(FEATURE_WLAN_LFR)
Jeff Johnson295189b2012-06-20 16:38:30 -07001630 }
1631#endif
1632
1633 //We should clear all sta register with TL, for now, only one.
1634 status = hdd_roamDeregisterSTA( pAdapter, pHddStaCtx->conn_info.staId [0] );
1635 if ( !VOS_IS_STATUS_SUCCESS(status ) )
1636 {
1637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1638 FL("hdd_roamDeregisterSTA() failed to for staID %d. Status= %d [0x%x]"),
1639 pHddStaCtx->conn_info.staId[0], status, status );
1640 status = eHAL_STATUS_FAILURE;
1641 }
1642
1643 // Clear saved connection information in HDD
1644 hdd_connRemoveConnectInfo( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) );
1645 }
1646 break;
1647 case eCSR_ROAM_LOSTLINK:
1648 case eCSR_ROAM_DISASSOCIATED:
1649 {
Jeff Johnson295189b2012-06-20 16:38:30 -07001650 hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07001651 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1652 "****eCSR_ROAM_DISASSOCIATED****");
1653 halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1654 /* Check if Mcast/Bcast Filters are set, if yes clear the filters here */
1655 if ((WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set == TRUE) {
1656 hdd_conf_mcastbcast_filter((WLAN_HDD_GET_CTX(pAdapter)), FALSE);
1657 (WLAN_HDD_GET_CTX(pAdapter))->hdd_mcastbcast_filter_set = FALSE;
1658 }
1659#ifdef WLAN_FEATURE_PACKET_FILTERING
1660 if (pHddCtx->cfg_ini->isMcAddrListFilter)
1661 {
1662 /*Multicast addr filtering is enabled*/
1663 if(pHddCtx->mc_addr_list.isFilterApplied)
1664 {
1665 /*Filter applied during suspend mode*/
1666 /*Clear it here*/
Jeff Johnsone7245742012-09-05 17:12:55 -07001667 wlan_hdd_set_mc_addr_list(pHddCtx, FALSE, pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07001668 }
1669 }
1670#endif
1671
Jeff Johnsone7245742012-09-05 17:12:55 -07001672 if (WLAN_HDD_P2P_CLIENT != pAdapter->device_mode)
1673 {
1674 /* Disconnected from current AP. Reset the country code information
1675 * so that it re-initialize the valid channel list*/
1676 hdd_ResetCountryCodeAfterDisAssoc(pAdapter);
1677 }
Jeff Johnson295189b2012-06-20 16:38:30 -07001678 }
1679 break;
1680 case eCSR_ROAM_IBSS_LEAVE:
1681 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1682 "****eCSR_ROAM_IBSS_LEAVE****");
1683 halStatus = hdd_DisConnectHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1684 break;
1685 case eCSR_ROAM_ASSOCIATION_COMPLETION:
1686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1687 "****eCSR_ROAM_ASSOCIATION_COMPLETION****");
1688 if ( (roamResult != eCSR_ROAM_RESULT_ASSOCIATED)
1689 && ( (pWextState->roamProfile.EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_WEP40_STATICKEY)
1690 || (pWextState->roamProfile.EncryptionType.encryptionType[0] == eCSR_ENCRYPT_TYPE_WEP104_STATICKEY)
1691 )
1692 && (eCSR_AUTH_TYPE_SHARED_KEY != pWextState->roamProfile.AuthType.authType[0])
1693 )
1694 {
1695 v_U32_t roamId = 0;
1696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
1697 "****WEP open authentication failed, trying with shared authentication****");
1698 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
1699 pWextState->roamProfile.AuthType.authType[0] = (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.authType;
1700 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
1701 halStatus = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, &(pWextState->roamProfile), &roamId);
1702 }
1703 else
1704 {
1705 halStatus = hdd_AssociationCompletionHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1706 }
1707
1708 break;
1709 case eCSR_ROAM_ASSOCIATION_FAILURE:
1710 halStatus = hdd_AssociationCompletionHandler( pAdapter,
1711 pRoamInfo, roamId, roamStatus, roamResult );
1712 break;
1713 case eCSR_ROAM_IBSS_IND:
1714 halStatus = roamRoamIbssIndicationHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1715 break;
1716
1717 case eCSR_ROAM_CONNECT_STATUS_UPDATE:
1718 halStatus = roamRoamConnectStatusUpdateHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1719 break;
1720
1721 case eCSR_ROAM_MIC_ERROR_IND:
1722 halStatus = hdd_RoamMicErrorIndicationHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1723 break;
1724
1725 case eCSR_ROAM_SET_KEY_COMPLETE:
1726 halStatus = hdd_RoamSetKeyCompleteHandler( pAdapter, pRoamInfo, roamId, roamStatus, roamResult );
1727 break;
1728#ifdef WLAN_FEATURE_VOWIFI_11R
1729 case eCSR_ROAM_FT_RESPONSE:
1730 hdd_SendFTEvent(pAdapter);
1731 break;
1732#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001733#ifdef FEATURE_WLAN_LFR
1734 case eCSR_ROAM_PMK_NOTIFY:
Jeff Johnson43971f52012-07-17 12:26:56 -07001735 if (eCSR_AUTH_TYPE_RSN == pHddStaCtx->conn_info.authType)
1736 {
1737 /* Notify the supplicant of a new candidate */
1738 halStatus = wlan_hdd_cfg80211_pmksa_candidate_notify(pAdapter, pRoamInfo, 1, false);
1739 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07001740 break;
1741#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07001742
1743#ifdef WLAN_FEATURE_P2P
1744 case eCSR_ROAM_INDICATE_MGMT_FRAME:
1745 hdd_indicateMgmtFrame( pAdapter,
1746 pRoamInfo->nFrameLength,
1747 pRoamInfo->pbFrames,
1748 pRoamInfo->frameType,
1749 pRoamInfo->rxChan );
1750 break;
1751 case eCSR_ROAM_REMAIN_CHAN_READY:
1752 hdd_remainChanReadyHandler( pAdapter );
1753 break;
1754 case eCSR_ROAM_SEND_ACTION_CNF:
1755 hdd_sendActionCnf( pAdapter,
1756 (roamResult == eCSR_ROAM_RESULT_NONE) ? TRUE : FALSE );
1757 break;
1758#endif
1759 default:
1760 break;
1761 }
1762 return( halStatus );
1763}
1764eCsrAuthType hdd_TranslateRSNToCsrAuthType( u_int8_t auth_suite[4])
1765{
1766 eCsrAuthType auth_type;
1767 // is the auth type supported?
1768 if ( memcmp(auth_suite , ccpRSNOui01, 4) == 0)
1769 {
1770 auth_type = eCSR_AUTH_TYPE_RSN;
1771 } else
1772 if (memcmp(auth_suite , ccpRSNOui02, 4) == 0)
1773 {
1774 auth_type = eCSR_AUTH_TYPE_RSN_PSK;
1775 } else
1776#ifdef WLAN_FEATURE_VOWIFI_11R
1777 if (memcmp(auth_suite , ccpRSNOui04, 4) == 0)
1778 {
1779 // Check for 11r FT Authentication with PSK
1780 auth_type = eCSR_AUTH_TYPE_FT_RSN_PSK;
1781 } else
1782 if (memcmp(auth_suite , ccpRSNOui03, 4) == 0)
1783 {
1784 // Check for 11R FT Authentication with 802.1X
1785 auth_type = eCSR_AUTH_TYPE_FT_RSN;
1786 } else
1787#endif
1788#ifdef FEATURE_WLAN_CCX
1789 if (memcmp(auth_suite , ccpRSNOui06, 4) == 0)
1790 {
1791 auth_type = eCSR_AUTH_TYPE_CCKM_RSN;
1792 } else
1793#endif /* FEATURE_WLAN_CCX */
1794 {
1795 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
1796 }
1797 return auth_type;
1798}
1799#ifdef WLAN_SOFTAP_FEATURE
1800eCsrAuthType
1801hdd_TranslateWPAToCsrAuthType(u_int8_t auth_suite[4])
1802#else
1803static eCsrAuthType hdd_TranslateWPAToCsrAuthType(u_int8_t auth_suite[4])
1804#endif
1805{
1806 eCsrAuthType auth_type;
1807 // is the auth type supported?
1808 if ( memcmp(auth_suite , ccpWpaOui01, 4) == 0)
1809 {
1810 auth_type = eCSR_AUTH_TYPE_WPA;
1811 } else
1812 if (memcmp(auth_suite , ccpWpaOui02, 4) == 0)
1813 {
1814 auth_type = eCSR_AUTH_TYPE_WPA_PSK;
1815 } else
1816#ifdef FEATURE_WLAN_CCX
1817 if (memcmp(auth_suite , ccpWpaOui06, 4) == 0)
1818 {
1819 auth_type = eCSR_AUTH_TYPE_CCKM_WPA;
1820 } else
1821#endif /* FEATURE_WLAN_CCX */
1822 {
1823 auth_type = eCSR_AUTH_TYPE_UNKNOWN;
1824 }
1825 hddLog(LOG1, FL("auth_type: %d"), auth_type);
1826 return auth_type;
1827}
1828#ifdef WLAN_SOFTAP_FEATURE
1829eCsrEncryptionType
1830hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4])
1831#else
1832static eCsrEncryptionType hdd_TranslateRSNToCsrEncryptionType(u_int8_t cipher_suite[4])
1833#endif
1834{
1835 eCsrEncryptionType cipher_type;
1836 // is the cipher type supported?
1837 if ( memcmp(cipher_suite , ccpRSNOui04, 4) == 0)
1838 {
1839 cipher_type = eCSR_ENCRYPT_TYPE_AES;
1840 }
1841 else if (memcmp(cipher_suite , ccpRSNOui02, 4) == 0)
1842 {
1843 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
1844 }
1845 else if (memcmp(cipher_suite , ccpRSNOui00, 4) == 0)
1846 {
1847 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
1848 }
1849 else if (memcmp(cipher_suite , ccpRSNOui01, 4) == 0)
1850 {
1851 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
1852 }
1853 else if (memcmp(cipher_suite , ccpRSNOui05, 4) == 0)
1854 {
1855 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
1856 }
1857 else
1858 {
1859 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
1860 }
1861 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
1862 return cipher_type;
1863}
1864/* To find if the MAC address is NULL */
1865static tANI_U8 hdd_IsMACAddrNULL (tANI_U8 *macAddr, tANI_U8 length)
1866{
1867 int i;
1868 for (i = 0; i < length; i++)
1869 {
1870 if (0x00 != (macAddr[i]))
1871 {
1872 return FALSE;
1873 }
1874 }
1875 return TRUE;
1876} /****** end hdd_IsMACAddrNULL() ******/
1877#ifdef WLAN_SOFTAP_FEATURE
1878eCsrEncryptionType
1879hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4])
1880#else
1881static eCsrEncryptionType
1882hdd_TranslateWPAToCsrEncryptionType(u_int8_t cipher_suite[4])
1883#endif
1884{
1885 eCsrEncryptionType cipher_type;
1886 // is the cipher type supported?
1887 if ( memcmp(cipher_suite , ccpWpaOui04, 4) == 0)
1888 {
1889 cipher_type = eCSR_ENCRYPT_TYPE_AES;
1890 } else
1891 if (memcmp(cipher_suite , ccpWpaOui02, 4) == 0)
1892 {
1893 cipher_type = eCSR_ENCRYPT_TYPE_TKIP;
1894 } else
1895 if (memcmp(cipher_suite , ccpWpaOui00, 4) == 0)
1896 {
1897 cipher_type = eCSR_ENCRYPT_TYPE_NONE;
1898 } else
1899 if (memcmp(cipher_suite , ccpWpaOui01, 4) == 0)
1900 {
1901 cipher_type = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
1902 } else
1903 if (memcmp(cipher_suite , ccpWpaOui05, 4) == 0)
1904 {
1905 cipher_type = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
1906 } else
1907 {
1908 cipher_type = eCSR_ENCRYPT_TYPE_FAILED;
1909 }
1910 hddLog(LOG1, FL("cipher_type: %d"), cipher_type);
1911 return cipher_type;
1912}
1913
1914static tANI_S32 hdd_ProcessGENIE(hdd_adapter_t *pAdapter,
1915 struct ether_addr *pBssid,
1916 eCsrEncryptionType *pEncryptType,
1917 eCsrEncryptionType *mcEncryptType,
1918 eCsrAuthType *pAuthType,
1919 u_int16_t gen_ie_len,
1920 u_int8_t *gen_ie)
1921{
1922 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
1923 eHalStatus result;
1924 tDot11fIERSN dot11RSNIE;
1925 tDot11fIEWPA dot11WPAIE;
1926 tANI_U32 i;
1927 tANI_U8 *pRsnIe;
1928 tANI_U16 RSNIeLen;
1929 tPmkidCacheInfo PMKIDCache[4]; // Local transfer memory
1930
1931 /* Clear struct of tDot11fIERSN and tDot11fIEWPA specifically setting present
1932 flag to 0 */
1933 memset( &dot11WPAIE, 0 , sizeof(tDot11fIEWPA) );
1934 memset( &dot11RSNIE, 0 , sizeof(tDot11fIERSN) );
1935
1936 // Validity checks
1937 if ((gen_ie_len < VOS_MIN(DOT11F_IE_RSN_MIN_LEN, DOT11F_IE_WPA_MIN_LEN)) ||
1938 (gen_ie_len > VOS_MAX(DOT11F_IE_RSN_MAX_LEN, DOT11F_IE_WPA_MAX_LEN)) )
1939 return -EINVAL;
1940 // Type check
1941 if ( gen_ie[0] == DOT11F_EID_RSN)
1942 {
1943 // Validity checks
1944 if ((gen_ie_len < DOT11F_IE_RSN_MIN_LEN ) ||
1945 (gen_ie_len > DOT11F_IE_RSN_MAX_LEN) )
1946 {
1947 return -EINVAL;
1948 }
1949 // Skip past the EID byte and length byte
1950 pRsnIe = gen_ie + 2;
1951 RSNIeLen = gen_ie_len - 2;
1952 // Unpack the RSN IE
1953 dot11fUnpackIeRSN((tpAniSirGlobal) halHandle,
1954 pRsnIe,
1955 RSNIeLen,
1956 &dot11RSNIE);
1957 // Copy out the encryption and authentication types
1958 hddLog(LOG1, FL("%s: pairwise cipher suite count: %d"),
1959 __FUNCTION__, dot11RSNIE.pwise_cipher_suite_count );
1960 hddLog(LOG1, FL("%s: authentication suite count: %d"),
1961 __FUNCTION__, dot11RSNIE.akm_suite_count);
1962 /*Here we have followed the apple base code,
1963 but probably I suspect we can do something different*/
1964 //dot11RSNIE.akm_suite_count
1965 // Just translate the FIRST one
1966 *pAuthType = hdd_TranslateRSNToCsrAuthType(dot11RSNIE.akm_suites[0]);
1967 //dot11RSNIE.pwise_cipher_suite_count
1968 *pEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.pwise_cipher_suites[0]);
1969 //dot11RSNIE.gp_cipher_suite_count
1970 *mcEncryptType = hdd_TranslateRSNToCsrEncryptionType(dot11RSNIE.gp_cipher_suite);
1971 // Set the PMKSA ID Cache for this interface
1972 for (i=0; i<dot11RSNIE.pmkid_count; i++)
1973 {
1974 if ( pBssid == NULL)
1975 {
1976 break;
1977 }
1978 if ( hdd_IsMACAddrNULL( (u_char *) pBssid , sizeof( (char *) pBssid)))
1979 {
1980 break;
1981 }
1982 // For right now, I assume setASSOCIATE() has passed in the bssid.
1983 vos_mem_copy(PMKIDCache[i].BSSID,
1984 pBssid, ETHER_ADDR_LEN);
1985 vos_mem_copy(PMKIDCache[i].PMKID,
1986 dot11RSNIE.pmkid[i],
1987 CSR_RSN_PMKID_SIZE);
1988 }
1989 // Calling csrRoamSetPMKIDCache to configure the PMKIDs into the cache
1990 hddLog(LOG1, FL("%s: Calling csrRoamSetPMKIDCache with cache entry %ld."),
1991 __FUNCTION__, i );
1992 // Finally set the PMKSA ID Cache in CSR
1993 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
1994 PMKIDCache,
1995 dot11RSNIE.pmkid_count );
1996 }
1997 else if (gen_ie[0] == DOT11F_EID_WPA)
1998 {
1999 // Validity checks
2000 if ((gen_ie_len < DOT11F_IE_WPA_MIN_LEN ) ||
2001 (gen_ie_len > DOT11F_IE_WPA_MAX_LEN))
2002 {
2003 return -EINVAL;
2004 }
2005 // Skip past the EID byte and length byte - and four byte WiFi OUI
2006 pRsnIe = gen_ie + 2 + 4;
2007 RSNIeLen = gen_ie_len - (2 + 4);
2008 // Unpack the WPA IE
2009 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
2010 pRsnIe,
2011 RSNIeLen,
2012 &dot11WPAIE);
2013 // Copy out the encryption and authentication types
2014 hddLog(LOG1, FL("%s: WPA unicast cipher suite count: %d"),
2015 __FUNCTION__, dot11WPAIE.unicast_cipher_count );
2016 hddLog(LOG1, FL("%s: WPA authentication suite count: %d"),
2017 __FUNCTION__, dot11WPAIE.auth_suite_count);
2018 //dot11WPAIE.auth_suite_count
2019 // Just translate the FIRST one
2020 *pAuthType = hdd_TranslateWPAToCsrAuthType(dot11WPAIE.auth_suites[0]);
2021 //dot11WPAIE.unicast_cipher_count
2022 *pEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.unicast_ciphers[0]);
2023 //dot11WPAIE.unicast_cipher_count
2024 *mcEncryptType = hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
2025 }
2026 else
2027 {
2028 hddLog(LOGW, FL("gen_ie[0]: %d"), gen_ie[0]);
2029 return -EINVAL;
2030 }
2031 return 0;
2032}
2033int hdd_SetGENIEToCsr( hdd_adapter_t *pAdapter, eCsrAuthType *RSNAuthType)
2034{
2035 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2036 v_U32_t status = 0;
2037 eCsrEncryptionType RSNEncryptType;
2038 eCsrEncryptionType mcRSNEncryptType;
2039 struct ether_addr bSsid; // MAC address of assoc peer
2040 // MAC address of assoc peer
2041 // But, this routine is only called when we are NOT associated.
2042 vos_mem_copy(bSsid.ether_addr_octet,
2043 pWextState->roamProfile.BSSIDs.bssid,
2044 sizeof(bSsid.ether_addr_octet));
2045 if (pWextState->WPARSNIE[0] == DOT11F_EID_RSN || pWextState->WPARSNIE[0] == DOT11F_EID_WPA)
2046 {
2047 //continue
2048 }
2049 else
2050 {
2051 return 0;
2052 }
2053 // The actual processing may eventually be more extensive than this.
2054 // Right now, just consume any PMKIDs that are sent in by the app.
2055 status = hdd_ProcessGENIE(pAdapter,
2056 &bSsid, // MAC address of assoc peer
2057 &RSNEncryptType,
2058 &mcRSNEncryptType,
2059 RSNAuthType,
2060 pWextState->WPARSNIE[1]+2,
2061 pWextState->WPARSNIE);
2062 if (status == 0)
2063 {
2064 // Now copy over all the security attributes you have parsed out
2065 pWextState->roamProfile.EncryptionType.numEntries = 1;
2066 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
2067
2068 pWextState->roamProfile.EncryptionType.encryptionType[0] = RSNEncryptType; // Use the cipher type in the RSN IE
2069 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = mcRSNEncryptType;
2070 hddLog( LOG1, "%s: CSR AuthType = %d, EncryptionType = %d mcEncryptionType = %d", __FUNCTION__, *RSNAuthType, RSNEncryptType, mcRSNEncryptType);
2071 }
2072 return 0;
2073}
2074int hdd_set_csr_auth_type ( hdd_adapter_t *pAdapter, eCsrAuthType RSNAuthType)
2075{
2076 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2077 tCsrRoamProfile* pRoamProfile = &(pWextState->roamProfile);
2078 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2079 ENTER();
2080
2081 pRoamProfile->AuthType.numEntries = 1;
2082 hddLog( LOG1, "%s: pHddStaCtx->conn_info.authType = %d\n", __FUNCTION__, pHddStaCtx->conn_info.authType);
2083
2084 switch( pHddStaCtx->conn_info.authType)
2085 {
2086 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
2087#ifdef FEATURE_WLAN_CCX
2088 case eCSR_AUTH_TYPE_CCKM_WPA:
2089 case eCSR_AUTH_TYPE_CCKM_RSN:
2090#endif
2091 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_DISABLED) {
2092
2093 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_OPEN_SYSTEM ;
2094 } else
2095 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA) {
2096
2097#ifdef FEATURE_WLAN_CCX
2098 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA) &&
2099 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
2100 == IW_AUTH_KEY_MGMT_802_1X)) {
2101 hddLog( LOG1, "%s: set authType to CCKM WPA. AKM also 802.1X.\n", __FUNCTION__);
2102 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA;
2103 } else
2104 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_WPA)) {
2105 hddLog( LOG1, "%s: Last chance to set authType to CCKM WPA.\n", __FUNCTION__);
2106 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_WPA;
2107 } else
2108#endif
2109 if((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
2110 == IW_AUTH_KEY_MGMT_802_1X) {
2111 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA;
2112 } else
2113 if ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
2114 == IW_AUTH_KEY_MGMT_PSK) {
2115 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_PSK;
2116 } else {
2117 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WPA_NONE;
2118 }
2119 }
2120 if (pWextState->wpaVersion & IW_AUTH_WPA_VERSION_WPA2) {
2121#ifdef FEATURE_WLAN_CCX
2122 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN) &&
2123 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
2124 == IW_AUTH_KEY_MGMT_802_1X)) {
2125 hddLog( LOG1, "%s: set authType to CCKM RSN. AKM also 802.1X.\n", __FUNCTION__);
2126 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN;
2127 } else
2128 if ((RSNAuthType == eCSR_AUTH_TYPE_CCKM_RSN)) {
2129 hddLog( LOG1, "%s: Last chance to set authType to CCKM RSN.\n", __FUNCTION__);
2130 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_CCKM_RSN;
2131 } else
2132#endif
2133
2134#ifdef WLAN_FEATURE_VOWIFI_11R
2135 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN) &&
2136 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
2137 == IW_AUTH_KEY_MGMT_802_1X)) {
2138 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN;
Jeff Johnson43971f52012-07-17 12:26:56 -07002139 }else
Jeff Johnson295189b2012-06-20 16:38:30 -07002140 if ((RSNAuthType == eCSR_AUTH_TYPE_FT_RSN_PSK) &&
2141 ((pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
2142 == IW_AUTH_KEY_MGMT_PSK)) {
2143 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_FT_RSN_PSK;
2144 } else
2145#endif
2146
2147 if( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X)
2148 == IW_AUTH_KEY_MGMT_802_1X) {
2149 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN;
2150 } else
2151 if ( (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_PSK)
2152 == IW_AUTH_KEY_MGMT_PSK) {
2153 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_RSN_PSK;
2154 } else {
2155 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
2156 }
2157 }
2158 break;
2159
2160 case eCSR_AUTH_TYPE_SHARED_KEY:
2161
2162 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_SHARED_KEY;
2163 break;
2164 default:
2165
2166#ifdef FEATURE_WLAN_CCX
2167 hddLog( LOG1, "%s: In default, unknown auth type.\n", __FUNCTION__);
2168#endif /* FEATURE_WLAN_CCX */
2169 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_UNKNOWN;
2170 break;
2171 }
2172
2173 hddLog( LOG1, "%s Set roam Authtype to %d",
2174 __FUNCTION__, pWextState->roamProfile.AuthType.authType[0]);
2175
2176 EXIT();
2177 return 0;
2178}
2179
2180/**---------------------------------------------------------------------------
2181
2182 \brief iw_set_essid() -
2183 This function sets the ssid received from wpa_supplicant
2184 to the CSR roam profile.
2185
2186 \param - dev - Pointer to the net device.
2187 - info - Pointer to the iw_request_info.
2188 - wrqu - Pointer to the iwreq_data.
2189 - extra - Pointer to the data.
2190 \return - 0 for success, non zero for failure
2191
2192 --------------------------------------------------------------------------*/
2193
2194int iw_set_essid(struct net_device *dev,
2195 struct iw_request_info *info,
2196 union iwreq_data *wrqu, char *extra)
2197{
2198 v_U32_t status = 0;
2199 hdd_wext_state_t *pWextState;
2200 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2201 v_U32_t roamId;
2202 tCsrRoamProfile *pRoamProfile;
2203 eMib_dot11DesiredBssType connectedBssType;
2204 eCsrAuthType RSNAuthType;
2205 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
2206 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2207
2208 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2209
2210 ENTER();
2211
2212 if ((WLAN_HDD_GET_CTX(pAdapter))->isLogpInProgress)
2213 {
2214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2215 "%s:LOGP in Progress. Ignore!!!",__func__);
2216 return 0;
2217 }
2218
2219 if(pWextState->mTKIPCounterMeasures == TKIP_COUNTER_MEASURE_STARTED) {
2220 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s :Counter measure is in progress", __func__);
2221 return -EBUSY;
2222 }
2223 if( SIR_MAC_MAX_SSID_LENGTH < wrqu->essid.length )
2224 return -EINVAL;
2225 pRoamProfile = &pWextState->roamProfile;
2226 if (pRoamProfile)
2227 {
2228 if ( hdd_connGetConnectedBssType( pHddStaCtx, &connectedBssType ) ||
2229 ( eMib_dot11DesiredBssType_independent == pHddStaCtx->conn_info.connDot11DesiredBssType ))
2230 {
2231 VOS_STATUS vosStatus;
2232 // need to issue a disconnect to CSR.
2233 INIT_COMPLETION(pAdapter->disconnect_comp_var);
2234 vosStatus = sme_RoamDisconnect( hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_UNSPECIFIED );
2235
2236 if(VOS_STATUS_SUCCESS == vosStatus)
2237 wait_for_completion_interruptible_timeout(&pAdapter->disconnect_comp_var,
2238 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
2239 }
2240 }
2241 /** wpa_supplicant 0.8.x, wext driver uses */
2242 else
2243 {
2244 return -EINVAL;
2245 }
2246 /** wpa_supplicant 0.8.x, wext driver uses */
2247#ifdef CONFIG_CFG80211
2248 /** when cfg80211 defined, wpa_supplicant wext driver uses
2249 zero-length, null-string ssid for force disconnection.
2250 after disconnection (if previously connected) and cleaning ssid,
2251 driver MUST return success */
2252 if ( 0 == wrqu->essid.length ) {
2253 return 0;
2254 }
2255#endif
2256
2257 status = hdd_wmm_get_uapsd_mask(pAdapter,
2258 &pWextState->roamProfile.uapsd_mask);
2259 if (VOS_STATUS_SUCCESS != status)
2260 {
2261 pWextState->roamProfile.uapsd_mask = 0;
2262 }
2263 pWextState->roamProfile.SSIDs.numOfSSIDs = 1;
2264
2265 pWextState->roamProfile.SSIDs.SSIDList->SSID.length = wrqu->essid.length;
2266
2267 vos_mem_zero(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId, sizeof(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId));
2268 vos_mem_copy((void *)(pWextState->roamProfile.SSIDs.SSIDList->SSID.ssId), extra, wrqu->essid.length);
2269 if (IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion ||
2270 IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion ) {
2271
2272 //set gen ie
2273 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
2274
2275 //set auth
2276 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
2277 }
2278#ifdef FEATURE_WLAN_WAPI
2279 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __FUNCTION__);
2280 if (pAdapter->wapi_info.nWapiMode)
2281 {
2282 switch (pAdapter->wapi_info.wapiAuthMode)
2283 {
2284 case WAPI_AUTH_MODE_PSK:
2285 {
2286 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __FUNCTION__, pAdapter->wapi_info.wapiAuthMode);
2287 pRoamProfile->AuthType.numEntries = 1;
2288 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
2289 break;
2290 }
2291 case WAPI_AUTH_MODE_CERT:
2292 {
2293 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __FUNCTION__, pAdapter->wapi_info.wapiAuthMode);
2294 pRoamProfile->AuthType.numEntries = 1;
2295 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
2296 break;
2297 }
2298 } // End of switch
2299 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
2300 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
2301 {
2302 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __FUNCTION__);
2303 pRoamProfile->EncryptionType.numEntries = 1;
2304 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
2305 pRoamProfile->mcEncryptionType.numEntries = 1;
2306 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
2307 }
2308 }
2309#endif /* FEATURE_WLAN_WAPI */
2310 /* if previous genIE is not NULL, update AssocIE */
2311 if (0 != pWextState->genIE.length)
2312 {
2313 memset( &pWextState->assocAddIE, 0, sizeof(pWextState->assocAddIE) );
2314 memcpy( pWextState->assocAddIE.addIEdata, pWextState->genIE.addIEdata,
2315 pWextState->genIE.length);
2316 pWextState->assocAddIE.length = pWextState->genIE.length;
2317 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
2318 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
2319
2320 /* clear previous genIE after use it */
2321 memset( &pWextState->genIE, 0, sizeof(pWextState->genIE) );
2322 }
2323
2324 /* assumes it is not WPS Association by default, except when pAddIEAssoc has WPS IE */
2325 pWextState->roamProfile.bWPSAssociation = FALSE;
2326
2327 if (NULL != wlan_hdd_get_wps_ie_ptr(pWextState->roamProfile.pAddIEAssoc,
2328 pWextState->roamProfile.nAddIEAssocLength))
2329 pWextState->roamProfile.bWPSAssociation = TRUE;
2330
2331
2332 // Disable auto BMPS entry by PMC until DHCP is done
2333 sme_SetDHCPTillPowerActiveFlag(WLAN_HDD_GET_HAL_CTX(pAdapter), TRUE);
2334
2335 pWextState->roamProfile.csrPersona = pAdapter->device_mode;
2336 (WLAN_HDD_GET_CTX(pAdapter))->isAmpAllowed = VOS_FALSE;
2337 status = sme_RoamConnect( hHal,pAdapter->sessionId, &(pWextState->roamProfile),&roamId);
2338 pRoamProfile->ChannelInfo.ChannelList = NULL;
2339 pRoamProfile->ChannelInfo.numOfChannels = 0;
2340
2341 EXIT();
2342 return status;
2343}
2344/**---------------------------------------------------------------------------
2345
2346 \brief iw_get_essid() -
2347 This function returns the essid to the wpa_supplicant.
2348
2349 \param - dev - Pointer to the net device.
2350 - info - Pointer to the iw_request_info.
2351 - wrqu - Pointer to the iwreq_data.
2352 - extra - Pointer to the data.
2353 \return - 0 for success, non zero for failure
2354
2355 --------------------------------------------------------------------------*/
2356int iw_get_essid(struct net_device *dev,
2357 struct iw_request_info *info,
2358 struct iw_point *dwrq, char *extra)
2359{
2360 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2361 hdd_wext_state_t *wextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2362 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2363 ENTER();
2364
2365 if((pHddStaCtx->conn_info.connState == eConnectionState_Associated &&
2366 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0) ||
2367 ((pHddStaCtx->conn_info.connState == eConnectionState_IbssConnected ||
2368 pHddStaCtx->conn_info.connState == eConnectionState_IbssDisconnected) &&
2369 wextBuf->roamProfile.SSIDs.SSIDList->SSID.length > 0))
2370 {
2371 dwrq->length = pHddStaCtx->conn_info.SSID.SSID.length;
2372 memcpy(extra, pHddStaCtx->conn_info.SSID.SSID.ssId, dwrq->length);
2373 dwrq->flags = 1;
2374 } else {
2375 memset(extra, 0, dwrq->length);
2376 dwrq->length = 0;
2377 dwrq->flags = 0;
2378 }
2379 EXIT();
2380 return 0;
2381}
2382/**---------------------------------------------------------------------------
2383
2384 \brief iw_set_auth() -
2385 This function sets the auth type received from the wpa_supplicant.
2386
2387 \param - dev - Pointer to the net device.
2388 - info - Pointer to the iw_request_info.
2389 - wrqu - Pointer to the iwreq_data.
2390 - extra - Pointer to the data.
2391 \return - 0 for success, non zero for failure
2392
2393 --------------------------------------------------------------------------*/
2394int iw_set_auth(struct net_device *dev,struct iw_request_info *info,
2395 union iwreq_data *wrqu,char *extra)
2396{
2397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2398 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2399 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2400 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2401 eCsrEncryptionType mcEncryptionType;
2402 eCsrEncryptionType ucEncryptionType;
2403
2404 ENTER();
2405 switch(wrqu->param.flags & IW_AUTH_INDEX)
2406 {
2407 case IW_AUTH_WPA_VERSION:
2408
2409 pWextState->wpaVersion = wrqu->param.value;
2410
2411 break;
2412
2413 case IW_AUTH_CIPHER_PAIRWISE:
2414 {
2415 if(wrqu->param.value & IW_AUTH_CIPHER_NONE) {
2416 ucEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
2417 }
2418 else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
2419 ucEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
2420 }
2421 else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
2422 ucEncryptionType = eCSR_ENCRYPT_TYPE_AES;
2423 }
2424
2425 else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
2426
2427 if( (IW_AUTH_KEY_MGMT_802_1X
2428 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) )
2429 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType) )
2430 /*Dynamic WEP key*/
2431 ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40;
2432 else
2433 /*Static WEP key*/
2434 ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2435 }
2436 else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104) {
2437
2438 if( ( IW_AUTH_KEY_MGMT_802_1X
2439 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X) )
2440 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
2441 /*Dynamic WEP key*/
2442 ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104;
2443 else
2444 /*Static WEP key*/
2445 ucEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2446
2447 }
2448 else {
2449
2450 hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER",
2451 __FUNCTION__, wrqu->param.value);
2452 return -EINVAL;
2453 }
2454
2455 pRoamProfile->EncryptionType.numEntries = 1;
2456 pRoamProfile->EncryptionType.encryptionType[0] = ucEncryptionType;
2457 }
2458 break;
2459 case IW_AUTH_CIPHER_GROUP:
2460 {
2461 if(wrqu->param.value & IW_AUTH_CIPHER_NONE) {
2462 mcEncryptionType = eCSR_ENCRYPT_TYPE_NONE;
2463 }
2464
2465 else if(wrqu->param.value & IW_AUTH_CIPHER_TKIP) {
2466 mcEncryptionType = eCSR_ENCRYPT_TYPE_TKIP;
2467 }
2468
2469 else if(wrqu->param.value & IW_AUTH_CIPHER_CCMP) {
2470 mcEncryptionType = eCSR_ENCRYPT_TYPE_AES;
2471 }
2472
2473 else if(wrqu->param.value & IW_AUTH_CIPHER_WEP40) {
2474
2475 if( ( IW_AUTH_KEY_MGMT_802_1X
2476 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
2477 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
2478
2479 mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40;
2480
2481 else
2482 mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
2483 }
2484
2485 else if(wrqu->param.value & IW_AUTH_CIPHER_WEP104)
2486 {
2487 /*Dynamic WEP keys won't work with shared keys*/
2488 if( ( IW_AUTH_KEY_MGMT_802_1X
2489 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
2490 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType))
2491 {
2492 mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104;
2493 }
2494 else
2495 {
2496 mcEncryptionType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
2497 }
2498 }
2499 else {
2500
2501 hddLog(LOGW, "%s value %d UNKNOWN IW_AUTH_CIPHER",
2502 __FUNCTION__, wrqu->param.value);
2503 return -EINVAL;
2504 }
2505
2506 pRoamProfile->mcEncryptionType.numEntries = 1;
2507 pRoamProfile->mcEncryptionType.encryptionType[0] = mcEncryptionType;
2508 }
2509 break;
2510
2511 case IW_AUTH_80211_AUTH_ALG:
2512 {
2513 /*Save the auth algo here and set auth type to SME Roam profile
2514 in the iw_set_ap_address*/
2515 if( wrqu->param.value & IW_AUTH_ALG_OPEN_SYSTEM)
2516 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2517
2518 else if(wrqu->param.value & IW_AUTH_ALG_SHARED_KEY)
2519 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
2520
2521 else if(wrqu->param.value & IW_AUTH_ALG_LEAP)
2522 /*Not supported*/
2523 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
2524 pWextState->roamProfile.AuthType.authType[0] = pHddStaCtx->conn_info.authType;
2525 }
2526 break;
2527
2528 case IW_AUTH_KEY_MGMT:
2529 {
2530#ifdef FEATURE_WLAN_CCX
2531#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
2532 /*Check for CCKM AKM type */
2533 if ( wrqu->param.value & IW_AUTH_KEY_MGMT_CCKM) {
2534 //hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"%s: CCKM AKM Set %d\n", __FUNCTION__, wrqu->param.value);
2535 hddLog(VOS_TRACE_LEVEL_INFO,"%s: CCKM AKM Set %d\n", __FUNCTION__, wrqu->param.value);
2536 /* Set the CCKM bit in authKeyMgmt */
2537 /* Right now, this breaks all ref to authKeyMgmt because our
2538 * code doesn't realize it is a "bitfield"
2539 */
2540 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
2541 /*Set the key management to 802.1X*/
2542 //pWextState->authKeyMgmt = IW_AUTH_KEY_MGMT_802_1X;
2543 pWextState->isCCXConnection = eANI_BOOLEAN_TRUE;
2544 //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA.
2545 pWextState->collectedAuthType = eCSR_AUTH_TYPE_CCKM_RSN;
2546 } else if ( wrqu->param.value & IW_AUTH_KEY_MGMT_PSK) {
2547 /*Save the key management*/
2548 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
2549 //pWextState->authKeyMgmt = wrqu->param.value;
2550 //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA.
2551 pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN;
2552 } else if (!( wrqu->param.value & IW_AUTH_KEY_MGMT_802_1X)) {
2553 pWextState->collectedAuthType = eCSR_AUTH_TYPE_NONE; //eCSR_AUTH_TYPE_WPA_NONE
2554 /*Save the key management anyway*/
2555 pWextState->authKeyMgmt = wrqu->param.value;
2556 } else { // It must be IW_AUTH_KEY_MGMT_802_1X
2557 /*Save the key management*/
2558 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
2559 //pWextState->authKeyMgmt = wrqu->param.value;
2560 //This is test code. I need to actually KNOW whether this is an RSN Assoc or WPA.
2561 pWextState->collectedAuthType = eCSR_AUTH_TYPE_RSN;
2562 }
2563#else
2564 /*Save the key management*/
2565 pWextState->authKeyMgmt = wrqu->param.value;
2566#endif /* FEATURE_WLAN_CCX */
2567 }
2568 break;
2569
2570 case IW_AUTH_TKIP_COUNTERMEASURES:
2571 {
2572 if(wrqu->param.value) {
2573 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2574 "Counter Measure started %d", wrqu->param.value);
2575 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STARTED;
2576 }
2577 else {
2578 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
2579 "Counter Measure stopped=%d", wrqu->param.value);
2580 pWextState->mTKIPCounterMeasures = TKIP_COUNTER_MEASURE_STOPED;
2581 }
2582 }
2583 break;
2584 case IW_AUTH_DROP_UNENCRYPTED:
2585 case IW_AUTH_WPA_ENABLED:
2586 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
2587 case IW_AUTH_ROAMING_CONTROL:
2588 case IW_AUTH_PRIVACY_INVOKED:
2589
2590 default:
2591
2592 hddLog(LOGW, "%s called with unsupported auth type %d", __FUNCTION__,
2593 wrqu->param.flags & IW_AUTH_INDEX);
2594 break;
2595 }
2596
2597 EXIT();
2598 return 0;
2599}
2600/**---------------------------------------------------------------------------
2601
2602 \brief iw_get_auth() -
2603 This function returns the auth type to the wpa_supplicant.
2604
2605 \param - dev - Pointer to the net device.
2606 - info - Pointer to the iw_request_info.
2607 - wrqu - Pointer to the iwreq_data.
2608 - extra - Pointer to the data.
2609 \return - 0 for success, non zero for failure
2610
2611 --------------------------------------------------------------------------*/
2612int iw_get_auth(struct net_device *dev,struct iw_request_info *info,
2613 union iwreq_data *wrqu,char *extra)
2614{
2615 hdd_adapter_t* pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2616 hdd_wext_state_t *pWextState= WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
2617 tCsrRoamProfile *pRoamProfile = &pWextState->roamProfile;
2618 ENTER();
2619 switch(pRoamProfile->negotiatedAuthType)
2620 {
2621 case eCSR_AUTH_TYPE_WPA_NONE:
2622 wrqu->param.flags = IW_AUTH_WPA_VERSION;
2623 wrqu->param.value = IW_AUTH_WPA_VERSION_DISABLED;
2624 break;
2625 case eCSR_AUTH_TYPE_WPA:
2626 wrqu->param.flags = IW_AUTH_WPA_VERSION;
2627 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA;
2628 break;
2629#ifdef WLAN_FEATURE_VOWIFI_11R
2630 case eCSR_AUTH_TYPE_FT_RSN:
2631#endif
2632 case eCSR_AUTH_TYPE_RSN:
2633 wrqu->param.flags = IW_AUTH_WPA_VERSION;
2634 wrqu->param.value = IW_AUTH_WPA_VERSION_WPA2;
2635 break;
2636 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
2637 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
2638 break;
2639 case eCSR_AUTH_TYPE_SHARED_KEY:
2640 wrqu->param.value = IW_AUTH_ALG_SHARED_KEY;
2641 break;
2642 case eCSR_AUTH_TYPE_UNKNOWN:
2643 hddLog(LOG1,"%s called with unknown auth type", __FUNCTION__);
2644 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
2645 break;
2646 case eCSR_AUTH_TYPE_AUTOSWITCH:
2647 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
2648 break;
2649 case eCSR_AUTH_TYPE_WPA_PSK:
2650 hddLog(LOG1,"%s called with unknown auth type", __FUNCTION__);
2651 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
2652 return -EIO;
2653#ifdef WLAN_FEATURE_VOWIFI_11R
2654 case eCSR_AUTH_TYPE_FT_RSN_PSK:
2655#endif
2656 case eCSR_AUTH_TYPE_RSN_PSK:
2657 hddLog(LOG1,"%s called with unknown auth type", __FUNCTION__);
2658 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
2659 return -EIO;
2660 default:
2661 hddLog(LOG1,"%s called with unknown auth type", __FUNCTION__);
2662 wrqu->param.value = IW_AUTH_ALG_OPEN_SYSTEM;
2663 return -EIO;
2664 }
2665 if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_PAIRWISE))
2666 {
2667 switch(pRoamProfile->negotiatedUCEncryptionType)
2668 {
2669 case eCSR_ENCRYPT_TYPE_NONE:
2670 wrqu->param.value = IW_AUTH_CIPHER_NONE;
2671 break;
2672 case eCSR_ENCRYPT_TYPE_WEP40:
2673 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
2674 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
2675 break;
2676 case eCSR_ENCRYPT_TYPE_TKIP:
2677 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
2678 break;
2679 case eCSR_ENCRYPT_TYPE_WEP104:
2680 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
2681 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
2682 break;
2683 case eCSR_ENCRYPT_TYPE_AES:
2684 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
2685 break;
2686 default:
2687 hddLog(LOG1, "%s called with unknown auth type", __FUNCTION__);
2688 return -EIO;
2689 }
2690 }
2691
2692 if(((wrqu->param.flags & IW_AUTH_INDEX) == IW_AUTH_CIPHER_GROUP))
2693 {
2694 switch(pRoamProfile->negotiatedMCEncryptionType)
2695 {
2696 case eCSR_ENCRYPT_TYPE_NONE:
2697 wrqu->param.value = IW_AUTH_CIPHER_NONE;
2698 break;
2699 case eCSR_ENCRYPT_TYPE_WEP40:
2700 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
2701 wrqu->param.value = IW_AUTH_CIPHER_WEP40;
2702 break;
2703 case eCSR_ENCRYPT_TYPE_TKIP:
2704 wrqu->param.value = IW_AUTH_CIPHER_TKIP;
2705 break;
2706 case eCSR_ENCRYPT_TYPE_WEP104:
2707 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
2708 wrqu->param.value = IW_AUTH_CIPHER_WEP104;
2709 break;
2710 case eCSR_ENCRYPT_TYPE_AES:
2711 wrqu->param.value = IW_AUTH_CIPHER_CCMP;
2712 break;
2713 default:
2714 hddLog(LOG1, "%s called with unknown auth type", __FUNCTION__);
2715 return -EIO;
2716 }
2717 }
2718
2719 hddLog(LOG1, "%s called with auth type %d",
2720 __FUNCTION__, pRoamProfile->AuthType.authType[0]);
2721 EXIT();
2722 return 0;
2723}
2724/**---------------------------------------------------------------------------
2725
2726 \brief iw_set_ap_address() -
2727 This function calls the sme_RoamConnect function to associate
2728 to the AP with the specified BSSID received from the wpa_supplicant.
2729
2730 \param - dev - Pointer to the net device.
2731 - info - Pointer to the iw_request_info.
2732 - wrqu - Pointer to the iwreq_data.
2733 - extra - Pointer to the data.
2734 \return - 0 for success, non zero for failure
2735
2736 --------------------------------------------------------------------------*/
2737int iw_set_ap_address(struct net_device *dev,
2738 struct iw_request_info *info,
2739 union iwreq_data *wrqu, char *extra)
2740{
2741 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
2742 v_U8_t *pMacAddress=NULL;
2743 ENTER();
2744 pMacAddress = (v_U8_t*) wrqu->ap_addr.sa_data;
2745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%02x:%02x:%02x:%02x:%02x:%02x",pMacAddress[0],pMacAddress[1],
2746 pMacAddress[2],pMacAddress[3],pMacAddress[4],pMacAddress[5]);
2747 vos_mem_copy( pHddStaCtx->conn_info.bssId, pMacAddress, sizeof( tCsrBssid ));
2748 EXIT();
2749
2750 return 0;
2751}
2752/**---------------------------------------------------------------------------
2753
2754 \brief iw_get_ap_address() -
2755 This function returns the BSSID to the wpa_supplicant
2756 \param - dev - Pointer to the net device.
2757 - info - Pointer to the iw_request_info.
2758 - wrqu - Pointer to the iwreq_data.
2759 - extra - Pointer to the data.
2760 \return - 0 for success, non zero for failure
2761
2762 --------------------------------------------------------------------------*/
2763int iw_get_ap_address(struct net_device *dev,
2764 struct iw_request_info *info,
2765 union iwreq_data *wrqu, char *extra)
2766{
2767 //hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2768 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(WLAN_HDD_GET_PRIV_PTR(dev));
2769
2770 ENTER();
2771
2772 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
2773 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
2774 {
2775 memcpy(wrqu->ap_addr.sa_data,pHddStaCtx->conn_info.bssId,sizeof(wrqu->ap_addr.sa_data));
2776 }
2777 else
2778 {
2779 memset(wrqu->ap_addr.sa_data,0,sizeof(wrqu->ap_addr.sa_data));
2780 }
2781 EXIT();
2782 return 0;
2783}
Jeff Johnsond13512a2012-07-17 11:42:19 -07002784
2785
2786/**---------------------------------------------------------------------------
2787
2788 \brief hdd_ResetCountryCodeAfterDisAssoc -
2789 This function reset the country code to default
2790 \param - pAdapter - Pointer to HDD adaptor
2791 \return - nothing
2792
2793 --------------------------------------------------------------------------*/
2794void hdd_ResetCountryCodeAfterDisAssoc(hdd_adapter_t *pAdapter)
2795{
2796 hdd_context_t* pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
2797 tSmeConfigParams smeConfig;
2798 eHalStatus status = eHAL_STATUS_SUCCESS;
2799 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
2800 tANI_U8 currentCountryCode[3] = SME_INVALID_COUNTRY_CODE;
2801
2802 sme_GetConfigParam(pHddCtx->hHal, &smeConfig);
2803
2804 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2805 "%s: 11d is %s\n",__func__,
2806 smeConfig.csrConfig.Is11dSupportEnabled ? "Enabled" : "Disabled");
2807 /* Reset country code only when 11d is enabled
2808 */
2809 if (smeConfig.csrConfig.Is11dSupportEnabled)
2810 {
2811 sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal, &defaultCountryCode[0]);
2812 sme_GetCurrentCountryCode(pHddCtx->hHal, &currentCountryCode[0]);
2813
2814 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2815 "%s: Default country code: %c%c%c, Current Country code: %c%c%c \n",
2816 __func__,
2817 defaultCountryCode[0], defaultCountryCode[1], defaultCountryCode[2],
2818 currentCountryCode[0], currentCountryCode[1], currentCountryCode[2]);
2819 /* Reset country code only when there is a mismatch
2820 * between current country code and default country code
2821 */
2822 if ((defaultCountryCode[0] != currentCountryCode[0]) ||
2823 (defaultCountryCode[1] != currentCountryCode[1]) ||
2824 (defaultCountryCode[2] != currentCountryCode[2]))
2825 {
2826 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
2827 "%s: Disconnected from the AP/Assoc failed and "
2828 "resetting the country code to default\n",__func__);
2829 /*reset the country code of previous connection*/
2830 status = (int)sme_ChangeCountryCode(pHddCtx->hHal, NULL,
2831 &defaultCountryCode[0], pAdapter,
2832 pHddCtx->pvosContext
2833 );
2834 if( 0 != status )
2835 {
2836 VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2837 "%s: failed to Reset the Country Code\n",__func__);
2838 }
2839 }
2840 }
2841}
2842