blob: eea8cbd2fb27c350cc61c46b0ebeed120c0cfddf [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
2 * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/** ------------------------------------------------------------------------- *
29 ------------------------------------------------------------------------- *
30
31 \file csr_util.c
32
33 Implementation supporting routines for CSR.
34 ========================================================================== */
35
36#include "ani_global.h"
37
38#include "csr_support.h"
39#include "csr_inside_api.h"
40#include "sms_debug.h"
41#include "sme_qos_internal.h"
42#include "wma_types.h"
43#include "cds_utils.h"
44
45
46uint8_t csr_wpa_oui[][CSR_WPA_OUI_SIZE] = {
47 {0x00, 0x50, 0xf2, 0x00}
48 ,
49 {0x00, 0x50, 0xf2, 0x01}
50 ,
51 {0x00, 0x50, 0xf2, 0x02}
52 ,
53 {0x00, 0x50, 0xf2, 0x03}
54 ,
55 {0x00, 0x50, 0xf2, 0x04}
56 ,
57 {0x00, 0x50, 0xf2, 0x05}
58 ,
59#ifdef FEATURE_WLAN_ESE
60 {0x00, 0x40, 0x96, 0x00}
61 , /* CCKM */
62#endif /* FEATURE_WLAN_ESE */
63};
64
65uint8_t csr_rsn_oui[][CSR_RSN_OUI_SIZE] = {
66 {0x00, 0x0F, 0xAC, 0x00}
67 , /* group cipher */
68 {0x00, 0x0F, 0xAC, 0x01}
69 , /* WEP-40 or RSN */
70 {0x00, 0x0F, 0xAC, 0x02}
71 , /* TKIP or RSN-PSK */
72 {0x00, 0x0F, 0xAC, 0x03}
73 , /* Reserved */
74 {0x00, 0x0F, 0xAC, 0x04}
75 , /* AES-CCMP */
76 {0x00, 0x0F, 0xAC, 0x05}
77 , /* WEP-104 */
78 {0x00, 0x40, 0x96, 0x00}
79 , /* CCKM */
80 {0x00, 0x0F, 0xAC, 0x06}
81 , /* BIP (encryption type) or
82 RSN-PSK-SHA256 (authentication type) */
83 /* RSN-8021X-SHA256 (authentication type) */
84 {0x00, 0x0F, 0xAC, 0x05}
85};
86
87#ifdef FEATURE_WLAN_WAPI
88uint8_t csr_wapi_oui[][CSR_WAPI_OUI_SIZE] = {
89 {0x00, 0x14, 0x72, 0x00}
90 , /* Reserved */
91 {0x00, 0x14, 0x72, 0x01}
92 , /* WAI certificate or SMS4 */
93 {0x00, 0x14, 0x72, 0x02} /* WAI PSK */
94};
95#endif /* FEATURE_WLAN_WAPI */
96uint8_t csr_wme_info_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
97uint8_t csr_wme_parm_oui[CSR_WME_OUI_SIZE] = { 0x00, 0x50, 0xf2, 0x02 };
98
99
100/* ////////////////////////////////////////////////////////////////////// */
101
102/**
103 * \var g_phy_rates_suppt
104 *
105 * \brief Rate support lookup table
106 *
107 *
108 * This is a lookup table indexing rates & configuration parameters to
109 * support. Given a rate (in unites of 0.5Mpbs) & three bools (MIMO
110 * Enabled, Channel Bonding Enabled, & Concatenation Enabled), one can
111 * determine whether the given rate is supported by computing two
112 * indices. The first maps the rate to table row as indicated below
113 * (i.e. eHddSuppRate_6Mbps maps to row zero, eHddSuppRate_9Mbps to row
114 * 1, and so on). Index two can be computed like so:
115 *
116 * \code
117 * idx2 = ( fEsf ? 0x4 : 0x0 ) |
118 * ( fCb ? 0x2 : 0x0 ) |
119 * ( fMimo ? 0x1 : 0x0 );
120 * \endcode
121 *
122 *
123 * Given that:
124 *
125 * \code
126 * fSupported = g_phy_rates_suppt[idx1][idx2];
127 * \endcode
128 *
129 *
130 * This table is based on the document "PHY Supported Rates.doc". This
131 * table is permissive in that a rate is reflected as being supported
132 * even when turning off an enabled feature would be required. For
133 * instance, "PHY Supported Rates" lists 42Mpbs as unsupported when CB,
134 * ESF, & MIMO are all on. However, if we turn off either of CB or
135 * MIMO, it then becomes supported. Therefore, we mark it as supported
136 * even in index 7 of this table.
137 *
138 *
139 */
140
141static const bool g_phy_rates_suppt[24][8] = {
142
143 /* SSF SSF SSF SSF ESF ESF ESF ESF */
144 /* SIMO MIMO SIMO MIMO SIMO MIMO SIMO MIMO */
145 /* No CB No CB CB CB No CB No CB CB CB */
146 {true, true, true, true, true, true, true, true}, /* 6Mbps */
147 {true, true, true, true, true, true, true, true}, /* 9Mbps */
148 {true, true, true, true, true, true, true, true}, /* 12Mbps */
149 {true, true, true, true, true, true, true, true}, /* 18Mbps */
150 {false, false, true, true, false, false, true, true}, /* 20Mbps */
151 {true, true, true, true, true, true, true, true}, /* 24Mbps */
152 {true, true, true, true, true, true, true, true}, /* 36Mbps */
153 {false, false, true, true, false, true, true, true}, /* 40Mbps */
154 {false, false, true, true, false, true, true, true}, /* 42Mbps */
155 {true, true, true, true, true, true, true, true}, /* 48Mbps */
156 {true, true, true, true, true, true, true, true}, /* 54Mbps */
157 {false, true, true, true, false, true, true, true}, /* 72Mbps */
158 {false, false, true, true, false, true, true, true}, /* 80Mbps */
159 {false, false, true, true, false, true, true, true}, /* 84Mbps */
160 {false, true, true, true, false, true, true, true}, /* 96Mbps */
161 {false, true, true, true, false, true, true, true}, /* 108Mbps */
162 {false, false, true, true, false, true, true, true}, /* 120Mbps */
163 {false, false, true, true, false, true, true, true}, /* 126Mbps */
164 {false, false, false, true, false, false, false, true}, /* 144Mbps */
165 {false, false, false, true, false, false, false, true}, /* 160Mbps */
166 {false, false, false, true, false, false, false, true}, /* 168Mbps */
167 {false, false, false, true, false, false, false, true}, /* 192Mbps */
168 {false, false, false, true, false, false, false, true}, /* 216Mbps */
169 {false, false, false, true, false, false, false, true}, /* 240Mbps */
170
171};
172
173#define CASE_RETURN_STR(n) {\
174 case (n): return (# n);\
175}
176
177const char *get_e_roam_cmd_status_str(eRoamCmdStatus val)
178{
179 switch (val) {
180 CASE_RETURN_STR(eCSR_ROAM_CANCELLED);
181 CASE_RETURN_STR(eCSR_ROAM_ROAMING_START);
182 CASE_RETURN_STR(eCSR_ROAM_ROAMING_COMPLETION);
183 CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_START);
184 CASE_RETURN_STR(eCSR_ROAM_ASSOCIATION_COMPLETION);
185 CASE_RETURN_STR(eCSR_ROAM_DISASSOCIATED);
186 CASE_RETURN_STR(eCSR_ROAM_SHOULD_ROAM);
187 CASE_RETURN_STR(eCSR_ROAM_SCAN_FOUND_NEW_BSS);
188 CASE_RETURN_STR(eCSR_ROAM_LOSTLINK);
189 default:
190 return "unknown";
191 }
192}
193
194const char *get_e_csr_roam_result_str(eCsrRoamResult val)
195{
196 switch (val) {
197 CASE_RETURN_STR(eCSR_ROAM_RESULT_NONE);
198 CASE_RETURN_STR(eCSR_ROAM_RESULT_FAILURE);
199 CASE_RETURN_STR(eCSR_ROAM_RESULT_ASSOCIATED);
200 CASE_RETURN_STR(eCSR_ROAM_RESULT_NOT_ASSOCIATED);
201 CASE_RETURN_STR(eCSR_ROAM_RESULT_MIC_FAILURE);
202 CASE_RETURN_STR(eCSR_ROAM_RESULT_FORCED);
203 CASE_RETURN_STR(eCSR_ROAM_RESULT_DISASSOC_IND);
204 CASE_RETURN_STR(eCSR_ROAM_RESULT_DEAUTH_IND);
205 CASE_RETURN_STR(eCSR_ROAM_RESULT_CAP_CHANGED);
206 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_CONNECT);
207 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_INACTIVE);
208 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_NEW_PEER);
209 CASE_RETURN_STR(eCSR_ROAM_RESULT_IBSS_COALESCED);
210 default:
211 return "unknown";
212 }
213}
214
215bool csr_get_bss_id_bss_desc(tHalHandle hHal, tSirBssDescription *pSirBssDesc,
216 struct cdf_mac_addr *pBssId)
217{
218 cdf_mem_copy(pBssId, &pSirBssDesc->bssId[0],
219 sizeof(struct cdf_mac_addr));
220 return true;
221}
222
223bool csr_is_bss_id_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1,
224 tSirBssDescription *pSirBssDesc2)
225{
226 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
227 bool fEqual = false;
228 struct cdf_mac_addr bssId1;
229 struct cdf_mac_addr bssId2;
230
231 do {
232 if (!pSirBssDesc1)
233 break;
234 if (!pSirBssDesc2)
235 break;
236
237 if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc1, &bssId1))
238 break;
239 if (!csr_get_bss_id_bss_desc(pMac, pSirBssDesc2, &bssId2))
240 break;
241
242 fEqual = cdf_is_macaddr_equal(&bssId1, &bssId2);
243 } while (0);
244
245 return fEqual;
246}
247
248bool csr_is_conn_state_connected_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
249{
250 return eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED ==
251 pMac->roam.roamSession[sessionId].connectState;
252}
253
254bool csr_is_conn_state_disconnected_ibss(tpAniSirGlobal pMac,
255 uint32_t sessionId)
256{
257 return eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED ==
258 pMac->roam.roamSession[sessionId].connectState;
259}
260
261bool csr_is_conn_state_connected_infra(tpAniSirGlobal pMac, uint32_t sessionId)
262{
263 return eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
264 pMac->roam.roamSession[sessionId].connectState;
265}
266
267bool csr_is_conn_state_connected(tpAniSirGlobal pMac, uint32_t sessionId)
268{
269 if (csr_is_conn_state_connected_ibss(pMac, sessionId)
270 || csr_is_conn_state_connected_infra(pMac, sessionId)
271 || csr_is_conn_state_connected_wds(pMac, sessionId))
272 return true;
273 else
274 return false;
275}
276
277bool csr_is_conn_state_infra(tpAniSirGlobal pMac, uint32_t sessionId)
278{
279 return csr_is_conn_state_connected_infra(pMac, sessionId);
280}
281
282bool csr_is_conn_state_ibss(tpAniSirGlobal pMac, uint32_t sessionId)
283{
284 return csr_is_conn_state_connected_ibss(pMac, sessionId) ||
285 csr_is_conn_state_disconnected_ibss(pMac, sessionId);
286}
287
288bool csr_is_conn_state_connected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
289{
290 return eCSR_ASSOC_STATE_TYPE_WDS_CONNECTED ==
291 pMac->roam.roamSession[sessionId].connectState;
292}
293
294bool csr_is_conn_state_connected_infra_ap(tpAniSirGlobal pMac,
295 uint32_t sessionId)
296{
297 return (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
298 pMac->roam.roamSession[sessionId].connectState) ||
299 (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
300 pMac->roam.roamSession[sessionId].connectState);
301}
302
303bool csr_is_conn_state_disconnected_wds(tpAniSirGlobal pMac, uint32_t sessionId)
304{
305 return eCSR_ASSOC_STATE_TYPE_WDS_DISCONNECTED ==
306 pMac->roam.roamSession[sessionId].connectState;
307}
308
309bool csr_is_conn_state_wds(tpAniSirGlobal pMac, uint32_t sessionId)
310{
311 return csr_is_conn_state_connected_wds(pMac, sessionId) ||
312 csr_is_conn_state_disconnected_wds(pMac, sessionId);
313}
314
315bool csr_is_conn_state_ap(tpAniSirGlobal pMac, uint32_t sessionId)
316{
317 tCsrRoamSession *pSession;
318 pSession = CSR_GET_SESSION(pMac, sessionId);
319 if (!pSession)
320 return false;
321 if (CSR_IS_INFRA_AP(&pSession->connectedProfile))
322 return true;
323 return false;
324}
325
326bool csr_is_any_session_in_connect_state(tpAniSirGlobal pMac)
327{
328 uint32_t i;
329 bool fRc = false;
330
331 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
332 if (CSR_IS_SESSION_VALID(pMac, i) &&
333 (csr_is_conn_state_infra(pMac, i)
334 || csr_is_conn_state_ibss(pMac, i)
335 || csr_is_conn_state_ap(pMac, i))) {
336 fRc = true;
337 break;
338 }
339 }
340
341 return fRc;
342}
343
344int8_t csr_get_infra_session_id(tpAniSirGlobal pMac)
345{
346 uint8_t i;
347 int8_t sessionid = -1;
348
349 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
350 if (CSR_IS_SESSION_VALID(pMac, i)
351 && csr_is_conn_state_infra(pMac, i)) {
352 sessionid = i;
353 break;
354 }
355 }
356
357 return sessionid;
358}
359
360uint8_t csr_get_infra_operation_channel(tpAniSirGlobal pMac, uint8_t sessionId)
361{
362 uint8_t channel;
363
364 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
365 channel =
366 pMac->roam.roamSession[sessionId].connectedProfile.
367 operationChannel;
368 } else {
369 channel = 0;
370 }
371 return channel;
372}
373
374bool csr_is_session_client_and_connected(tpAniSirGlobal pMac, uint8_t sessionId)
375{
376 tCsrRoamSession *pSession = NULL;
377 if (CSR_IS_SESSION_VALID(pMac, sessionId)
378 && csr_is_conn_state_infra(pMac, sessionId)) {
379 pSession = CSR_GET_SESSION(pMac, sessionId);
380 if (NULL != pSession->pCurRoamProfile) {
381 if ((pSession->pCurRoamProfile->csrPersona ==
382 CDF_STA_MODE)
383 || (pSession->pCurRoamProfile->csrPersona ==
384 CDF_P2P_CLIENT_MODE))
385 return true;
386 }
387 }
388 return false;
389}
390
391/**
392 * csr_get_concurrent_operation_channel() - To get concurrent operating channel
393 * @mac_ctx: Pointer to mac context
394 *
395 * This routine will return operating channel on FIRST BSS that is
396 * active/operating to be used for concurrency mode.
397 * If other BSS is not up or not connected it will return 0
398 *
399 * Return: uint8_t
400 */
401uint8_t csr_get_concurrent_operation_channel(tpAniSirGlobal mac_ctx)
402{
403 tCsrRoamSession *session = NULL;
404 uint8_t i = 0;
405 tCDF_CON_MODE persona;
406
407 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
408 if (!CSR_IS_SESSION_VALID(mac_ctx, i))
409 continue;
410 session = CSR_GET_SESSION(mac_ctx, i);
411 if (NULL == session->pCurRoamProfile)
412 continue;
413 persona = session->pCurRoamProfile->csrPersona;
414 if ((((persona == CDF_STA_MODE) ||
415 (persona == CDF_P2P_CLIENT_MODE)) &&
416 (session->connectState ==
417 eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) ||
418 (((persona == CDF_P2P_GO_MODE) ||
419 (persona == CDF_SAP_MODE))
420 && (session->connectState !=
421 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)))
422 return session->connectedProfile.operationChannel;
423
424 }
425 return 0;
426}
427
428#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
429
430#define HALF_BW_OF(eCSR_bw_val) ((eCSR_bw_val)/2)
431
432/* calculation of center channel based on V/HT BW and WIFI channel bw=5MHz) */
433
434#define CSR_GET_HT40_PLUS_CCH(och) ((och)+2)
435#define CSR_GET_HT40_MINUS_CCH(och) ((och)-2)
436
437#define CSR_GET_HT80_PLUS_LL_CCH(och) ((och)+6)
438#define CSR_GET_HT80_PLUS_HL_CCH(och) ((och)+2)
439#define CSR_GET_HT80_MINUS_LH_CCH(och) ((och)-2)
440#define CSR_GET_HT80_MINUS_HH_CCH(och) ((och)-6)
441
442/**
443 * csr_get_ch_from_ht_profile() - to get channel from HT profile
444 * @pMac: pointer to Mac context
445 * @htp: pointer to HT profile
446 * @och: operating channel
447 * @cfreq: channel frequency
448 * @hbw: half bandwidth
449 *
450 * This function will fill half bandwidth and channel frequency based
451 * on the HT profile
452 *
453 * Return: none
454 */
455void csr_get_ch_from_ht_profile(tpAniSirGlobal pMac, tCsrRoamHTProfile *htp,
456 uint16_t och, uint16_t *cfreq, uint16_t *hbw)
457{
458 uint16_t cch, ch_bond;
459
460 if (och > 14)
461 ch_bond = pMac->roam.configParam.channelBondingMode5GHz;
462 else
463 ch_bond = pMac->roam.configParam.channelBondingMode24GHz;
464
465 cch = och;
466 *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
467
468 if (!ch_bond)
469 goto ret;
470
471 sms_log(pMac, LOG1, FL("##HTC: %d scbw: %d rcbw: %d sco: %d"
472#ifdef WLAN_FEATURE_11AC
473 "VHTC: %d apc: %d apbw: %d"
474#endif
475 ),
476 htp->htCapability, htp->htSupportedChannelWidthSet,
477 htp->htRecommendedTxWidthSet,
478 htp->htSecondaryChannelOffset,
479#ifdef WLAN_FEATURE_11AC
480 htp->vhtCapability, htp->apCenterChan, htp->apChanWidth
481#endif
482 );
483
484#ifdef WLAN_FEATURE_11AC
485 if (htp->vhtCapability) {
486 cch = htp->apCenterChan;
487 if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ)
488 *hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
489 else if (htp->apChanWidth == WNI_CFG_VHT_CHANNEL_WIDTH_160MHZ)
490 *hbw = HALF_BW_OF(eCSR_BW_160MHz_VAL);
491
492 if (!*hbw && htp->htCapability) {
493 if (htp->htSupportedChannelWidthSet ==
494 eHT_CHANNEL_WIDTH_40MHZ)
495 *hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
496 else
497 *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
498 }
499 } else
500#endif
501 if (htp->htCapability) {
502 if (htp->htSupportedChannelWidthSet ==
503 eHT_CHANNEL_WIDTH_40MHZ) {
504 *hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
505 if (htp->htSecondaryChannelOffset ==
506 PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
507 cch = CSR_GET_HT40_PLUS_CCH(och);
508 else if (htp->htSecondaryChannelOffset ==
509 PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
510 cch = CSR_GET_HT40_MINUS_CCH(och);
511 } else {
512 cch = och;
513 *hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
514 }
515 }
516
517ret:
518 *cfreq = cds_chan_to_freq(cch);
519 return;
520}
521
522/**
523 * csr_calc_chb_for_sap_phymode() - to calc channel bandwidth for sap phymode
524 * @mac_ctx: pointer to mac context
525 * @sap_ch: SAP operating channel
526 * @sap_phymode: SAP physical mode
527 * @sap_cch: concurrency channel
528 * @sap_hbw: SAP half bw
529 * @chb: channel bandwidth
530 *
531 * This routine is called to calculate channel bandwidth
532 *
533 * Return: none
534 */
535static void csr_calc_chb_for_sap_phymode(tpAniSirGlobal mac_ctx,
536 uint16_t *sap_ch, eCsrPhyMode *sap_phymode,
537 uint16_t *sap_cch, uint16_t *sap_hbw, uint8_t *chb)
538{
539 if (*sap_phymode == eCSR_DOT11_MODE_11n ||
540 *sap_phymode == eCSR_DOT11_MODE_11n_ONLY) {
541
542 *sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
543 if (*chb == PHY_DOUBLE_CHANNEL_LOW_PRIMARY)
544 *sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
545 else if (*chb == PHY_DOUBLE_CHANNEL_HIGH_PRIMARY)
546 *sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
547
548 }
549#ifdef WLAN_FEATURE_11AC
550 else if (*sap_phymode == eCSR_DOT11_MODE_11ac ||
551 *sap_phymode == eCSR_DOT11_MODE_11ac_ONLY) {
552 /*11AC only 80/40/20 Mhz supported in Rome */
553 if (mac_ctx->roam.configParam.nVhtChannelWidth ==
554 (WNI_CFG_VHT_CHANNEL_WIDTH_80MHZ + 1)) {
555 *sap_hbw = HALF_BW_OF(eCSR_BW_80MHz_VAL);
556 if (*chb ==
557 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW - 1))
558 *sap_cch = CSR_GET_HT80_PLUS_LL_CCH(*sap_ch);
559 else if (*chb ==
560 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
561 - 1))
562 *sap_cch = CSR_GET_HT80_PLUS_HL_CCH(*sap_ch);
563 else if (*chb ==
564 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
565 - 1))
566 *sap_cch = CSR_GET_HT80_MINUS_LH_CCH(*sap_ch);
567 else if (*chb ==
568 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
569 - 1))
570 *sap_cch = CSR_GET_HT80_MINUS_HH_CCH(*sap_ch);
571 } else {
572 *sap_hbw = HALF_BW_OF(eCSR_BW_40MHz_VAL);
573 if (*chb == (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_LOW
574 - 1))
575 *sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
576 else if (*chb ==
577 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_LOW
578 - 1))
579 *sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
580 else if (*chb ==
581 (PHY_QUADRUPLE_CHANNEL_20MHZ_LOW_40MHZ_HIGH
582 - 1))
583 *sap_cch = CSR_GET_HT40_PLUS_CCH(*sap_ch);
584 else if (*chb ==
585 (PHY_QUADRUPLE_CHANNEL_20MHZ_HIGH_40MHZ_HIGH
586 - 1))
587 *sap_cch = CSR_GET_HT40_MINUS_CCH(*sap_ch);
588 }
589 }
590#endif
591}
592
593/**
594 * csr_handle_conc_chnl_overlap_for_sap_go - To handle overlap for AP+AP
595 * @mac_ctx: pointer to mac context
596 * @session: Current session
597 * @sap_ch: SAP/GO operating channel
598 * @sap_hbw: SAP/GO half bw
599 * @sap_cfreq: SAP/GO channel frequency
600 * @intf_ch: concurrent SAP/GO operating channel
601 * @intf_hbw: concurrent SAP/GO half bw
602 * @intf_cfreq: concurrent SAP/GO channel frequency
603 *
604 * This routine is called to check if one SAP/GO channel is overlapping with
605 * other SAP/GO channel
606 *
607 * Return: none
608 */
609static void csr_handle_conc_chnl_overlap_for_sap_go(tpAniSirGlobal mac_ctx,
610 tCsrRoamSession *session,
611 uint16_t *sap_ch, uint16_t *sap_hbw, uint16_t *sap_cfreq,
612 uint16_t *intf_ch, uint16_t *intf_hbw, uint16_t *intf_cfreq)
613{
614 /*
615 * if conc_custom_rule1 is defined then we don't
616 * want p2pgo to follow SAP's channel or SAP to
617 * follow P2PGO's channel.
618 */
619 if (0 == mac_ctx->roam.configParam.conc_custom_rule1 &&
620 0 == mac_ctx->roam.configParam.conc_custom_rule2) {
621 if (*sap_ch == 0) {
622 *sap_ch = session->connectedProfile.operationChannel;
623 csr_get_ch_from_ht_profile(mac_ctx,
624 &session->connectedProfile.HTProfile,
625 *sap_ch, sap_cfreq, sap_hbw);
626 } else if (*sap_ch !=
627 session->connectedProfile.operationChannel) {
628 *intf_ch = session->connectedProfile.operationChannel;
629 csr_get_ch_from_ht_profile(mac_ctx,
630 &session->connectedProfile.HTProfile,
631 *intf_ch, intf_cfreq, intf_hbw);
632 }
633 } else if (*sap_ch == 0 &&
634 (session->pCurRoamProfile->csrPersona ==
635 CDF_SAP_MODE)) {
636 *sap_ch = session->connectedProfile.operationChannel;
637 csr_get_ch_from_ht_profile(mac_ctx,
638 &session->connectedProfile.HTProfile,
639 *sap_ch, sap_cfreq, sap_hbw);
640 }
641}
642
643
644/**
645 * csr_check_concurrent_channel_overlap() - To check concurrent overlap chnls
646 * @mac_ctx: Pointer to mac context
647 * @sap_ch: SAP channel
648 * @sap_phymode: SAP phy mode
649 * @cc_switch_mode: concurrent switch mode
650 *
651 * This routine will be called to check concurrent overlap channels
652 *
653 * Return: uint16_t
654 */
655uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx,
656 uint16_t sap_ch, eCsrPhyMode sap_phymode,
657 uint8_t cc_switch_mode)
658{
659 tCsrRoamSession *session = NULL;
660 uint8_t i = 0, chb = PHY_SINGLE_CHANNEL_CENTERED;
661 uint16_t intf_ch = 0, sap_hbw = 0, intf_hbw = 0, intf_cfreq = 0;
662 uint16_t sap_cfreq = 0;
663 uint16_t sap_lfreq, sap_hfreq, intf_lfreq, intf_hfreq, sap_cch;
664
665 if (mac_ctx->roam.configParam.cc_switch_mode ==
666 CDF_MCC_TO_SCC_SWITCH_DISABLE)
667 return 0;
668
669 if (sap_ch != 0) {
670 sap_cch = sap_ch;
671 sap_hbw = HALF_BW_OF(eCSR_BW_20MHz_VAL);
672
673 if (sap_ch > 14)
674 chb = mac_ctx->roam.configParam.channelBondingMode5GHz;
675 else
676 chb = mac_ctx->roam.configParam.channelBondingMode24GHz;
677
678 if (chb)
679 csr_calc_chb_for_sap_phymode(mac_ctx, &sap_ch,
680 &sap_phymode, &sap_cch, &sap_hbw, &chb);
681 sap_cfreq = cds_chan_to_freq(sap_cch);
682 }
683
684 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
685 if (!CSR_IS_SESSION_VALID(mac_ctx, i))
686 continue;
687
688 session = CSR_GET_SESSION(mac_ctx, i);
689 if (NULL == session->pCurRoamProfile)
690 continue;
691 if (((session->pCurRoamProfile->csrPersona == CDF_STA_MODE) ||
692 (session->pCurRoamProfile->csrPersona ==
693 CDF_P2P_CLIENT_MODE)) &&
694 (session->connectState ==
695 eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED)) {
696 intf_ch = session->connectedProfile.operationChannel;
697 csr_get_ch_from_ht_profile(mac_ctx,
698 &session->connectedProfile.HTProfile,
699 intf_ch, &intf_cfreq, &intf_hbw);
700 } else if (((session->pCurRoamProfile->csrPersona ==
701 CDF_P2P_GO_MODE) ||
702 (session->pCurRoamProfile->csrPersona ==
703 CDF_SAP_MODE)) &&
704 (session->connectState !=
705 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
706 csr_handle_conc_chnl_overlap_for_sap_go(mac_ctx,
707 session, &sap_ch, &sap_hbw, &sap_cfreq,
708 &intf_ch, &intf_hbw, &intf_cfreq);
709 }
710 }
711
712 if (intf_ch && sap_ch != intf_ch &&
713 cc_switch_mode != CDF_MCC_TO_SCC_SWITCH_FORCE) {
714 sap_lfreq = sap_cfreq - sap_hbw;
715 sap_hfreq = sap_cfreq + sap_hbw;
716 intf_lfreq = intf_cfreq - intf_hbw;
717 intf_hfreq = intf_cfreq + intf_hbw;
718
719 sms_log(mac_ctx, LOGE,
720 FL("\nSAP: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d\n"
721 "INTF: OCH: %03d OCF: %d CCH: %03d CF: %d BW: %d LF: %d HF: %d"),
722 sap_ch, cds_chan_to_freq(sap_ch),
723 cds_freq_to_chan(sap_cfreq), sap_cfreq, sap_hbw * 2,
724 sap_lfreq, sap_hfreq, intf_ch,
725 cds_chan_to_freq(intf_ch), cds_freq_to_chan(intf_cfreq),
726 intf_cfreq, intf_hbw * 2, intf_lfreq, intf_hfreq);
727
728 if (!(((sap_lfreq > intf_lfreq && sap_lfreq < intf_hfreq) ||
729 (sap_hfreq > intf_lfreq && sap_hfreq < intf_hfreq)) ||
730 ((intf_lfreq > sap_lfreq && intf_lfreq < sap_hfreq) ||
731 (intf_hfreq > sap_lfreq && intf_hfreq < sap_hfreq))))
732 intf_ch = 0;
733 } else if (intf_ch && sap_ch != intf_ch &&
734 cc_switch_mode == CDF_MCC_TO_SCC_SWITCH_FORCE) {
735 if (!((intf_ch < 14 && sap_ch < 14) ||
736 (intf_ch > 14 && sap_ch > 14)))
737 intf_ch = 0;
738 } else if (intf_ch == sap_ch) {
739 intf_ch = 0;
740 }
741
742 sms_log(mac_ctx, LOGE, FL("##Concurrent Channels %s Interfering"),
743 intf_ch == 0 ? "Not" : "Are");
744 return intf_ch;
745}
746#endif
747
748bool csr_is_all_session_disconnected(tpAniSirGlobal pMac)
749{
750 uint32_t i;
751 bool fRc = true;
752
753 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
754 if (CSR_IS_SESSION_VALID(pMac, i)
755 && !csr_is_conn_state_disconnected(pMac, i)) {
756 fRc = false;
757 break;
758 }
759 }
760
761 return fRc;
762}
763
764/**
765 * csr_is_sta_session_connected() - to find if concurrent sta is active
766 * @mac_ctx: pointer to mac context
767 *
768 * This function will iterate through each session and check if sta
769 * session exist and active
770 *
771 * Return: true or false
772 */
773bool csr_is_sta_session_connected(tpAniSirGlobal mac_ctx)
774{
775 uint32_t i;
776 tCsrRoamSession *pSession = NULL;
777
778 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
779 if (CSR_IS_SESSION_VALID(mac_ctx, i) &&
780 !csr_is_conn_state_disconnected(mac_ctx, i)) {
781 pSession = CSR_GET_SESSION(mac_ctx, i);
782
783 if ((NULL != pSession->pCurRoamProfile) &&
784 (CDF_STA_MODE ==
785 pSession->pCurRoamProfile->csrPersona))
786 return true;
787 }
788 }
789
790 return false;
791}
792
793/**
794 * csr_is_p2p_session_connected() - to find if any p2p session is active
795 * @mac_ctx: pointer to mac context
796 *
797 * This function will iterate through each session and check if any p2p
798 * session exist and active
799 *
800 * Return: true or false
801 */
802bool csr_is_p2p_session_connected(tpAniSirGlobal pMac)
803{
804 uint32_t i;
805 tCsrRoamSession *pSession = NULL;
806 tCDF_CON_MODE persona;
807
808 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
809 if (CSR_IS_SESSION_VALID(pMac, i)
810 && !csr_is_conn_state_disconnected(pMac, i)) {
811 pSession = CSR_GET_SESSION(pMac, i);
812 persona = pSession->pCurRoamProfile->csrPersona;
813 if ((NULL != pSession->pCurRoamProfile) &&
814 ((CDF_P2P_CLIENT_MODE == persona) ||
815 (CDF_P2P_GO_MODE == persona))) {
816 return true;
817 }
818 }
819 }
820
821 return false;
822}
823
824bool csr_is_any_session_connected(tpAniSirGlobal pMac)
825{
826 uint32_t i, count;
827 bool fRc = false;
828
829 count = 0;
830 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
831 if (CSR_IS_SESSION_VALID(pMac, i)
832 && !csr_is_conn_state_disconnected(pMac, i))
833 count++;
834 }
835
836 if (count > 0)
837 fRc = true;
838 return fRc;
839}
840
841bool csr_is_infra_connected(tpAniSirGlobal pMac)
842{
843 uint32_t i;
844 bool fRc = false;
845
846 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
847 if (CSR_IS_SESSION_VALID(pMac, i)
848 && csr_is_conn_state_connected_infra(pMac, i)) {
849 fRc = true;
850 break;
851 }
852 }
853
854 return fRc;
855}
856
857bool csr_is_concurrent_infra_connected(tpAniSirGlobal pMac)
858{
859 uint32_t i, noOfConnectedInfra = 0;
860
861 bool fRc = false;
862
863 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
864 if (CSR_IS_SESSION_VALID(pMac, i)
865 && csr_is_conn_state_connected_infra(pMac, i)) {
866 ++noOfConnectedInfra;
867 }
868 }
869
870 /* More than one Infra Sta Connected */
871 if (noOfConnectedInfra > 1)
872 fRc = true;
873 return fRc;
874}
875
876bool csr_is_ibss_started(tpAniSirGlobal pMac)
877{
878 uint32_t i;
879 bool fRc = false;
880
881 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
882 if (CSR_IS_SESSION_VALID(pMac, i)
883 && csr_is_conn_state_ibss(pMac, i)) {
884 fRc = true;
885 break;
886 }
887 }
888
889 return fRc;
890}
891
892bool csr_is_btamp_started(tpAniSirGlobal pMac)
893{
894 uint32_t i;
895 bool fRc = false;
896
897 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
898 if (CSR_IS_SESSION_VALID(pMac, i)
899 && csr_is_conn_state_connected_wds(pMac, i)) {
900 fRc = true;
901 break;
902 }
903 }
904
905 return fRc;
906}
907
908bool csr_is_concurrent_session_running(tpAniSirGlobal pMac)
909{
910 uint32_t sessionId, noOfCocurrentSession = 0;
911 eCsrConnectState connectState;
912
913 bool fRc = false;
914
915 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
916 if (CSR_IS_SESSION_VALID(pMac, sessionId)) {
917 connectState =
918 pMac->roam.roamSession[sessionId].connectState;
919 if ((eCSR_ASSOC_STATE_TYPE_INFRA_ASSOCIATED ==
920 connectState)
921 || (eCSR_ASSOC_STATE_TYPE_INFRA_CONNECTED ==
922 connectState)
923 || (eCSR_ASSOC_STATE_TYPE_INFRA_DISCONNECTED ==
924 connectState)) {
925 ++noOfCocurrentSession;
926 }
927 }
928 }
929
930 /* More than one session is Up and Running */
931 if (noOfCocurrentSession > 1)
932 fRc = true;
933 return fRc;
934}
935
936bool csr_is_infra_ap_started(tpAniSirGlobal pMac)
937{
938 uint32_t sessionId;
939 bool fRc = false;
940
941 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
942 if (CSR_IS_SESSION_VALID(pMac, sessionId)
943 && (csr_is_conn_state_connected_infra_ap(pMac, sessionId))) {
944 fRc = true;
945 break;
946 }
947 }
948
949 return fRc;
950
951}
952
953bool csr_is_btamp(tpAniSirGlobal pMac, uint32_t sessionId)
954{
955 return csr_is_conn_state_connected_wds(pMac, sessionId);
956}
957
958bool csr_is_conn_state_disconnected(tpAniSirGlobal pMac, uint32_t sessionId)
959{
960 return eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED ==
961 pMac->roam.roamSession[sessionId].connectState;
962}
963
964/**
965 * csr_is_valid_mc_concurrent_session() - To check concurren session is valid
966 * @mac_ctx: pointer to mac context
967 * @session_id: session id
968 * @bss_descr: bss description
969 *
970 * This function validates the concurrent session
971 *
972 * Return: true or false
973 */
974bool csr_is_valid_mc_concurrent_session(tpAniSirGlobal mac_ctx,
975 uint32_t session_id,
976 tSirBssDescription *bss_descr)
977{
978 tCsrRoamSession *pSession = NULL;
979
980 /* Check for MCC support */
981 if (!mac_ctx->roam.configParam.fenableMCCMode)
982 return false;
983 if (!CSR_IS_SESSION_VALID(mac_ctx, session_id))
984 return false;
985 /* Validate BeaconInterval */
986 pSession = CSR_GET_SESSION(mac_ctx, session_id);
987 if (NULL == pSession->pCurRoamProfile)
988 return false;
989 if (CDF_STATUS_SUCCESS ==
990 csr_isconcurrentsession_valid(mac_ctx, session_id,
991 pSession->pCurRoamProfile->csrPersona)) {
992 if (CDF_STATUS_SUCCESS ==
993 csr_validate_mcc_beacon_interval(mac_ctx,
994 bss_descr->channelId,
995 &bss_descr->beaconInterval, session_id,
996 pSession->pCurRoamProfile->csrPersona))
997 return true;
998 }
999 return false;
1000}
1001
1002static tSirMacCapabilityInfo csr_get_bss_capabilities(tSirBssDescription *
1003 pSirBssDesc)
1004{
1005 tSirMacCapabilityInfo dot11Caps;
1006
1007 /* tSirMacCapabilityInfo is 16-bit */
1008 cdf_get_u16((uint8_t *) &pSirBssDesc->capabilityInfo,
1009 (uint16_t *) &dot11Caps);
1010
1011 return dot11Caps;
1012}
1013
1014bool csr_is_infra_bss_desc(tSirBssDescription *pSirBssDesc)
1015{
1016 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1017
1018 return (bool) dot11Caps.ess;
1019}
1020
1021bool csr_is_ibss_bss_desc(tSirBssDescription *pSirBssDesc)
1022{
1023 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1024
1025 return (bool) dot11Caps.ibss;
1026}
1027
1028bool csr_is_qo_s_bss_desc(tSirBssDescription *pSirBssDesc)
1029{
1030 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1031
1032 return (bool) dot11Caps.qos;
1033}
1034
1035bool csr_is_privacy(tSirBssDescription *pSirBssDesc)
1036{
1037 tSirMacCapabilityInfo dot11Caps = csr_get_bss_capabilities(pSirBssDesc);
1038
1039 return (bool) dot11Caps.privacy;
1040}
1041
1042bool csr_is11d_supported(tpAniSirGlobal pMac)
1043{
1044 return pMac->roam.configParam.Is11dSupportEnabled;
1045}
1046
1047bool csr_is11h_supported(tpAniSirGlobal pMac)
1048{
1049 return pMac->roam.configParam.Is11hSupportEnabled;
1050}
1051
1052bool csr_is11e_supported(tpAniSirGlobal pMac)
1053{
1054 return pMac->roam.configParam.Is11eSupportEnabled;
1055}
1056
1057bool csr_is_mcc_supported(tpAniSirGlobal pMac)
1058{
1059 return pMac->roam.configParam.fenableMCCMode;
1060
1061}
1062
1063bool csr_is_wmm_supported(tpAniSirGlobal pMac)
1064{
1065 if (eCsrRoamWmmNoQos == pMac->roam.configParam.WMMSupportMode)
1066 return false;
1067 else
1068 return true;
1069}
1070
1071/* pIes is the IEs for pSirBssDesc2 */
1072bool csr_is_ssid_equal(tHalHandle hHal, tSirBssDescription *pSirBssDesc1,
1073 tSirBssDescription *pSirBssDesc2, tDot11fBeaconIEs *pIes2)
1074{
1075 bool fEqual = false;
1076 tSirMacSSid Ssid1, Ssid2;
1077 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1078 tDot11fBeaconIEs *pIes1 = NULL;
1079 tDot11fBeaconIEs *pIesLocal = pIes2;
1080
1081 do {
1082 if ((NULL == pSirBssDesc1) || (NULL == pSirBssDesc2))
1083 break;
1084 if (!pIesLocal
1085 &&
1086 !CDF_IS_STATUS_SUCCESS(csr_get_parsed_bss_description_ies
1087 (pMac, pSirBssDesc2,
1088 &pIesLocal))) {
1089 sms_log(pMac, LOGE, FL(" fail to parse IEs"));
1090 break;
1091 }
1092 if (!CDF_IS_STATUS_SUCCESS
1093 (csr_get_parsed_bss_description_ies(pMac,
1094 pSirBssDesc1, &pIes1))) {
1095 break;
1096 }
1097 if ((!pIes1->SSID.present) || (!pIesLocal->SSID.present))
1098 break;
1099 if (pIes1->SSID.num_ssid != pIesLocal->SSID.num_ssid)
1100 break;
1101 cdf_mem_copy(Ssid1.ssId, pIes1->SSID.ssid,
1102 pIes1->SSID.num_ssid);
1103 cdf_mem_copy(Ssid2.ssId, pIesLocal->SSID.ssid,
1104 pIesLocal->SSID.num_ssid);
1105
1106 fEqual =
1107 cdf_mem_compare(Ssid1.ssId, Ssid2.ssId,
1108 pIesLocal->SSID.num_ssid);
1109
1110 } while (0);
1111 if (pIes1)
1112 cdf_mem_free(pIes1);
1113 if (pIesLocal && !pIes2)
1114 cdf_mem_free(pIesLocal);
1115
1116 return fEqual;
1117}
1118
1119/* pIes can be passed in as NULL if the caller doesn't have one prepared */
1120bool csr_is_bss_description_wme(tHalHandle hHal, tSirBssDescription *pSirBssDesc,
1121 tDot11fBeaconIEs *pIes)
1122{
1123 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1124 /* Assume that WME is found... */
1125 bool fWme = true;
1126 tDot11fBeaconIEs *pIesTemp = pIes;
1127
1128 do {
1129 if (pIesTemp == NULL) {
1130 if (!CDF_IS_STATUS_SUCCESS
1131 (csr_get_parsed_bss_description_ies
1132 (pMac, pSirBssDesc, &pIesTemp))) {
1133 fWme = false;
1134 break;
1135 }
1136 }
1137 /* if the Wme Info IE is found, then WME is supported... */
1138 if (CSR_IS_QOS_BSS(pIesTemp))
1139 break;
1140 /* if none of these are found, then WME is NOT supported... */
1141 fWme = false;
1142 } while (0);
1143 if (!csr_is_wmm_supported(pMac) && fWme) {
1144 if (!pIesTemp->HTCaps.present) {
1145 fWme = false;
1146 }
1147 }
1148 if ((pIes == NULL) && (NULL != pIesTemp)) {
1149 /* we allocate memory here so free it before returning */
1150 cdf_mem_free(pIesTemp);
1151 }
1152
1153 return fWme;
1154}
1155
1156eCsrMediaAccessType csr_get_qo_s_from_bss_desc(tHalHandle hHal,
1157 tSirBssDescription *pSirBssDesc,
1158 tDot11fBeaconIEs *pIes)
1159{
1160 eCsrMediaAccessType qosType = eCSR_MEDIUM_ACCESS_DCF;
1161
1162 if (NULL == pIes) {
1163 CDF_ASSERT(pIes != NULL);
1164 return qosType;
1165 }
1166
1167 do {
1168 /* if we find WMM in the Bss Description, then we let this */
1169 /* override and use WMM. */
1170 if (csr_is_bss_description_wme(hHal, pSirBssDesc, pIes)) {
1171 qosType = eCSR_MEDIUM_ACCESS_WMM_eDCF_DSCP;
1172 } else {
1173 /* if the QoS bit is on, then the AP is advertising 11E QoS... */
1174 if (csr_is_qo_s_bss_desc(pSirBssDesc)) {
1175 qosType = eCSR_MEDIUM_ACCESS_11e_eDCF;
1176 } else {
1177 qosType = eCSR_MEDIUM_ACCESS_DCF;
1178 }
1179 /* scale back based on the types turned on for the adapter... */
1180 if (eCSR_MEDIUM_ACCESS_11e_eDCF == qosType
1181 && !csr_is11e_supported(hHal)) {
1182 qosType = eCSR_MEDIUM_ACCESS_DCF;
1183 }
1184 }
1185
1186 } while (0);
1187
1188 return qosType;
1189}
1190
1191/* Caller allocates memory for pIEStruct */
1192CDF_STATUS csr_parse_bss_description_ies(tHalHandle hHal,
1193 tSirBssDescription *pBssDesc,
1194 tDot11fBeaconIEs *pIEStruct)
1195{
1196 CDF_STATUS status = CDF_STATUS_E_FAILURE;
1197 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1198 int ieLen =
1199 (int)(pBssDesc->length + sizeof(pBssDesc->length) -
1200 GET_FIELD_OFFSET(tSirBssDescription, ieFields));
1201
1202 if (ieLen > 0 && pIEStruct) {
1203 if (!DOT11F_FAILED
1204 (dot11f_unpack_beacon_i_es
1205 (pMac, (uint8_t *) pBssDesc->ieFields, ieLen,
1206 pIEStruct))) {
1207 status = CDF_STATUS_SUCCESS;
1208 }
1209 }
1210
1211 return status;
1212}
1213
1214/* This function will allocate memory for the parsed IEs to the caller. Caller must free the memory */
1215/* after it is done with the data only if this function succeeds */
1216CDF_STATUS csr_get_parsed_bss_description_ies(tHalHandle hHal,
1217 tSirBssDescription *pBssDesc,
1218 tDot11fBeaconIEs **ppIEStruct)
1219{
1220 CDF_STATUS status = CDF_STATUS_E_INVAL;
1221 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1222
1223 if (pBssDesc && ppIEStruct) {
1224 *ppIEStruct = cdf_mem_malloc(sizeof(tDot11fBeaconIEs));
1225 if ((*ppIEStruct) != NULL) {
1226 cdf_mem_set((void *)*ppIEStruct,
1227 sizeof(tDot11fBeaconIEs), 0);
1228 status =
1229 csr_parse_bss_description_ies(hHal, pBssDesc,
1230 *ppIEStruct);
1231 if (!CDF_IS_STATUS_SUCCESS(status)) {
1232 cdf_mem_free(*ppIEStruct);
1233 *ppIEStruct = NULL;
1234 }
1235 } else {
1236 sms_log(pMac, LOGE, FL(" failed to allocate memory"));
1237 CDF_ASSERT(0);
1238 return CDF_STATUS_E_NOMEM;
1239 }
1240 }
1241
1242 return status;
1243}
1244
1245bool csr_is_nullssid(uint8_t *pBssSsid, uint8_t len)
1246{
1247 bool fNullSsid = false;
1248
1249 uint32_t SsidLength;
1250 uint8_t *pSsidStr;
1251
1252 do {
1253 if (0 == len) {
1254 fNullSsid = true;
1255 break;
1256 }
1257 /* Consider 0 or space for hidden SSID */
1258 if (0 == pBssSsid[0]) {
1259 fNullSsid = true;
1260 break;
1261 }
1262
1263 SsidLength = len;
1264 pSsidStr = pBssSsid;
1265
1266 while (SsidLength) {
1267 if (*pSsidStr)
1268 break;
1269
1270 pSsidStr++;
1271 SsidLength--;
1272 }
1273
1274 if (0 == SsidLength) {
1275 fNullSsid = true;
1276 break;
1277 }
1278 } while (0);
1279
1280 return fNullSsid;
1281}
1282
1283uint32_t csr_get_frag_thresh(tHalHandle hHal)
1284{
1285 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1286
1287 return pMac->roam.configParam.FragmentationThreshold;
1288}
1289
1290uint32_t csr_get_rts_thresh(tHalHandle hHal)
1291{
1292 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1293
1294 return pMac->roam.configParam.RTSThreshold;
1295}
1296
1297eCsrPhyMode csr_translate_to_phy_mode_from_bss_desc(tSirBssDescription *pSirBssDesc)
1298{
1299 eCsrPhyMode phyMode;
1300
1301 switch (pSirBssDesc->nwType) {
1302 case eSIR_11A_NW_TYPE:
1303 phyMode = eCSR_DOT11_MODE_11a;
1304 break;
1305
1306 case eSIR_11B_NW_TYPE:
1307 phyMode = eCSR_DOT11_MODE_11b;
1308 break;
1309
1310 case eSIR_11G_NW_TYPE:
1311 phyMode = eCSR_DOT11_MODE_11g;
1312 break;
1313
1314 case eSIR_11N_NW_TYPE:
1315 phyMode = eCSR_DOT11_MODE_11n;
1316 break;
1317#ifdef WLAN_FEATURE_11AC
1318 case eSIR_11AC_NW_TYPE:
1319 default:
1320 phyMode = eCSR_DOT11_MODE_11ac;
1321#else
1322 default:
1323 phyMode = eCSR_DOT11_MODE_11n;
1324#endif
1325 break;
1326 }
1327 return phyMode;
1328}
1329
1330uint32_t csr_translate_to_wni_cfg_dot11_mode(tpAniSirGlobal pMac,
1331 eCsrCfgDot11Mode csrDot11Mode)
1332{
1333 uint32_t ret;
1334
1335 switch (csrDot11Mode) {
1336 case eCSR_CFG_DOT11_MODE_AUTO:
1337 sms_log(pMac, LOGW,
1338 FL(" Warning: sees eCSR_CFG_DOT11_MODE_AUTO "));
1339 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
1340 ret = WNI_CFG_DOT11_MODE_11AC;
1341 else
1342 ret = WNI_CFG_DOT11_MODE_11N;
1343 break;
1344 case eCSR_CFG_DOT11_MODE_11A:
1345 ret = WNI_CFG_DOT11_MODE_11A;
1346 break;
1347 case eCSR_CFG_DOT11_MODE_11B:
1348 ret = WNI_CFG_DOT11_MODE_11B;
1349 break;
1350 case eCSR_CFG_DOT11_MODE_11G:
1351 ret = WNI_CFG_DOT11_MODE_11G;
1352 break;
1353 case eCSR_CFG_DOT11_MODE_11N:
1354 ret = WNI_CFG_DOT11_MODE_11N;
1355 break;
1356 case eCSR_CFG_DOT11_MODE_11G_ONLY:
1357 ret = WNI_CFG_DOT11_MODE_11G_ONLY;
1358 break;
1359 case eCSR_CFG_DOT11_MODE_11N_ONLY:
1360 ret = WNI_CFG_DOT11_MODE_11N_ONLY;
1361 break;
1362 case eCSR_CFG_DOT11_MODE_11AC_ONLY:
1363 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
1364 ret = WNI_CFG_DOT11_MODE_11AC_ONLY;
1365 else
1366 ret = WNI_CFG_DOT11_MODE_11N;
1367 break;
1368 case eCSR_CFG_DOT11_MODE_11AC:
1369 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC))
1370 ret = WNI_CFG_DOT11_MODE_11AC;
1371 else
1372 ret = WNI_CFG_DOT11_MODE_11N;
1373 break;
1374 default:
1375 sms_log(pMac, LOGW, FL("doesn't expect %d as csrDo11Mode"),
1376 csrDot11Mode);
1377 if (eCSR_BAND_24 == pMac->roam.configParam.eBand) {
1378 ret = WNI_CFG_DOT11_MODE_11G;
1379 } else {
1380 ret = WNI_CFG_DOT11_MODE_11A;
1381 }
1382 break;
1383 }
1384
1385 return ret;
1386}
1387
1388/**
1389 * csr_get_phy_mode_from_bss() - Get Phy Mode
1390 * @pMac: Global MAC context
1391 * @pBSSDescription: BSS Descriptor
1392 * @pPhyMode: Physical Mode
1393 * @pIes: Pointer to the IE fields
1394 *
1395 * This function should only return the super set of supported modes
1396 * 11n implies 11b/g/a/n.
1397 *
1398 * Return: success
1399 **/
1400CDF_STATUS csr_get_phy_mode_from_bss(tpAniSirGlobal pMac,
1401 tSirBssDescription *pBSSDescription,
1402 eCsrPhyMode *pPhyMode, tDot11fBeaconIEs *pIes)
1403{
1404 CDF_STATUS status = CDF_STATUS_SUCCESS;
1405 eCsrPhyMode phyMode =
1406 csr_translate_to_phy_mode_from_bss_desc(pBSSDescription);
1407
1408 if (pIes) {
1409 if (pIes->HTCaps.present) {
1410 phyMode = eCSR_DOT11_MODE_11n;
1411#ifdef WLAN_FEATURE_11AC
1412 if (IS_BSS_VHT_CAPABLE(pIes->VHTCaps) ||
1413 IS_BSS_VHT_CAPABLE(pIes->vendor2_ie.VHTCaps))
1414 phyMode = eCSR_DOT11_MODE_11ac;
1415#endif
1416 }
1417 *pPhyMode = phyMode;
1418 }
1419
1420 return status;
1421}
1422
1423/**
1424 * csr_get_phy_mode_in_use() - to get phymode
1425 * @phyModeIn: physical mode
1426 * @bssPhyMode: physical mode in bss
1427 * @f5GhzBand: 5Ghz band
1428 * @pCfgDot11ModeToUse: dot11 mode in use
1429 *
1430 * This function returns the correct eCSR_CFG_DOT11_MODE is the two phyModes
1431 * matches. bssPhyMode is the mode derived from the BSS description
1432 * f5GhzBand is derived from the channel id of BSS description
1433 *
1434 * Return: true or false
1435 */
1436bool csr_get_phy_mode_in_use(eCsrPhyMode phyModeIn, eCsrPhyMode bssPhyMode,
1437 bool f5GhzBand, eCsrCfgDot11Mode *pCfgDot11ModeToUse)
1438{
1439 bool fMatch = false;
1440 eCsrCfgDot11Mode cfgDot11Mode;
1441 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1442
1443 switch (phyModeIn) {
1444 /* 11a or 11b or 11g */
1445 case eCSR_DOT11_MODE_abg:
1446 fMatch = true;
1447 if (f5GhzBand)
1448 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1449 else if (eCSR_DOT11_MODE_11b == bssPhyMode)
1450 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1451 else
1452 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1453 break;
1454
1455 case eCSR_DOT11_MODE_11a:
1456 if (f5GhzBand) {
1457 fMatch = true;
1458 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1459 }
1460 break;
1461
1462 case eCSR_DOT11_MODE_11g:
1463 if (!f5GhzBand) {
1464 fMatch = true;
1465 if (eCSR_DOT11_MODE_11b == bssPhyMode)
1466 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1467 else
1468 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1469 }
1470 break;
1471
1472 case eCSR_DOT11_MODE_11g_ONLY:
1473 if (eCSR_DOT11_MODE_11g == bssPhyMode) {
1474 fMatch = true;
1475 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1476 }
1477 break;
1478
1479 case eCSR_DOT11_MODE_11b:
1480 if (!f5GhzBand) {
1481 fMatch = true;
1482 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1483 }
1484 break;
1485
1486 case eCSR_DOT11_MODE_11b_ONLY:
1487 if (eCSR_DOT11_MODE_11b == bssPhyMode) {
1488 fMatch = true;
1489 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1490 }
1491 break;
1492
1493 case eCSR_DOT11_MODE_11n:
1494 fMatch = true;
1495 switch (bssPhyMode) {
1496 case eCSR_DOT11_MODE_11g:
1497 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1498 break;
1499 case eCSR_DOT11_MODE_11b:
1500 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1501 break;
1502 case eCSR_DOT11_MODE_11a:
1503 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1504 break;
1505 case eCSR_DOT11_MODE_11n:
1506#ifdef WLAN_FEATURE_11AC
1507 case eCSR_DOT11_MODE_11ac:
1508#endif
1509 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1510 break;
1511
1512 default:
1513#ifdef WLAN_FEATURE_11AC
1514 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1515#else
1516 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1517#endif
1518 break;
1519 }
1520 break;
1521
1522 case eCSR_DOT11_MODE_11n_ONLY:
1523 if ((eCSR_DOT11_MODE_11n == bssPhyMode)) {
1524 fMatch = true;
1525 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1526
1527 }
1528
1529 break;
1530#ifdef WLAN_FEATURE_11AC
1531 case eCSR_DOT11_MODE_11ac:
1532 fMatch = true;
1533 switch (bssPhyMode) {
1534 case eCSR_DOT11_MODE_11g:
1535 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1536 break;
1537 case eCSR_DOT11_MODE_11b:
1538 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1539 break;
1540 case eCSR_DOT11_MODE_11a:
1541 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1542 break;
1543 case eCSR_DOT11_MODE_11n:
1544 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1545 break;
1546 case eCSR_DOT11_MODE_11ac:
1547 default:
1548 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1549 break;
1550 }
1551 break;
1552
1553 case eCSR_DOT11_MODE_11ac_ONLY:
1554 if ((eCSR_DOT11_MODE_11ac == bssPhyMode)) {
1555 fMatch = true;
1556 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1557 }
1558 break;
1559#endif
1560
1561 default:
1562 fMatch = true;
1563 switch (bssPhyMode) {
1564 case eCSR_DOT11_MODE_11g:
1565 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
1566 break;
1567 case eCSR_DOT11_MODE_11b:
1568 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
1569 break;
1570 case eCSR_DOT11_MODE_11a:
1571 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
1572 break;
1573 case eCSR_DOT11_MODE_11n:
1574 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
1575 break;
1576#ifdef WLAN_FEATURE_11AC
1577 case eCSR_DOT11_MODE_11ac:
1578 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
1579 break;
1580#endif
1581 default:
1582 cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
1583 break;
1584 }
1585 break;
1586 }
1587
1588 if (fMatch && pCfgDot11ModeToUse) {
1589#ifdef WLAN_FEATURE_11AC
1590 if (cfgDot11Mode == eCSR_CFG_DOT11_MODE_11AC
1591 && (!IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)))
1592 *pCfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
1593 else
1594#endif
1595 *pCfgDot11ModeToUse = cfgDot11Mode;
1596 }
1597 return fMatch;
1598}
1599
1600/**
1601 * csr_is_phy_mode_match() - to find if phy mode matches
1602 * @pMac: pointer to mac context
1603 * @phyMode: physical mode
1604 * @pSirBssDesc: bss description
1605 * @pProfile: pointer to roam profile
1606 * @pReturnCfgDot11Mode: dot1 mode to return
1607 * @pIes: pointer to IEs
1608 *
1609 * This function decides whether the one of the bit of phyMode is matching the
1610 * mode in the BSS and allowed by the user setting
1611 *
1612 * Return: true or false based on mode that fits the criteria
1613 */
1614bool csr_is_phy_mode_match(tpAniSirGlobal pMac, uint32_t phyMode,
1615 tSirBssDescription *pSirBssDesc,
1616 tCsrRoamProfile *pProfile,
1617 eCsrCfgDot11Mode *pReturnCfgDot11Mode,
1618 tDot11fBeaconIEs *pIes)
1619{
1620 bool fMatch = false;
1621 eCsrPhyMode phyModeInBssDesc = eCSR_DOT11_MODE_AUTO, phyMode2;
1622 eCsrCfgDot11Mode cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_AUTO;
1623 uint32_t bitMask, loopCount;
1624
1625 if (!CDF_IS_STATUS_SUCCESS(csr_get_phy_mode_from_bss(pMac, pSirBssDesc,
1626 &phyModeInBssDesc, pIes)))
1627 return fMatch;
1628
1629 if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
1630 if (eCSR_CFG_DOT11_MODE_ABG ==
1631 pMac->roam.configParam.uCfgDot11Mode)
1632 phyMode = eCSR_DOT11_MODE_abg;
1633 else if (eCSR_CFG_DOT11_MODE_AUTO ==
1634 pMac->roam.configParam.uCfgDot11Mode)
1635#ifdef WLAN_FEATURE_11AC
1636 phyMode = eCSR_DOT11_MODE_11ac;
1637#else
1638 phyMode = eCSR_DOT11_MODE_11n;
1639#endif
1640
1641 else
1642 /* user's pick */
1643 phyMode = pMac->roam.configParam.phyMode;
1644 }
1645
1646 if ((0 == phyMode) || (eCSR_DOT11_MODE_AUTO & phyMode)) {
1647 if (0 != phyMode) {
1648 if (eCSR_DOT11_MODE_AUTO & phyMode) {
1649 phyMode2 =
1650 eCSR_DOT11_MODE_AUTO & phyMode;
1651 }
1652 } else {
1653 phyMode2 = phyMode;
1654 }
1655 fMatch = csr_get_phy_mode_in_use(phyMode2, phyModeInBssDesc,
1656 CDS_IS_CHANNEL_5GHZ(pSirBssDesc->channelId),
1657 &cfgDot11ModeToUse);
1658 } else {
1659 bitMask = 1;
1660 loopCount = 0;
1661 while (loopCount < eCSR_NUM_PHY_MODE) {
1662 phyMode2 = (phyMode & (bitMask << loopCount++));
1663 if (0 != phyMode2 && csr_get_phy_mode_in_use(phyMode2,
1664 phyModeInBssDesc,
1665 CDS_IS_CHANNEL_5GHZ
1666 (pSirBssDesc->channelId),
1667 &cfgDot11ModeToUse)) {
1668 fMatch = true;
1669 break;
1670 }
1671 }
1672 }
1673 if (fMatch && pReturnCfgDot11Mode) {
1674 if (pProfile) {
1675 /*
1676 * IEEE 11n spec (8.4.3): HT STA shall
1677 * eliminate TKIP as a choice for the pairwise
1678 * cipher suite if CCMP is advertised by the AP
1679 * or if the AP included an HT capabilities
1680 * element in its Beacons and Probe Response.
1681 */
1682 if ((!CSR_IS_11n_ALLOWED(
1683 pProfile->negotiatedUCEncryptionType))
1684 && ((eCSR_CFG_DOT11_MODE_11N ==
1685 cfgDot11ModeToUse) ||
1686#ifdef WLAN_FEATURE_11AC
1687 (eCSR_CFG_DOT11_MODE_11AC ==
1688 cfgDot11ModeToUse)
1689#endif
1690 )) {
1691 /* We cannot do 11n here */
1692 if (!CDS_IS_CHANNEL_5GHZ
1693 (pSirBssDesc->channelId)) {
1694 cfgDot11ModeToUse =
1695 eCSR_CFG_DOT11_MODE_11G;
1696 } else {
1697 cfgDot11ModeToUse =
1698 eCSR_CFG_DOT11_MODE_11A;
1699 }
1700 }
1701 }
1702 *pReturnCfgDot11Mode = cfgDot11ModeToUse;
1703 }
1704
1705 return fMatch;
1706}
1707
1708eCsrCfgDot11Mode csr_find_best_phy_mode(tpAniSirGlobal pMac, uint32_t phyMode)
1709{
1710 eCsrCfgDot11Mode cfgDot11ModeToUse;
1711 eCsrBand eBand = pMac->roam.configParam.eBand;
1712
1713 if ((0 == phyMode) ||
1714#ifdef WLAN_FEATURE_11AC
1715 (eCSR_DOT11_MODE_11ac & phyMode) ||
1716#endif
1717 (eCSR_DOT11_MODE_AUTO & phyMode)) {
1718#ifdef WLAN_FEATURE_11AC
1719 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
1720 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11AC;
1721 } else
1722#endif
1723 {
1724 /* Default to 11N mode if user has configured 11ac mode
1725 * and FW doesn't supports 11ac mode .
1726 */
1727 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
1728 }
1729 } else {
1730 if ((eCSR_DOT11_MODE_11n | eCSR_DOT11_MODE_11n_ONLY) & phyMode) {
1731 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11N;
1732 } else if (eCSR_DOT11_MODE_abg & phyMode) {
1733 if (eCSR_BAND_24 != eBand) {
1734 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
1735 } else {
1736 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
1737 }
1738 } else if (eCSR_DOT11_MODE_11a & phyMode) {
1739 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11A;
1740 } else if ((eCSR_DOT11_MODE_11g | eCSR_DOT11_MODE_11g_ONLY) &
1741 phyMode) {
1742 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11G;
1743 } else {
1744 cfgDot11ModeToUse = eCSR_CFG_DOT11_MODE_11B;
1745 }
1746 }
1747
1748 return cfgDot11ModeToUse;
1749}
1750
1751uint32_t csr_get11h_power_constraint(tHalHandle hHal,
1752 tDot11fIEPowerConstraints *pPowerConstraint)
1753{
1754 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
1755 uint32_t localPowerConstraint = 0;
1756
1757 /* check if .11h support is enabled, if not, the power constraint is 0. */
1758 if (pMac->roam.configParam.Is11hSupportEnabled
1759 && pPowerConstraint->present) {
1760 localPowerConstraint = pPowerConstraint->localPowerConstraints;
1761 }
1762
1763 return localPowerConstraint;
1764}
1765
1766bool csr_is_profile_wpa(tCsrRoamProfile *pProfile)
1767{
1768 bool fWpaProfile = false;
1769
1770 switch (pProfile->negotiatedAuthType) {
1771 case eCSR_AUTH_TYPE_WPA:
1772 case eCSR_AUTH_TYPE_WPA_PSK:
1773 case eCSR_AUTH_TYPE_WPA_NONE:
1774#ifdef FEATURE_WLAN_ESE
1775 case eCSR_AUTH_TYPE_CCKM_WPA:
1776#endif
1777 fWpaProfile = true;
1778 break;
1779
1780 default:
1781 fWpaProfile = false;
1782 break;
1783 }
1784
1785 if (fWpaProfile) {
1786 switch (pProfile->negotiatedUCEncryptionType) {
1787 case eCSR_ENCRYPT_TYPE_WEP40:
1788 case eCSR_ENCRYPT_TYPE_WEP104:
1789 case eCSR_ENCRYPT_TYPE_TKIP:
1790 case eCSR_ENCRYPT_TYPE_AES:
1791 fWpaProfile = true;
1792 break;
1793
1794 default:
1795 fWpaProfile = false;
1796 break;
1797 }
1798 }
1799 return fWpaProfile;
1800}
1801
1802bool csr_is_profile_rsn(tCsrRoamProfile *pProfile)
1803{
1804 bool fRSNProfile = false;
1805
1806 switch (pProfile->negotiatedAuthType) {
1807 case eCSR_AUTH_TYPE_RSN:
1808 case eCSR_AUTH_TYPE_RSN_PSK:
1809#ifdef WLAN_FEATURE_VOWIFI_11R
1810 case eCSR_AUTH_TYPE_FT_RSN:
1811 case eCSR_AUTH_TYPE_FT_RSN_PSK:
1812#endif
1813#ifdef FEATURE_WLAN_ESE
1814 case eCSR_AUTH_TYPE_CCKM_RSN:
1815#endif
1816#ifdef WLAN_FEATURE_11W
1817 case eCSR_AUTH_TYPE_RSN_PSK_SHA256:
1818 case eCSR_AUTH_TYPE_RSN_8021X_SHA256:
1819#endif
1820 fRSNProfile = true;
1821 break;
1822
1823 default:
1824 fRSNProfile = false;
1825 break;
1826 }
1827
1828 if (fRSNProfile) {
1829 switch (pProfile->negotiatedUCEncryptionType) {
1830 /* !!REVIEW - For WPA2, use of RSN IE mandates */
1831 /* use of AES as encryption. Here, we qualify */
1832 /* even if encryption type is WEP or TKIP */
1833 case eCSR_ENCRYPT_TYPE_WEP40:
1834 case eCSR_ENCRYPT_TYPE_WEP104:
1835 case eCSR_ENCRYPT_TYPE_TKIP:
1836 case eCSR_ENCRYPT_TYPE_AES:
1837 fRSNProfile = true;
1838 break;
1839
1840 default:
1841 fRSNProfile = false;
1842 break;
1843 }
1844 }
1845 return fRSNProfile;
1846}
1847
1848/**
1849 * csr_isconcurrentsession_valid() - check if concurrent session is valid
1850 * @mac_ctx: pointer to mac context
1851 * @cur_sessionid: current session id
1852 * @cur_bss_persona: current BSS persona
1853 *
1854 * This function will check if concurrent session is valid
1855 *
1856 * Return: CDF_STATUS
1857 */
1858CDF_STATUS
1859csr_isconcurrentsession_valid(tpAniSirGlobal mac_ctx, uint32_t cur_sessionid,
1860 tCDF_CON_MODE cur_bss_persona)
1861{
1862 uint32_t sessionid = 0;
1863 tCDF_CON_MODE bss_persona;
1864 eCsrConnectState connect_state, temp;
1865 tCsrRoamSession *roam_session;
1866
1867 for (sessionid = 0; sessionid < CSR_ROAM_SESSION_MAX; sessionid++) {
1868 if (cur_sessionid == sessionid)
1869 continue;
1870 if (!CSR_IS_SESSION_VALID(mac_ctx, sessionid))
1871 continue;
1872 roam_session = &mac_ctx->roam.roamSession[sessionid];
1873 bss_persona = roam_session->bssParams.bssPersona;
1874 connect_state = roam_session->connectState;
1875
1876 switch (cur_bss_persona) {
1877 case CDF_STA_MODE:
1878 CDF_TRACE(CDF_MODULE_ID_SME,
1879 CDF_TRACE_LEVEL_INFO,
1880 FL("** STA session **"));
1881 return CDF_STATUS_SUCCESS;
1882
1883 case CDF_SAP_MODE:
1884 temp = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
1885#ifndef WLAN_FEATURE_MBSSID
1886 if ((bss_persona == CDF_SAP_MODE) &&
1887 (connect_state !=
1888 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
1889 CDF_TRACE(CDF_MODULE_ID_SME,
1890 CDF_TRACE_LEVEL_ERROR,
1891 FL("sap mode already exist"));
1892 return CDF_STATUS_E_FAILURE;
1893 } else
1894#endif
1895 if ((bss_persona == CDF_IBSS_MODE)
1896 && (connect_state != temp)) {
1897 CDF_TRACE(CDF_MODULE_ID_SME,
1898 CDF_TRACE_LEVEL_ERROR,
1899 FL("Can't start GO"));
1900 return CDF_STATUS_E_FAILURE;
1901 }
1902 break;
1903
1904 case CDF_P2P_GO_MODE:
1905 temp = eCSR_ASSOC_STATE_TYPE_IBSS_DISCONNECTED;
1906 if ((bss_persona == CDF_P2P_GO_MODE) &&
1907 (connect_state !=
1908 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
1909 CDF_TRACE(CDF_MODULE_ID_SME,
1910 CDF_TRACE_LEVEL_ERROR,
1911 FL("GO mode already exists"));
1912 return CDF_STATUS_E_FAILURE;
1913 } else if ((bss_persona == CDF_IBSS_MODE)
1914 && (connect_state != temp)) {
1915 CDF_TRACE(CDF_MODULE_ID_SME,
1916 CDF_TRACE_LEVEL_ERROR,
1917 FL("Can't start SAP"));
1918 return CDF_STATUS_E_FAILURE;
1919 }
1920 break;
1921 case CDF_IBSS_MODE:
1922 if ((bss_persona == CDF_IBSS_MODE) && (connect_state !=
1923 eCSR_ASSOC_STATE_TYPE_IBSS_CONNECTED)) {
1924 CDF_TRACE(CDF_MODULE_ID_SME,
1925 CDF_TRACE_LEVEL_ERROR,
1926 FL("IBSS mode already exist"));
1927 return CDF_STATUS_E_FAILURE;
1928 } else if (((bss_persona == CDF_P2P_GO_MODE) ||
1929 (bss_persona == CDF_SAP_MODE)) &&
1930 (connect_state !=
1931 eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) {
1932 CDF_TRACE(CDF_MODULE_ID_SME,
1933 CDF_TRACE_LEVEL_ERROR,
1934 FL("Can't start GO"));
1935 return CDF_STATUS_E_FAILURE;
1936 }
1937 break;
1938 case CDF_P2P_CLIENT_MODE:
1939 CDF_TRACE(CDF_MODULE_ID_SME,
1940 CDF_TRACE_LEVEL_INFO,
1941 FL("**P2P-Client session**"));
1942 return CDF_STATUS_SUCCESS;
1943 default:
1944 CDF_TRACE(CDF_MODULE_ID_SME,
1945 CDF_TRACE_LEVEL_ERROR,
1946 FL("Persona not handled = %d"),
1947 cur_bss_persona);
1948 break;
1949 }
1950 }
1951 return CDF_STATUS_SUCCESS;
1952
1953}
1954
1955/**
1956 * csr_update_mcc_p2p_beacon_interval() - update p2p beacon interval
1957 * @mac_ctx: pointer to mac context
1958 *
1959 * This function is to update the mcc p2p beacon interval
1960 *
1961 * Return: CDF_STATUS
1962 */
1963CDF_STATUS csr_update_mcc_p2p_beacon_interval(tpAniSirGlobal mac_ctx)
1964{
1965 uint32_t session_id = 0;
1966 tCsrRoamSession *roam_session;
1967
1968 /* If MCC is not supported just break and return SUCCESS */
1969 if (!mac_ctx->roam.configParam.fenableMCCMode)
1970 return CDF_STATUS_E_FAILURE;
1971
1972 for (session_id = 0; session_id < CSR_ROAM_SESSION_MAX; session_id++) {
1973 /*
1974 * If GO in MCC support different beacon interval,
1975 * change the BI of the P2P-GO
1976 */
1977 roam_session = &mac_ctx->roam.roamSession[session_id];
1978 if (roam_session->bssParams.bssPersona != CDF_P2P_GO_MODE)
1979 continue;
1980 /*
1981 * Handle different BI scneario based on the
1982 * configuration set.If Config is set to 0x02 then
1983 * Disconnect all the P2P clients associated. If config
1984 * is set to 0x04 then update the BI without
1985 * disconnecting all the clients
1986 */
1987 if ((mac_ctx->roam.configParam.fAllowMCCGODiffBI == 0x04)
1988 && (roam_session->bssParams.
1989 updatebeaconInterval)) {
1990 return csr_send_chng_mcc_beacon_interval(mac_ctx,
1991 session_id);
1992 } else if (roam_session->bssParams.updatebeaconInterval) {
1993 /*
1994 * If the configuration of fAllowMCCGODiffBI is set to
1995 * other than 0x04
1996 */
1997 return csr_roam_call_callback(mac_ctx,
1998 session_id,
1999 NULL, 0,
2000 eCSR_ROAM_DISCONNECT_ALL_P2P_CLIENTS,
2001 eCSR_ROAM_RESULT_NONE);
2002 }
2003 }
2004 return CDF_STATUS_E_FAILURE;
2005}
2006
2007uint16_t csr_calculate_mcc_beacon_interval(tpAniSirGlobal pMac, uint16_t sta_bi,
2008 uint16_t go_gbi)
2009{
2010 uint8_t num_beacons = 0;
2011 uint8_t is_multiple = 0;
2012 uint16_t go_cbi = 0;
2013 uint16_t go_fbi = 0;
2014 uint16_t sta_cbi = 0;
2015
2016 /* If GO's given beacon Interval is less than 100 */
2017 if (go_gbi < 100)
2018 go_cbi = 100;
2019 /* if GO's given beacon Interval is greater than or equal to 100 */
2020 else
2021 go_cbi = 100 + (go_gbi % 100);
2022
2023 if (sta_bi == 0) {
2024 /* There is possibility to receive zero as value.
2025 Which will cause divide by zero. Hence initialise with 100
2026 */
2027 sta_bi = 100;
2028 sms_log(pMac, LOGW,
2029 FL("sta_bi 2nd parameter is zero, initialize to %d"),
2030 sta_bi);
2031 }
2032 /* check, if either one is multiple of another */
2033 if (sta_bi > go_cbi) {
2034 is_multiple = !(sta_bi % go_cbi);
2035 } else {
2036 is_multiple = !(go_cbi % sta_bi);
2037 }
2038 /* if it is multiple, then accept GO's beacon interval range [100,199] as it is */
2039 if (is_multiple) {
2040 return go_cbi;
2041 }
2042 /* else , if it is not multiple, then then check for number of beacons to be */
2043 /* inserted based on sta BI */
2044 num_beacons = sta_bi / 100;
2045 if (num_beacons) {
2046 /* GO's final beacon interval will be aligned to sta beacon interval, but */
2047 /* in the range of [100, 199]. */
2048 sta_cbi = sta_bi / num_beacons;
2049 go_fbi = sta_cbi;
2050 } else {
2051 /* if STA beacon interval is less than 100, use GO's change bacon interval */
2052 /* instead of updating to STA's beacon interval. */
2053 go_fbi = go_cbi;
2054 }
2055 return go_fbi;
2056}
2057
2058CDF_STATUS csr_validate_mcc_beacon_interval(tpAniSirGlobal pMac, uint8_t channelId,
2059 uint16_t *beaconInterval,
2060 uint32_t cursessionId,
2061 tCDF_CON_MODE currBssPersona)
2062{
2063 uint32_t sessionId = 0;
2064 uint16_t new_beaconInterval = 0;
2065
2066 /* If MCC is not supported just break */
2067 if (!pMac->roam.configParam.fenableMCCMode) {
2068 return CDF_STATUS_E_FAILURE;
2069 }
2070
2071 for (sessionId = 0; sessionId < CSR_ROAM_SESSION_MAX; sessionId++) {
2072 if (cursessionId != sessionId) {
2073 if (!CSR_IS_SESSION_VALID(pMac, sessionId)) {
2074 continue;
2075 }
2076
2077 switch (currBssPersona) {
2078 case CDF_STA_MODE:
2079 if (pMac->roam.roamSession[sessionId].
2080 pCurRoamProfile &&
2081 (pMac->roam.roamSession[sessionId].
2082 pCurRoamProfile->csrPersona ==
2083 CDF_P2P_CLIENT_MODE)) {
2084 /* check for P2P client mode */
2085 sms_log(pMac, LOG1,
2086 FL
2087 (" Beacon Interval Validation not required for STA/CLIENT"));
2088 }
2089 /*
2090 * IF SAP has started and STA wants to connect
2091 * on different channel MCC should
2092 * MCC should not be enabled so making it
2093 * false to enforce on same channel
2094 */
2095 else if (pMac->roam.roamSession[sessionId].
2096 bssParams.bssPersona ==
2097 CDF_SAP_MODE) {
2098 if (pMac->roam.roamSession[sessionId].
2099 bssParams.operationChn !=
2100 channelId) {
2101 sms_log(pMac, LOGE,
2102 FL
2103 ("*** MCC with SAP+STA sessions ****"));
2104 return CDF_STATUS_SUCCESS;
2105 }
2106 } else if (pMac->roam.roamSession[sessionId].
2107 bssParams.bssPersona ==
2108 CDF_P2P_GO_MODE) {
2109 /*
2110 * Check for P2P go scenario
2111 * if GO in MCC support different
2112 * beacon interval,
2113 * change the BI of the P2P-GO
2114 */
2115 if ((pMac->roam.roamSession[sessionId].
2116 bssParams.operationChn !=
2117 channelId)
2118 && (pMac->roam.
2119 roamSession[sessionId].
2120 bssParams.beaconInterval !=
2121 *beaconInterval)) {
2122 /* if GO in MCC support different beacon interval, return success */
2123 if (pMac->roam.configParam.
2124 fAllowMCCGODiffBI == 0x01) {
2125 return
2126 CDF_STATUS_SUCCESS;
2127 }
2128 /* Send only Broadcast disassoc and update beaconInterval */
2129 /* If configuration is set to 0x04 then dont */
2130 /* disconnect all the station */
2131 else if ((pMac->roam.
2132 configParam.
2133 fAllowMCCGODiffBI ==
2134 0x02)
2135 || (pMac->roam.
2136 configParam.
2137 fAllowMCCGODiffBI
2138 == 0x04)) {
2139 /* Check to pass the right beacon Interval */
2140 if (pMac->roam.configParam.conc_custom_rule1 ||
2141 pMac->roam.configParam.conc_custom_rule2) {
2142 new_beaconInterval = CSR_CUSTOM_CONC_GO_BI;
2143 } else {
2144 new_beaconInterval =
2145 csr_calculate_mcc_beacon_interval(pMac,
2146 *beaconInterval,
2147 pMac->roam.
2148 roamSession
2149 [sessionId].
2150 bssParams.
2151 beaconInterval);
2152 }
2153 sms_log(pMac, LOG1,
2154 FL
2155 (" Peer AP BI : %d, new Beacon Interval: %d"),
2156 *beaconInterval,
2157 new_beaconInterval);
2158 /* Update the becon Interval */
2159 if (new_beaconInterval
2160 !=
2161 pMac->roam.
2162 roamSession
2163 [sessionId].
2164 bssParams.
2165 beaconInterval) {
2166 /* Update the beaconInterval now */
2167 sms_log(pMac,
2168 LOGE,
2169 FL
2170 (" Beacon Interval got changed config used: %d\n"),
2171 pMac->
2172 roam.
2173 configParam.
2174 fAllowMCCGODiffBI);
2175
2176 pMac->roam.
2177 roamSession
2178 [sessionId].
2179 bssParams.
2180 beaconInterval
2181 =
2182 new_beaconInterval;
2183 pMac->roam.
2184 roamSession
2185 [sessionId].
2186 bssParams.
2187 updatebeaconInterval
2188 = true;
2189 return
2190 csr_update_mcc_p2p_beacon_interval
2191 (pMac);
2192 }
2193 return
2194 CDF_STATUS_SUCCESS;
2195 }
2196 /* Disconnect the P2P session */
2197 else if (pMac->roam.configParam.
2198 fAllowMCCGODiffBI ==
2199 0x03) {
2200 pMac->roam.roamSession[sessionId].bssParams.updatebeaconInterval = false;
2201 return
2202 csr_roam_call_callback
2203 (pMac, sessionId,
2204 NULL, 0,
2205 eCSR_ROAM_SEND_P2P_STOP_BSS,
2206 eCSR_ROAM_RESULT_NONE);
2207 } else {
2208 sms_log(pMac, LOGE,
2209 FL
2210 ("BeaconInterval is different cannot connect to preferred AP..."));
2211 return
2212 CDF_STATUS_E_FAILURE;
2213 }
2214 }
2215 }
2216 break;
2217
2218 case CDF_P2P_CLIENT_MODE:
2219 if (pMac->roam.roamSession[sessionId].
2220 pCurRoamProfile &&
2221 (pMac->roam.roamSession[sessionId].
2222 pCurRoamProfile->csrPersona ==
2223 CDF_STA_MODE)) {
2224 /* check for P2P client mode */
2225 sms_log(pMac, LOG1,
2226 FL
2227 (" Ignore Beacon Interval Validation..."));
2228 } else if (pMac->roam.roamSession[sessionId].
2229 bssParams.bssPersona ==
2230 CDF_P2P_GO_MODE) {
2231 /* Check for P2P go scenario */
2232 if ((pMac->roam.roamSession[sessionId].
2233 bssParams.operationChn !=
2234 channelId)
2235 && (pMac->roam.
2236 roamSession[sessionId].
2237 bssParams.beaconInterval !=
2238 *beaconInterval)) {
2239 sms_log(pMac, LOGE,
2240 FL
2241 ("BeaconInterval is different cannot connect to P2P_GO network ..."));
2242 return CDF_STATUS_E_FAILURE;
2243 }
2244 }
2245 break;
2246
2247 case CDF_SAP_MODE:
2248 break;
2249
2250 case CDF_P2P_GO_MODE:
2251 {
2252 if (pMac->roam.roamSession[sessionId].
2253 pCurRoamProfile &&
2254 ((pMac->roam.roamSession[sessionId].
2255 pCurRoamProfile->csrPersona ==
2256 CDF_P2P_CLIENT_MODE) ||
2257 (pMac->roam.roamSession[sessionId].
2258 pCurRoamProfile->csrPersona ==
2259 CDF_STA_MODE))) {
2260 /* check for P2P_client scenario */
2261 if ((pMac->roam.
2262 roamSession[sessionId].
2263 connectedProfile.
2264 operationChannel == 0)
2265 && (pMac->roam.
2266 roamSession[sessionId].
2267 connectedProfile.
2268 beaconInterval == 0)) {
2269 continue;
2270 }
2271
2272 if (csr_is_conn_state_connected_infra
2273 (pMac, sessionId)
2274 && (pMac->roam.
2275 roamSession[sessionId].
2276 connectedProfile.
2277 operationChannel !=
2278 channelId)
2279 && (pMac->roam.
2280 roamSession[sessionId].
2281 connectedProfile.
2282 beaconInterval !=
2283 *beaconInterval)) {
2284 /*
2285 * Updated beaconInterval should be used only when we are starting a new BSS
2286 * not incase of client or STA case
2287 */
2288 /* Calculate beacon Interval for P2P-GO incase of MCC */
2289 if (pMac->roam.configParam.conc_custom_rule1 ||
2290 pMac->roam.configParam.conc_custom_rule2) {
2291 new_beaconInterval = CSR_CUSTOM_CONC_GO_BI;
2292 } else {
2293 new_beaconInterval =
2294 csr_calculate_mcc_beacon_interval
2295 (pMac,
2296 pMac->roam.
2297 roamSession
2298 [sessionId].
2299 connectedProfile.
2300 beaconInterval,
2301 *beaconInterval);
2302 }
2303 if (*beaconInterval !=
2304 new_beaconInterval)
2305 *beaconInterval
2306 =
2307 new_beaconInterval;
2308 return
2309 CDF_STATUS_SUCCESS;
2310 }
2311 }
2312 }
2313 break;
2314
2315 default:
2316 sms_log(pMac, LOGE,
2317 FL(" Persona not supported : %d"),
2318 currBssPersona);
2319 return CDF_STATUS_E_FAILURE;
2320 }
2321 }
2322 }
2323
2324 return CDF_STATUS_SUCCESS;
2325}
2326
2327#ifdef WLAN_FEATURE_VOWIFI_11R
2328/* Function to return true if the authtype is 11r */
2329bool csr_is_auth_type11r(eCsrAuthType AuthType, uint8_t mdiePresent)
2330{
2331 switch (AuthType) {
2332 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
2333 if (mdiePresent)
2334 return true;
2335 break;
2336 case eCSR_AUTH_TYPE_FT_RSN_PSK:
2337 case eCSR_AUTH_TYPE_FT_RSN:
2338 return true;
2339 break;
2340 default:
2341 break;
2342 }
2343 return false;
2344}
2345
2346/* Function to return true if the profile is 11r */
2347bool csr_is_profile11r(tCsrRoamProfile *pProfile)
2348{
2349 return csr_is_auth_type11r(pProfile->negotiatedAuthType,
2350 pProfile->MDID.mdiePresent);
2351}
2352
2353#endif
2354
2355#ifdef FEATURE_WLAN_ESE
2356
2357/* Function to return true if the authtype is ESE */
2358bool csr_is_auth_type_ese(eCsrAuthType AuthType)
2359{
2360 switch (AuthType) {
2361 case eCSR_AUTH_TYPE_CCKM_WPA:
2362 case eCSR_AUTH_TYPE_CCKM_RSN:
2363 return true;
2364 break;
2365 default:
2366 break;
2367 }
2368 return false;
2369}
2370
2371/* Function to return true if the profile is ESE */
2372bool csr_is_profile_ese(tCsrRoamProfile *pProfile)
2373{
2374 return csr_is_auth_type_ese(pProfile->negotiatedAuthType);
2375}
2376
2377#endif
2378
2379#ifdef FEATURE_WLAN_WAPI
2380bool csr_is_profile_wapi(tCsrRoamProfile *pProfile)
2381{
2382 bool fWapiProfile = false;
2383
2384 switch (pProfile->negotiatedAuthType) {
2385 case eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE:
2386 case eCSR_AUTH_TYPE_WAPI_WAI_PSK:
2387 fWapiProfile = true;
2388 break;
2389
2390 default:
2391 fWapiProfile = false;
2392 break;
2393 }
2394
2395 if (fWapiProfile) {
2396 switch (pProfile->negotiatedUCEncryptionType) {
2397 case eCSR_ENCRYPT_TYPE_WPI:
2398 fWapiProfile = true;
2399 break;
2400
2401 default:
2402 fWapiProfile = false;
2403 break;
2404 }
2405 }
2406 return fWapiProfile;
2407}
2408
2409static bool csr_is_wapi_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
2410 uint8_t *Oui2)
2411{
2412 return cdf_mem_compare(Oui1, Oui2, CSR_WAPI_OUI_SIZE);
2413}
2414
2415static bool csr_is_wapi_oui_match(tpAniSirGlobal pMac,
2416 uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
2417 uint8_t cAllCyphers, uint8_t Cypher[],
2418 uint8_t Oui[])
2419{
2420 bool fYes = false;
2421 uint8_t idx;
2422
2423 for (idx = 0; idx < cAllCyphers; idx++) {
2424 if (csr_is_wapi_oui_equal(pMac, AllCyphers[idx], Cypher)) {
2425 fYes = true;
2426 break;
2427 }
2428 }
2429
2430 if (fYes && Oui) {
2431 cdf_mem_copy(Oui, AllCyphers[idx], CSR_WAPI_OUI_SIZE);
2432 }
2433
2434 return fYes;
2435}
2436#endif /* FEATURE_WLAN_WAPI */
2437
2438static bool csr_is_wpa_oui_equal(tpAniSirGlobal pMac, uint8_t *Oui1,
2439 uint8_t *Oui2)
2440{
2441 return cdf_mem_compare(Oui1, Oui2, CSR_WPA_OUI_SIZE);
2442}
2443
2444static bool csr_is_oui_match(tpAniSirGlobal pMac,
2445 uint8_t AllCyphers[][CSR_WPA_OUI_SIZE],
2446 uint8_t cAllCyphers, uint8_t Cypher[], uint8_t Oui[])
2447{
2448 bool fYes = false;
2449 uint8_t idx;
2450
2451 for (idx = 0; idx < cAllCyphers; idx++) {
2452 if (csr_is_wpa_oui_equal(pMac, AllCyphers[idx], Cypher)) {
2453 fYes = true;
2454 break;
2455 }
2456 }
2457
2458 if (fYes && Oui) {
2459 cdf_mem_copy(Oui, AllCyphers[idx], CSR_WPA_OUI_SIZE);
2460 }
2461
2462 return fYes;
2463}
2464
2465static bool csr_match_rsnoui_index(tpAniSirGlobal pMac,
2466 uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
2467 uint8_t cAllCyphers, uint8_t ouiIndex,
2468 uint8_t Oui[])
2469{
2470 return csr_is_oui_match
2471 (pMac, AllCyphers, cAllCyphers, csr_rsn_oui[ouiIndex], Oui);
2472
2473}
2474
2475#ifdef FEATURE_WLAN_WAPI
2476static bool csr_match_wapi_oui_index(tpAniSirGlobal pMac,
2477 uint8_t AllCyphers[][CSR_WAPI_OUI_SIZE],
2478 uint8_t cAllCyphers, uint8_t ouiIndex,
2479 uint8_t Oui[])
2480{
2481 return csr_is_wapi_oui_match
2482 (pMac, AllCyphers, cAllCyphers, csr_wapi_oui[ouiIndex], Oui);
2483
2484}
2485#endif /* FEATURE_WLAN_WAPI */
2486
2487static bool csr_match_wpaoui_index(tpAniSirGlobal pMac,
2488 uint8_t AllCyphers[][CSR_RSN_OUI_SIZE],
2489 uint8_t cAllCyphers, uint8_t ouiIndex,
2490 uint8_t Oui[])
2491{
2492 return csr_is_oui_match
2493 (pMac, AllCyphers, cAllCyphers, csr_wpa_oui[ouiIndex], Oui);
2494
2495}
2496
2497#ifdef FEATURE_WLAN_WAPI
2498static bool csr_is_auth_wapi_cert(tpAniSirGlobal pMac,
2499 uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
2500 uint8_t cAllSuites, uint8_t Oui[])
2501{
2502 return csr_is_wapi_oui_match
2503 (pMac, AllSuites, cAllSuites, csr_wapi_oui[1], Oui);
2504}
2505
2506static bool csr_is_auth_wapi_psk(tpAniSirGlobal pMac,
2507 uint8_t AllSuites[][CSR_WAPI_OUI_SIZE],
2508 uint8_t cAllSuites, uint8_t Oui[])
2509{
2510 return csr_is_wapi_oui_match
2511 (pMac, AllSuites, cAllSuites, csr_wapi_oui[2], Oui);
2512}
2513#endif /* FEATURE_WLAN_WAPI */
2514
2515#ifdef WLAN_FEATURE_VOWIFI_11R
2516
2517/*
2518 * Function for 11R FT Authentication. We match the FT Authentication Cipher
2519 * suite here. This matches for FT Auth with the 802.1X exchange.
2520 */
2521static bool csr_is_ft_auth_rsn(tpAniSirGlobal pMac,
2522 uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2523 uint8_t cAllSuites, uint8_t Oui[])
2524{
2525 return csr_is_oui_match
2526 (pMac, AllSuites, cAllSuites, csr_rsn_oui[03], Oui);
2527}
2528
2529/*
2530 * Function for 11R FT Authentication. We match the FT Authentication Cipher
2531 * suite here. This matches for FT Auth with the PSK.
2532 */
2533static bool csr_is_ft_auth_rsn_psk(tpAniSirGlobal pMac,
2534 uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2535 uint8_t cAllSuites, uint8_t Oui[])
2536{
2537 return csr_is_oui_match
2538 (pMac, AllSuites, cAllSuites, csr_rsn_oui[04], Oui);
2539}
2540
2541#endif
2542
2543#ifdef FEATURE_WLAN_ESE
2544
2545/*
2546 * Function for ESE CCKM AKM Authentication. We match the CCKM AKM
2547 * Authentication Key Management suite here. This matches for CCKM AKM Auth
2548 * with the 802.1X exchange.
2549 */
2550static bool csr_is_ese_cckm_auth_rsn(tpAniSirGlobal pMac,
2551 uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2552 uint8_t cAllSuites, uint8_t Oui[])
2553{
2554 return csr_is_oui_match
2555 (pMac, AllSuites, cAllSuites, csr_rsn_oui[06], Oui);
2556}
2557
2558static bool csr_is_ese_cckm_auth_wpa(tpAniSirGlobal pMac,
2559 uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
2560 uint8_t cAllSuites, uint8_t Oui[])
2561{
2562 return csr_is_oui_match
2563 (pMac, AllSuites, cAllSuites, csr_wpa_oui[06], Oui);
2564}
2565
2566#endif
2567
2568static bool csr_is_auth_rsn(tpAniSirGlobal pMac,
2569 uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2570 uint8_t cAllSuites, uint8_t Oui[])
2571{
2572 return csr_is_oui_match
2573 (pMac, AllSuites, cAllSuites, csr_rsn_oui[01], Oui);
2574}
2575
2576static bool csr_is_auth_rsn_psk(tpAniSirGlobal pMac,
2577 uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2578 uint8_t cAllSuites, uint8_t Oui[])
2579{
2580 return csr_is_oui_match
2581 (pMac, AllSuites, cAllSuites, csr_rsn_oui[02], Oui);
2582}
2583
2584#ifdef WLAN_FEATURE_11W
2585static bool csr_is_auth_rsn_psk_sha256(tpAniSirGlobal pMac,
2586 uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2587 uint8_t cAllSuites, uint8_t Oui[])
2588{
2589 return csr_is_oui_match
2590 (pMac, AllSuites, cAllSuites, csr_rsn_oui[07], Oui);
2591}
2592static bool csr_is_auth_rsn8021x_sha256(tpAniSirGlobal pMac,
2593 uint8_t AllSuites[][CSR_RSN_OUI_SIZE],
2594 uint8_t cAllSuites, uint8_t Oui[])
2595{
2596 return csr_is_oui_match
2597 (pMac, AllSuites, cAllSuites, csr_rsn_oui[8], Oui);
2598}
2599#endif
2600
2601static bool csr_is_auth_wpa(tpAniSirGlobal pMac,
2602 uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
2603 uint8_t cAllSuites, uint8_t Oui[])
2604{
2605 return csr_is_oui_match
2606 (pMac, AllSuites, cAllSuites, csr_wpa_oui[01], Oui);
2607}
2608
2609static bool csr_is_auth_wpa_psk(tpAniSirGlobal pMac,
2610 uint8_t AllSuites[][CSR_WPA_OUI_SIZE],
2611 uint8_t cAllSuites, uint8_t Oui[])
2612{
2613 return csr_is_oui_match
2614 (pMac, AllSuites, cAllSuites, csr_wpa_oui[02], Oui);
2615}
2616
2617uint8_t csr_get_oui_index_from_cipher(eCsrEncryptionType enType)
2618{
2619 uint8_t OUIIndex;
2620
2621 switch (enType) {
2622 case eCSR_ENCRYPT_TYPE_WEP40:
2623 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
2624 OUIIndex = CSR_OUI_WEP40_OR_1X_INDEX;
2625 break;
2626 case eCSR_ENCRYPT_TYPE_WEP104:
2627 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
2628 OUIIndex = CSR_OUI_WEP104_INDEX;
2629 break;
2630 case eCSR_ENCRYPT_TYPE_TKIP:
2631 OUIIndex = CSR_OUI_TKIP_OR_PSK_INDEX;
2632 break;
2633 case eCSR_ENCRYPT_TYPE_AES:
2634 OUIIndex = CSR_OUI_AES_INDEX;
2635 break;
2636 case eCSR_ENCRYPT_TYPE_NONE:
2637 OUIIndex = CSR_OUI_USE_GROUP_CIPHER_INDEX;
2638 break;
2639#ifdef FEATURE_WLAN_WAPI
2640 case eCSR_ENCRYPT_TYPE_WPI:
2641 OUIIndex = CSR_OUI_WAPI_WAI_CERT_OR_SMS4_INDEX;
2642 break;
2643#endif /* FEATURE_WLAN_WAPI */
2644 default: /* HOWTO handle this? */
2645 OUIIndex = CSR_OUI_RESERVED_INDEX;
2646 break;
2647 } /* switch */
2648
2649 return OUIIndex;
2650}
2651/**
2652 * csr_get_rsn_information() - to get RSN infomation
2653 * @hal: pointer to HAL
2654 * @auth_type: auth type
2655 * @encr_type: encryption type
2656 * @mc_encryption: multicast encryption type
2657 * @rsn_ie: pointer to RSN IE
2658 * @ucast_cipher: Unicast cipher
2659 * @mcast_cipher: Multicast cipher
2660 * @auth_suite: Authentication suite
2661 * @capabilities: RSN capabilities
2662 * @negotiated_authtype: Negotiated auth type
2663 * @negotiated_mccipher: negotiated multicast cipher
2664 *
2665 * This routine will get all RSN information
2666 *
2667 * Return: bool
2668 */
2669bool csr_get_rsn_information(tHalHandle hal, tCsrAuthList *auth_type,
2670 eCsrEncryptionType encr_type,
2671 tCsrEncryptionList *mc_encryption,
2672 tDot11fIERSN *rsn_ie, uint8_t *ucast_cipher,
2673 uint8_t *mcast_cipher, uint8_t *auth_suite,
2674 tCsrRSNCapabilities *capabilities,
2675 eCsrAuthType *negotiated_authtype,
2676 eCsrEncryptionType *negotiated_mccipher)
2677{
2678 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
2679 bool acceptable_cipher = false;
2680 uint8_t c_ucast_cipher = 0;
2681 uint8_t c_mcast_cipher = 0;
2682 uint8_t c_auth_suites = 0, i;
2683 uint8_t unicast[CSR_RSN_OUI_SIZE];
2684 uint8_t multicast[CSR_RSN_OUI_SIZE];
2685 uint8_t authsuites[CSR_RSN_MAX_AUTH_SUITES][CSR_RSN_OUI_SIZE];
2686 uint8_t authentication[CSR_RSN_OUI_SIZE];
2687 uint8_t mccipher_arr[CSR_RSN_MAX_MULTICAST_CYPHERS][CSR_RSN_OUI_SIZE];
2688 eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
2689
2690 if (!rsn_ie->present)
2691 goto end;
2692 c_mcast_cipher++;
2693 cdf_mem_copy(mccipher_arr, rsn_ie->gp_cipher_suite,
2694 CSR_RSN_OUI_SIZE);
2695 c_ucast_cipher =
2696 (uint8_t) (rsn_ie->pwise_cipher_suite_count);
2697 c_auth_suites = (uint8_t) (rsn_ie->akm_suite_count);
2698 for (i = 0; i < c_auth_suites && i < CSR_RSN_MAX_AUTH_SUITES; i++) {
2699 cdf_mem_copy((void *)&authsuites[i],
2700 (void *)&rsn_ie->akm_suites[i], CSR_RSN_OUI_SIZE);
2701 }
2702
2703 /* Check - Is requested unicast Cipher supported by the BSS. */
2704 acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
2705 rsn_ie->pwise_cipher_suites, c_ucast_cipher,
2706 csr_get_oui_index_from_cipher(encr_type),
2707 unicast);
2708
2709 if (!acceptable_cipher)
2710 goto end;
2711
2712 /* unicast is supported. Pick the first matching Group cipher, if any */
2713 for (i = 0; i < mc_encryption->numEntries; i++) {
2714 acceptable_cipher = csr_match_rsnoui_index(mac_ctx,
2715 mccipher_arr, c_mcast_cipher,
2716 csr_get_oui_index_from_cipher(
2717 mc_encryption->encryptionType[i]),
2718 multicast);
2719 if (acceptable_cipher)
2720 break;
2721 }
2722 if (!acceptable_cipher)
2723 goto end;
2724
2725 if (negotiated_mccipher)
2726 *negotiated_mccipher = mc_encryption->encryptionType[i];
2727
2728 /* Initializing with false as it has true value already */
2729 acceptable_cipher = false;
2730 for (i = 0; i < auth_type->numEntries; i++) {
2731 /*
2732 * Ciphers are supported, Match authentication algorithm and
2733 * pick first matching authtype.
2734 */
2735#ifdef WLAN_FEATURE_VOWIFI_11R
2736 /* Changed the AKM suites according to order of preference */
2737 if (csr_is_ft_auth_rsn(mac_ctx, authsuites,
2738 c_auth_suites, authentication)) {
2739 if (eCSR_AUTH_TYPE_FT_RSN == auth_type->authType[i])
2740 neg_authtype = eCSR_AUTH_TYPE_FT_RSN;
2741 }
2742 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2743 && csr_is_ft_auth_rsn_psk(mac_ctx, authsuites,
2744 c_auth_suites, authentication)) {
2745 if (eCSR_AUTH_TYPE_FT_RSN_PSK ==
2746 auth_type->authType[i])
2747 neg_authtype = eCSR_AUTH_TYPE_FT_RSN_PSK;
2748 }
2749#endif
2750#ifdef FEATURE_WLAN_ESE
2751 /* ESE only supports 802.1X. No PSK. */
2752 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
2753 csr_is_ese_cckm_auth_rsn(mac_ctx, authsuites,
2754 c_auth_suites, authentication)) {
2755 if (eCSR_AUTH_TYPE_CCKM_RSN == auth_type->authType[i])
2756 neg_authtype = eCSR_AUTH_TYPE_CCKM_RSN;
2757 }
2758#endif
2759 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2760 && csr_is_auth_rsn(mac_ctx, authsuites,
2761 c_auth_suites, authentication)) {
2762 if (eCSR_AUTH_TYPE_RSN == auth_type->authType[i])
2763 neg_authtype = eCSR_AUTH_TYPE_RSN;
2764 }
2765 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2766 && csr_is_auth_rsn_psk(mac_ctx, authsuites,
2767 c_auth_suites, authentication)) {
2768 if (eCSR_AUTH_TYPE_RSN_PSK == auth_type->authType[i])
2769 neg_authtype = eCSR_AUTH_TYPE_RSN_PSK;
2770 }
2771#ifdef WLAN_FEATURE_11W
2772 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
2773 && csr_is_auth_rsn_psk_sha256(mac_ctx, authsuites,
2774 c_auth_suites, authentication)) {
2775 if (eCSR_AUTH_TYPE_RSN_PSK_SHA256 ==
2776 auth_type->authType[i])
2777 neg_authtype = eCSR_AUTH_TYPE_RSN_PSK_SHA256;
2778 }
2779 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
2780 csr_is_auth_rsn8021x_sha256(mac_ctx, authsuites,
2781 c_auth_suites, authentication)) {
2782 if (eCSR_AUTH_TYPE_RSN_8021X_SHA256 ==
2783 auth_type->authType[i])
2784 neg_authtype = eCSR_AUTH_TYPE_RSN_8021X_SHA256;
2785 }
2786#endif
2787
2788 /*
2789 * The 1st auth type in the APs RSN IE, to match stations
2790 * connecting profiles auth type will cause us to exit this
2791 * loop. This is added as some APs advertise multiple akms in
2792 * the RSN IE
2793 */
2794 if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
2795 acceptable_cipher = true;
2796 break;
2797 }
2798 } /* for */
2799end:
2800 if (acceptable_cipher) {
2801 if (mcast_cipher)
2802 cdf_mem_copy(mcast_cipher, multicast,
2803 CSR_RSN_OUI_SIZE);
2804
2805 if (ucast_cipher)
2806 cdf_mem_copy(ucast_cipher, unicast, CSR_RSN_OUI_SIZE);
2807
2808 if (auth_suite)
2809 cdf_mem_copy(auth_suite, authentication,
2810 CSR_RSN_OUI_SIZE);
2811
2812 if (negotiated_authtype)
2813 *negotiated_authtype = neg_authtype;
2814
2815 if (capabilities) {
2816 /* Bit 0 Preauthentication */
2817 capabilities->PreAuthSupported =
2818 (rsn_ie->RSN_Cap[0] >> 0) & 0x1;
2819 /* Bit 1 No Pairwise */
2820 capabilities->NoPairwise =
2821 (rsn_ie->RSN_Cap[0] >> 1) & 0x1;
2822 /* Bit 2, 3 PTKSA Replay Counter */
2823 capabilities->PTKSAReplayCounter =
2824 (rsn_ie->RSN_Cap[0] >> 2) & 0x3;
2825 /* Bit 4, 5 GTKSA Replay Counter */
2826 capabilities->GTKSAReplayCounter =
2827 (rsn_ie->RSN_Cap[0] >> 4) & 0x3;
2828#ifdef WLAN_FEATURE_11W
2829 /* Bit 6 MFPR */
2830 capabilities->MFPRequired =
2831 (rsn_ie->RSN_Cap[0] >> 6) & 0x1;
2832 /* Bit 7 MFPC */
2833 capabilities->MFPCapable =
2834 (rsn_ie->RSN_Cap[0] >> 7) & 0x1;
2835#else
2836 /* Bit 6 MFPR */
2837 capabilities->MFPRequired = 0;
2838 /* Bit 7 MFPC */
2839 capabilities->MFPCapable = 0;
2840#endif
2841 /* remaining reserved */
2842 capabilities->Reserved = rsn_ie->RSN_Cap[1] & 0xff;
2843 }
2844 }
2845 return acceptable_cipher;
2846}
2847
2848#ifdef WLAN_FEATURE_11W
2849/**
2850 * csr_is_pmf_capabilities_in_rsn_match() - check for PMF capability
2851 * @hHal: Global HAL handle
2852 * @pFilterMFPEnabled: given by supplicant to us to specify what kind
2853 * of connection supplicant is expecting to make
2854 * if it is enabled then make PMF connection.
2855 * if it is disabled then make normal connection.
2856 * @pFilterMFPRequired: given by supplicant based on our configuration
2857 * if it is 1 then we will require mandatory
2858 * PMF connection and if it is 0 then we PMF
2859 * connection is optional.
2860 * @pFilterMFPCapable: given by supplicant based on our configuration
2861 * if it 1 then we are PMF capable and if it 0
2862 * then we are not PMF capable.
2863 * @pRSNIe: RSNIe from Beacon/probe response of
2864 * neighbor AP against which we will compare
2865 * our capabilities.
2866 *
2867 * This function is to match our current capabilities with the AP
2868 * to which we are expecting make the connection.
2869 *
2870 * Return: if our PMF capabilities matches with AP then we
2871 * will return true to indicate that we are good
2872 * to make connection with it. Else we will return false
2873 **/
2874static bool
2875csr_is_pmf_capabilities_in_rsn_match(tHalHandle hHal,
2876 bool *pFilterMFPEnabled,
2877 uint8_t *pFilterMFPRequired,
2878 uint8_t *pFilterMFPCapable,
2879 tDot11fIERSN *pRSNIe)
2880{
2881 uint8_t apProfileMFPCapable = 0;
2882 uint8_t apProfileMFPRequired = 0;
2883 if (pRSNIe && pFilterMFPEnabled && pFilterMFPCapable
2884 && pFilterMFPRequired) {
2885 /* Extracting MFPCapable bit from RSN Ie */
2886 apProfileMFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1;
2887 apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1;
2888 if (*pFilterMFPEnabled && *pFilterMFPCapable
2889 && *pFilterMFPRequired && (apProfileMFPCapable == 0)) {
2890 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
2891 "AP is not capable to make PMF connection");
2892 return false;
2893 } else if (*pFilterMFPEnabled && *pFilterMFPCapable &&
2894 !(*pFilterMFPRequired) &&
2895 (apProfileMFPCapable == 0)) {
2896 /*
2897 * This is tricky, because supplicant asked us to
2898 * make mandatory PMF connection eventhough PMF
2899 * connection is optional here.
2900 * so if AP is not capable of PMF then drop it.
2901 * Don't try to connect with it.
2902 */
2903 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
2904 "we need PMF connection & AP isn't capable to make PMF connection");
2905 return false;
2906 } else if (!(*pFilterMFPCapable) &&
2907 apProfileMFPCapable && apProfileMFPRequired) {
2908
2909 /*
2910 * In this case, AP with whom we trying to connect
2911 * requires mandatory PMF connections and we are not
2912 * capable so this AP is not good choice to connect
2913 */
2914 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
2915 "AP needs PMF connection and we are not capable of pmf connection");
2916 return false;
2917 } else if (!(*pFilterMFPEnabled) && *pFilterMFPCapable &&
2918 (apProfileMFPCapable == 1)) {
2919 CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_INFO,
2920 "we don't need PMF connection even though both parties are capable");
2921 return false;
2922 }
2923 }
2924 return true;
2925}
2926#endif
2927
2928bool csr_is_rsn_match(tHalHandle hHal, tCsrAuthList *pAuthType,
2929 eCsrEncryptionType enType,
2930 tCsrEncryptionList *pEnMcType,
2931 bool *pMFPEnabled, uint8_t *pMFPRequired,
2932 uint8_t *pMFPCapable,
2933 tDot11fBeaconIEs *pIes,
2934 eCsrAuthType *pNegotiatedAuthType,
2935 eCsrEncryptionType *pNegotiatedMCCipher)
2936{
2937 bool fRSNMatch = false;
2938
2939 /* See if the cyphers in the Bss description match with the settings in the profile. */
2940 fRSNMatch =
2941 csr_get_rsn_information(hHal, pAuthType, enType, pEnMcType, &pIes->RSN,
2942 NULL, NULL, NULL, NULL, pNegotiatedAuthType,
2943 pNegotiatedMCCipher);
2944#ifdef WLAN_FEATURE_11W
2945 /* If all the filter matches then finally checks for PMF capabilities */
2946 if (fRSNMatch) {
2947 fRSNMatch = csr_is_pmf_capabilities_in_rsn_match(hHal, pMFPEnabled,
2948 pMFPRequired,
2949 pMFPCapable,
2950 &pIes->RSN);
2951 }
2952#endif
2953 return fRSNMatch;
2954}
2955
2956bool csr_lookup_pmkid(tpAniSirGlobal pMac, uint32_t sessionId, uint8_t *pBSSId,
2957 uint8_t *pPMKId)
2958{
2959 bool fRC = false, fMatchFound = false;
2960 uint32_t Index;
2961 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
2962
2963 if (!pSession) {
2964 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
2965 return false;
2966 }
2967
2968 do {
2969 for (Index = 0; Index < CSR_MAX_PMKID_ALLOWED; Index++) {
2970 sms_log(pMac, LOG1,
2971 "match PMKID " MAC_ADDRESS_STR " to ",
2972 MAC_ADDR_ARRAY(pBSSId));
2973 if (cdf_mem_compare
2974 (pBSSId, pSession->PmkidCacheInfo[Index].BSSID.bytes,
2975 sizeof(struct cdf_mac_addr))) {
2976 /* match found */
2977 fMatchFound = true;
2978 break;
2979 }
2980 }
2981
2982 if (!fMatchFound)
2983 break;
2984
2985 cdf_mem_copy(pPMKId, pSession->PmkidCacheInfo[Index].PMKID,
2986 CSR_RSN_PMKID_SIZE);
2987
2988 fRC = true;
2989 } while (0);
2990 sms_log(pMac, LOGW,
2991 "csr_lookup_pmkid called return match = %d pMac->roam.NumPmkidCache = %d",
2992 fRC, pSession->NumPmkidCache);
2993
2994 return fRC;
2995}
2996
2997uint8_t csr_construct_rsn_ie(tHalHandle hHal, uint32_t sessionId,
2998 tCsrRoamProfile *pProfile,
2999 tSirBssDescription *pSirBssDesc,
3000 tDot11fBeaconIEs *pIes, tCsrRSNIe *pRSNIe)
3001{
3002 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3003 bool fRSNMatch;
3004 uint8_t cbRSNIe = 0;
3005 uint8_t UnicastCypher[CSR_RSN_OUI_SIZE];
3006 uint8_t MulticastCypher[CSR_RSN_OUI_SIZE];
3007 uint8_t AuthSuite[CSR_RSN_OUI_SIZE];
3008 tCsrRSNAuthIe *pAuthSuite;
3009 tCsrRSNCapabilities RSNCapabilities;
3010 tCsrRSNPMKIe *pPMK;
3011 uint8_t PMKId[CSR_RSN_PMKID_SIZE];
3012#ifdef WLAN_FEATURE_11W
3013 uint8_t *pGroupMgmtCipherSuite;
3014#endif
3015 tDot11fBeaconIEs *pIesLocal = pIes;
3016 eCsrAuthType negAuthType = eCSR_AUTH_TYPE_UNKNOWN;
3017
3018 sms_log(pMac, LOGW, "%s called...", __func__);
3019
3020 do {
3021 if (!csr_is_profile_rsn(pProfile))
3022 break;
3023
3024 if (!pIesLocal
3025 &&
3026 (!CDF_IS_STATUS_SUCCESS
3027 (csr_get_parsed_bss_description_ies
3028 (pMac, pSirBssDesc, &pIesLocal)))) {
3029 break;
3030 }
3031 /* See if the cyphers in the Bss description match with the settings in the profile. */
3032 fRSNMatch =
3033 csr_get_rsn_information(hHal, &pProfile->AuthType,
3034 pProfile->negotiatedUCEncryptionType,
3035 &pProfile->mcEncryptionType,
3036 &pIesLocal->RSN, UnicastCypher,
3037 MulticastCypher, AuthSuite,
3038 &RSNCapabilities, &negAuthType, NULL);
3039 if (!fRSNMatch)
3040 break;
3041
3042 pRSNIe->IeHeader.ElementID = SIR_MAC_RSN_EID;
3043
3044 pRSNIe->Version = CSR_RSN_VERSION_SUPPORTED;
3045
3046 cdf_mem_copy(pRSNIe->MulticastOui, MulticastCypher,
3047 sizeof(MulticastCypher));
3048
3049 pRSNIe->cUnicastCyphers = 1;
3050
3051 cdf_mem_copy(&pRSNIe->UnicastOui[0], UnicastCypher,
3052 sizeof(UnicastCypher));
3053
3054 pAuthSuite =
3055 (tCsrRSNAuthIe *) (&pRSNIe->
3056 UnicastOui[pRSNIe->cUnicastCyphers]);
3057
3058 pAuthSuite->cAuthenticationSuites = 1;
3059 cdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
3060 sizeof(AuthSuite));
3061
3062 /* RSN capabilities follows the Auth Suite (two octects) */
3063 /* !!REVIEW - What should STA put in RSN capabilities, currently */
3064 /* just putting back APs capabilities */
3065 /* For one, we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability */
3066 /* For another, we should use the Management Frame Protection values given by the supplicant */
3067 RSNCapabilities.PreAuthSupported = 0;
3068#ifdef WLAN_FEATURE_11W
3069 if (RSNCapabilities.MFPCapable && pProfile->MFPCapable) {
3070 RSNCapabilities.MFPCapable = pProfile->MFPCapable;
3071 RSNCapabilities.MFPRequired = pProfile->MFPRequired;
3072 } else {
3073 RSNCapabilities.MFPCapable = 0;
3074 RSNCapabilities.MFPRequired = 0;
3075 }
3076#endif
3077 *(uint16_t *) (&pAuthSuite->AuthOui[1]) =
3078 *((uint16_t *) (&RSNCapabilities));
3079
3080 pPMK =
3081 (tCsrRSNPMKIe *) (((uint8_t *) (&pAuthSuite->AuthOui[1])) +
3082 sizeof(uint16_t));
3083
3084 /* Don't include the PMK SA IDs for CCKM associations. */
3085 if (
3086#ifdef FEATURE_WLAN_ESE
3087 (eCSR_AUTH_TYPE_CCKM_RSN != negAuthType) &&
3088#endif
3089 csr_lookup_pmkid(pMac, sessionId, pSirBssDesc->bssId,
3090 &(PMKId[0]))) {
3091 pPMK->cPMKIDs = 1;
3092
3093 cdf_mem_copy(pPMK->PMKIDList[0].PMKID, PMKId,
3094 CSR_RSN_PMKID_SIZE);
3095 } else {
3096 pPMK->cPMKIDs = 0;
3097 }
3098
3099#ifdef WLAN_FEATURE_11W
3100 if (pProfile->MFPEnabled) {
3101 pGroupMgmtCipherSuite =
3102 (uint8_t *) pPMK + sizeof(uint16_t) +
3103 (pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE);
3104 cdf_mem_copy(pGroupMgmtCipherSuite, csr_rsn_oui[07],
3105 CSR_WPA_OUI_SIZE);
3106 }
3107#endif
3108
3109 /* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */
3110 /* Add in the size of the Auth suite (count plus a single OUI) */
3111 /* Add in the RSN caps field. */
3112 /* Add PMKID count and PMKID (if any) */
3113 /* Add group management cipher suite */
3114 pRSNIe->IeHeader.Length =
3115 (uint8_t) (sizeof(*pRSNIe) - sizeof(pRSNIe->IeHeader) +
3116 sizeof(*pAuthSuite) +
3117 sizeof(tCsrRSNCapabilities));
3118 if (pPMK->cPMKIDs) {
3119 pRSNIe->IeHeader.Length += (uint8_t) (sizeof(uint16_t) +
3120 (pPMK->cPMKIDs *
3121 CSR_RSN_PMKID_SIZE));
3122 }
3123#ifdef WLAN_FEATURE_11W
3124 if (pProfile->MFPEnabled) {
3125 if (0 == pPMK->cPMKIDs)
3126 pRSNIe->IeHeader.Length += sizeof(uint16_t);
3127 pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE;
3128 }
3129#endif
3130
3131 /* return the size of the IE header (total) constructed... */
3132 cbRSNIe = pRSNIe->IeHeader.Length + sizeof(pRSNIe->IeHeader);
3133
3134 } while (0);
3135
3136 if (!pIes && pIesLocal) {
3137 /* locally allocated */
3138 cdf_mem_free(pIesLocal);
3139 }
3140
3141 return cbRSNIe;
3142}
3143
3144#ifdef FEATURE_WLAN_WAPI
3145/**
3146 * csr_get_wapi_information() - to get WAPI infomation
3147 * @hal: pointer to HAL
3148 * @auth_type: auth type
3149 * @encr_type: encryption type
3150 * @mc_encryption: multicast encryption type
3151 * @wapi_ie: pointer to WAPI IE
3152 * @ucast_cipher: Unicast cipher
3153 * @mcast_cipher: Multicast cipher
3154 * @auth_suite: Authentication suite
3155 * @negotiated_authtype: Negotiated auth type
3156 * @negotiated_mccipher: negotiated multicast cipher
3157 *
3158 * This routine will get all WAPI information
3159 *
3160 * Return: bool
3161 */
3162bool csr_get_wapi_information(tHalHandle hal, tCsrAuthList *auth_type,
3163 eCsrEncryptionType encr_type,
3164 tCsrEncryptionList *mc_encryption,
3165 tDot11fIEWAPI *wapi_ie, uint8_t *ucast_cipher,
3166 uint8_t *mcast_cipher, uint8_t *auth_suite,
3167 eCsrAuthType *negotiated_authtype,
3168 eCsrEncryptionType *negotiated_mccipher)
3169{
3170 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
3171 bool acceptable_cipher = false;
3172 uint8_t c_ucast_cipher = 0;
3173 uint8_t c_mcast_cipher = 0;
3174 uint8_t c_auth_suites = 0, i;
3175 uint8_t unicast[CSR_WAPI_OUI_SIZE];
3176 uint8_t multicast[CSR_WAPI_OUI_SIZE];
3177 uint8_t authsuites[CSR_WAPI_MAX_AUTH_SUITES][CSR_WAPI_OUI_SIZE];
3178 uint8_t authentication[CSR_WAPI_OUI_SIZE];
3179 uint8_t mccipher_arr[CSR_WAPI_MAX_MULTICAST_CYPHERS][CSR_WAPI_OUI_SIZE];
3180 eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
3181 uint8_t wapioui_idx = 0;
3182
3183 if (!wapi_ie->present)
3184 goto end;
3185
3186 c_mcast_cipher++;
3187 cdf_mem_copy(mccipher_arr, wapi_ie->multicast_cipher_suite,
3188 CSR_WAPI_OUI_SIZE);
3189 c_ucast_cipher = (uint8_t) (wapi_ie->unicast_cipher_suite_count);
3190 c_auth_suites = (uint8_t) (wapi_ie->akm_suite_count);
3191 for (i = 0; i < c_auth_suites && i < CSR_WAPI_MAX_AUTH_SUITES; i++)
3192 cdf_mem_copy((void *)&authsuites[i],
3193 (void *)&wapi_ie->akm_suites[i], CSR_WAPI_OUI_SIZE);
3194
3195 wapioui_idx = csr_get_oui_index_from_cipher(encr_type);
3196 if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
3197 sms_log(mac_ctx, LOGE,
3198 FL("Wapi OUI index = %d out of limit"),
3199 wapioui_idx);
3200 acceptable_cipher = false;
3201 goto end;
3202 }
3203 /* Check - Is requested unicast Cipher supported by the BSS. */
3204 acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
3205 wapi_ie->unicast_cipher_suites,
3206 c_ucast_cipher, wapioui_idx, unicast);
3207 if (!acceptable_cipher)
3208 goto end;
3209
3210 /* unicast is supported. Pick the first matching Group cipher, if any */
3211 for (i = 0; i < mc_encryption->numEntries; i++) {
3212 wapioui_idx = csr_get_oui_index_from_cipher(
3213 mc_encryption->encryptionType[i]);
3214 if (wapioui_idx >= CSR_OUI_WAPI_WAI_MAX_INDEX) {
3215 sms_log(mac_ctx, LOGE,
3216 FL("Wapi OUI index = %d out of limit"),
3217 wapioui_idx);
3218 acceptable_cipher = false;
3219 break;
3220 }
3221 acceptable_cipher = csr_match_wapi_oui_index(mac_ctx,
3222 mccipher_arr, c_mcast_cipher,
3223 wapioui_idx, multicast);
3224 if (acceptable_cipher)
3225 break;
3226 }
3227 if (!acceptable_cipher)
3228 goto end;
3229
3230 if (negotiated_mccipher)
3231 *negotiated_mccipher =
3232 mc_encryption->encryptionType[i];
3233
3234 /*
3235 * Ciphers are supported, Match authentication algorithm and
3236 * pick first matching authtype
3237 */
3238 if (csr_is_auth_wapi_cert
3239 (mac_ctx, authsuites, c_auth_suites, authentication)) {
3240 neg_authtype =
3241 eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
3242 } else if (csr_is_auth_wapi_psk(mac_ctx, authsuites,
3243 c_auth_suites, authentication)) {
3244 neg_authtype = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
3245 } else {
3246 acceptable_cipher = false;
3247 neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
3248 }
3249
3250 /* Caller doesn't care about auth type, or BSS doesn't match */
3251 if ((0 == auth_type->numEntries) || (false == acceptable_cipher))
3252 goto end;
3253
3254 acceptable_cipher = false;
3255 for (i = 0; i < auth_type->numEntries; i++) {
3256 if (auth_type->authType[i] == neg_authtype) {
3257 acceptable_cipher = true;
3258 break;
3259 }
3260 }
3261
3262end:
3263 if (acceptable_cipher) {
3264 if (mcast_cipher)
3265 cdf_mem_copy(mcast_cipher, multicast,
3266 CSR_WAPI_OUI_SIZE);
3267 if (ucast_cipher)
3268 cdf_mem_copy(ucast_cipher, unicast, CSR_WAPI_OUI_SIZE);
3269 if (auth_suite)
3270 cdf_mem_copy(auth_suite, authentication,
3271 CSR_WAPI_OUI_SIZE);
3272 if (negotiated_authtype)
3273 *negotiated_authtype = neg_authtype;
3274 }
3275 return acceptable_cipher;
3276}
3277
3278bool csr_is_wapi_match(tHalHandle hHal, tCsrAuthList *pAuthType,
3279 eCsrEncryptionType enType, tCsrEncryptionList *pEnMcType,
3280 tDot11fBeaconIEs *pIes, eCsrAuthType *pNegotiatedAuthType,
3281 eCsrEncryptionType *pNegotiatedMCCipher)
3282{
3283 bool fWapiMatch = false;
3284
3285 /* See if the cyphers in the Bss description match with the settings in the profile. */
3286 fWapiMatch =
3287 csr_get_wapi_information(hHal, pAuthType, enType, pEnMcType,
3288 &pIes->WAPI, NULL, NULL, NULL,
3289 pNegotiatedAuthType, pNegotiatedMCCipher);
3290
3291 return fWapiMatch;
3292}
3293
3294bool csr_lookup_bkid(tpAniSirGlobal pMac, uint32_t sessionId, uint8_t *pBSSId,
3295 uint8_t *pBKId)
3296{
3297 bool fRC = false, fMatchFound = false;
3298 uint32_t Index;
3299 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
3300
3301 if (!pSession) {
3302 sms_log(pMac, LOGE, FL(" session %d not found "), sessionId);
3303 return false;
3304 }
3305
3306 do {
3307 for (Index = 0; Index < pSession->NumBkidCache; Index++) {
3308 sms_log(pMac, LOGW, "match BKID " MAC_ADDRESS_STR " to ",
3309 MAC_ADDR_ARRAY(pBSSId));
3310 if (cdf_mem_compare
3311 (pBSSId, pSession->BkidCacheInfo[Index].BSSID.bytes,
3312 sizeof(struct cdf_mac_addr))) {
3313 /* match found */
3314 fMatchFound = true;
3315 break;
3316 }
3317 }
3318
3319 if (!fMatchFound)
3320 break;
3321
3322 cdf_mem_copy(pBKId, pSession->BkidCacheInfo[Index].BKID,
3323 CSR_WAPI_BKID_SIZE);
3324
3325 fRC = true;
3326 } while (0);
3327 sms_log(pMac, LOGW,
3328 "csr_lookup_bkid called return match = %d pMac->roam.NumBkidCache = %d",
3329 fRC, pSession->NumBkidCache);
3330
3331 return fRC;
3332}
3333
3334uint8_t csr_construct_wapi_ie(tpAniSirGlobal pMac, uint32_t sessionId,
3335 tCsrRoamProfile *pProfile,
3336 tSirBssDescription *pSirBssDesc,
3337 tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
3338{
3339 bool fWapiMatch = false;
3340 uint8_t cbWapiIe = 0;
3341 uint8_t UnicastCypher[CSR_WAPI_OUI_SIZE];
3342 uint8_t MulticastCypher[CSR_WAPI_OUI_SIZE];
3343 uint8_t AuthSuite[CSR_WAPI_OUI_SIZE];
3344 uint8_t BKId[CSR_WAPI_BKID_SIZE];
3345 uint8_t *pWapi = NULL;
3346 bool fBKIDFound = false;
3347 tDot11fBeaconIEs *pIesLocal = pIes;
3348
3349 do {
3350 if (!csr_is_profile_wapi(pProfile))
3351 break;
3352
3353 if (!pIesLocal
3354 &&
3355 (!CDF_IS_STATUS_SUCCESS
3356 (csr_get_parsed_bss_description_ies
3357 (pMac, pSirBssDesc, &pIesLocal)))) {
3358 break;
3359 }
3360 /* See if the cyphers in the Bss description match with the settings in the profile. */
3361 fWapiMatch =
3362 csr_get_wapi_information(pMac, &pProfile->AuthType,
3363 pProfile->negotiatedUCEncryptionType,
3364 &pProfile->mcEncryptionType,
3365 &pIesLocal->WAPI, UnicastCypher,
3366 MulticastCypher, AuthSuite, NULL,
3367 NULL);
3368 if (!fWapiMatch)
3369 break;
3370
3371 cdf_mem_set(pWapiIe, sizeof(tCsrWapiIe), 0);
3372
3373 pWapiIe->IeHeader.ElementID = DOT11F_EID_WAPI;
3374
3375 pWapiIe->Version = CSR_WAPI_VERSION_SUPPORTED;
3376
3377 pWapiIe->cAuthenticationSuites = 1;
3378 cdf_mem_copy(&pWapiIe->AuthOui[0], AuthSuite,
3379 sizeof(AuthSuite));
3380
3381 pWapi = (uint8_t *) (&pWapiIe->AuthOui[1]);
3382
3383 *pWapi = (uint16_t) 1; /* cUnicastCyphers */
3384 pWapi += 2;
3385 cdf_mem_copy(pWapi, UnicastCypher, sizeof(UnicastCypher));
3386 pWapi += sizeof(UnicastCypher);
3387
3388 cdf_mem_copy(pWapi, MulticastCypher, sizeof(MulticastCypher));
3389 pWapi += sizeof(MulticastCypher);
3390
3391 /* WAPI capabilities follows the Auth Suite (two octects) */
3392 /* we shouldn't EVER be sending out "pre-auth supported". It is an AP only capability */
3393 /* & since we already did a memset pWapiIe to 0, skip these fields */
3394 pWapi += 2;
3395
3396 fBKIDFound =
3397 csr_lookup_bkid(pMac, sessionId, pSirBssDesc->bssId,
3398 &(BKId[0]));
3399
3400 if (fBKIDFound) {
3401 /* Do we need to change the endianness here */
3402 *pWapi = (uint16_t) 1; /* cBKIDs */
3403 pWapi += 2;
3404 cdf_mem_copy(pWapi, BKId, CSR_WAPI_BKID_SIZE);
3405 } else {
3406 *pWapi = 0;
3407 pWapi += 1;
3408 *pWapi = 0;
3409 pWapi += 1;
3410 }
3411
3412 /* Add in the IE fields except the IE header */
3413 /* Add BKID count and BKID (if any) */
3414 pWapiIe->IeHeader.Length =
3415 (uint8_t) (sizeof(*pWapiIe) - sizeof(pWapiIe->IeHeader));
3416
3417 /*2 bytes for BKID Count field */
3418 pWapiIe->IeHeader.Length += sizeof(uint16_t);
3419
3420 if (fBKIDFound) {
3421 pWapiIe->IeHeader.Length += CSR_WAPI_BKID_SIZE;
3422 }
3423 /* return the size of the IE header (total) constructed... */
3424 cbWapiIe = pWapiIe->IeHeader.Length + sizeof(pWapiIe->IeHeader);
3425
3426 } while (0);
3427
3428 if (!pIes && pIesLocal) {
3429 /* locally allocated */
3430 cdf_mem_free(pIesLocal);
3431 }
3432
3433 return cbWapiIe;
3434}
3435#endif /* FEATURE_WLAN_WAPI */
3436
3437/**
3438 * csr_get_wpa_cyphers() - to get WPA cipher info
3439 * @mac_ctx: pointer to mac context
3440 * @auth_type: auth type
3441 * @encr_type: encryption type
3442 * @mc_encryption: multicast encryption type
3443 * @wpa_ie: pointer to WPA IE
3444 * @ucast_cipher: Unicast cipher
3445 * @mcast_cipher: Multicast cipher
3446 * @auth_suite: Authentication suite
3447 * @negotiated_authtype: Negotiated auth type
3448 * @negotiated_mccipher: negotiated multicast cipher
3449 *
3450 * This routine will get all WPA information
3451 *
3452 * Return: bool
3453 */
3454bool csr_get_wpa_cyphers(tpAniSirGlobal mac_ctx, tCsrAuthList *auth_type,
3455 eCsrEncryptionType encr_type, tCsrEncryptionList *mc_encryption,
3456 tDot11fIEWPA *wpa_ie, uint8_t *ucast_cipher,
3457 uint8_t *mcast_cipher, uint8_t *auth_suite,
3458 eCsrAuthType *negotiated_authtype,
3459 eCsrEncryptionType *negotiated_mccipher)
3460{
3461 bool acceptable_cipher = false;
3462 uint8_t c_ucast_cipher = 0;
3463 uint8_t c_mcast_cipher = 0;
3464 uint8_t c_auth_suites = 0;
3465 uint8_t unicast[CSR_WPA_OUI_SIZE];
3466 uint8_t multicast[CSR_WPA_OUI_SIZE];
3467 uint8_t authentication[CSR_WPA_OUI_SIZE];
3468 uint8_t mccipher_arr[1][CSR_WPA_OUI_SIZE];
3469 uint8_t i;
3470 eCsrAuthType neg_authtype = eCSR_AUTH_TYPE_UNKNOWN;
3471
3472 if (!wpa_ie->present)
3473 goto end;
3474 c_mcast_cipher = 1;
3475 cdf_mem_copy(mccipher_arr, wpa_ie->multicast_cipher, CSR_WPA_OUI_SIZE);
3476 c_ucast_cipher = (uint8_t) (wpa_ie->unicast_cipher_count);
3477 c_auth_suites = (uint8_t) (wpa_ie->auth_suite_count);
3478
3479 /* Check - Is requested unicast Cipher supported by the BSS. */
3480 acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
3481 wpa_ie->unicast_ciphers, c_ucast_cipher,
3482 csr_get_oui_index_from_cipher(encr_type),
3483 unicast);
3484 if (!acceptable_cipher)
3485 goto end;
3486 /* unicast is supported. Pick the first matching Group cipher, if any */
3487 for (i = 0; i < mc_encryption->numEntries; i++) {
3488 acceptable_cipher = csr_match_wpaoui_index(mac_ctx,
3489 mccipher_arr, c_mcast_cipher,
3490 csr_get_oui_index_from_cipher(
3491 mc_encryption->encryptionType[i]),
3492 multicast);
3493 if (acceptable_cipher)
3494 break;
3495 }
3496 if (!acceptable_cipher)
3497 goto end;
3498
3499 if (negotiated_mccipher)
3500 *negotiated_mccipher = mc_encryption->encryptionType[i];
3501
3502 /* Initializing with false as it has true value already */
3503 acceptable_cipher = false;
3504 for (i = 0; i < auth_type->numEntries; i++) {
3505 /*
3506 * Ciphers are supported, Match authentication algorithm and
3507 * pick first matching authtype
3508 */
3509 if (csr_is_auth_wpa(mac_ctx, wpa_ie->auth_suites, c_auth_suites,
3510 authentication)) {
3511 if (eCSR_AUTH_TYPE_WPA == auth_type->authType[i])
3512 neg_authtype = eCSR_AUTH_TYPE_WPA;
3513 }
3514 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN) &&
3515 csr_is_auth_wpa_psk(mac_ctx,
3516 wpa_ie->auth_suites, c_auth_suites,
3517 authentication)) {
3518 if (eCSR_AUTH_TYPE_WPA_PSK == auth_type->authType[i])
3519 neg_authtype = eCSR_AUTH_TYPE_WPA_PSK;
3520 }
3521#ifdef FEATURE_WLAN_ESE
3522 if ((neg_authtype == eCSR_AUTH_TYPE_UNKNOWN)
3523 && csr_is_ese_cckm_auth_wpa(mac_ctx,
3524 wpa_ie->auth_suites, c_auth_suites,
3525 authentication)) {
3526 if (eCSR_AUTH_TYPE_CCKM_WPA == auth_type->authType[i])
3527 neg_authtype = eCSR_AUTH_TYPE_CCKM_WPA;
3528 }
3529#endif /* FEATURE_WLAN_ESE */
3530
3531 /*
3532 * The 1st auth type in the APs WPA IE, to match stations
3533 * connecting profiles auth type will cause us to exit this
3534 * loop. This is added as some APs advertise multiple akms in
3535 * the WPA IE
3536 */
3537 if (eCSR_AUTH_TYPE_UNKNOWN != neg_authtype) {
3538 acceptable_cipher = true;
3539 break;
3540 }
3541 }
3542
3543end:
3544 if (acceptable_cipher) {
3545 if (mcast_cipher)
3546 cdf_mem_copy((uint8_t **) mcast_cipher, multicast,
3547 CSR_WPA_OUI_SIZE);
3548
3549 if (ucast_cipher)
3550 cdf_mem_copy((uint8_t **) ucast_cipher, unicast,
3551 CSR_WPA_OUI_SIZE);
3552
3553 if (auth_suite)
3554 cdf_mem_copy((uint8_t **) auth_suite, authentication,
3555 CSR_WPA_OUI_SIZE);
3556
3557 if (negotiated_authtype)
3558 *negotiated_authtype = neg_authtype;
3559 }
3560
3561 return acceptable_cipher;
3562}
3563
3564bool csr_is_wpa_encryption_match(tpAniSirGlobal pMac, tCsrAuthList *pAuthType,
3565 eCsrEncryptionType enType,
3566 tCsrEncryptionList *pEnMcType,
3567 tDot11fBeaconIEs *pIes,
3568 eCsrAuthType *pNegotiatedAuthtype,
3569 eCsrEncryptionType *pNegotiatedMCCipher)
3570{
3571 bool fWpaMatch = false;
3572
3573 /* See if the cyphers in the Bss description match with the settings in the profile. */
3574 fWpaMatch =
3575 csr_get_wpa_cyphers(pMac, pAuthType, enType, pEnMcType, &pIes->WPA,
3576 NULL, NULL, NULL, pNegotiatedAuthtype,
3577 pNegotiatedMCCipher);
3578
3579 return fWpaMatch;
3580}
3581
3582uint8_t csr_construct_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile,
3583 tSirBssDescription *pSirBssDesc,
3584 tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
3585{
3586 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3587 bool fWpaMatch;
3588 uint8_t cbWpaIe = 0;
3589 uint8_t UnicastCypher[CSR_WPA_OUI_SIZE];
3590 uint8_t MulticastCypher[CSR_WPA_OUI_SIZE];
3591 uint8_t AuthSuite[CSR_WPA_OUI_SIZE];
3592 tCsrWpaAuthIe *pAuthSuite;
3593 tDot11fBeaconIEs *pIesLocal = pIes;
3594
3595 do {
3596 if (!csr_is_profile_wpa(pProfile))
3597 break;
3598
3599 if (!pIesLocal
3600 &&
3601 (!CDF_IS_STATUS_SUCCESS
3602 (csr_get_parsed_bss_description_ies
3603 (pMac, pSirBssDesc, &pIesLocal)))) {
3604 break;
3605 }
3606 /* See if the cyphers in the Bss description match with the settings in the profile. */
3607 fWpaMatch =
3608 csr_get_wpa_cyphers(hHal, &pProfile->AuthType,
3609 pProfile->negotiatedUCEncryptionType,
3610 &pProfile->mcEncryptionType,
3611 &pIesLocal->WPA, UnicastCypher,
3612 MulticastCypher, AuthSuite, NULL, NULL);
3613 if (!fWpaMatch)
3614 break;
3615
3616 pWpaIe->IeHeader.ElementID = SIR_MAC_WPA_EID;
3617
3618 cdf_mem_copy(pWpaIe->Oui, csr_wpa_oui[01], sizeof(pWpaIe->Oui));
3619
3620 pWpaIe->Version = CSR_WPA_VERSION_SUPPORTED;
3621
3622 cdf_mem_copy(pWpaIe->MulticastOui, MulticastCypher,
3623 sizeof(MulticastCypher));
3624
3625 pWpaIe->cUnicastCyphers = 1;
3626
3627 cdf_mem_copy(&pWpaIe->UnicastOui[0], UnicastCypher,
3628 sizeof(UnicastCypher));
3629
3630 pAuthSuite =
3631 (tCsrWpaAuthIe *) (&pWpaIe->
3632 UnicastOui[pWpaIe->cUnicastCyphers]);
3633
3634 pAuthSuite->cAuthenticationSuites = 1;
3635 cdf_mem_copy(&pAuthSuite->AuthOui[0], AuthSuite,
3636 sizeof(AuthSuite));
3637
3638 /* The WPA capabilities follows the Auth Suite (two octects)-- */
3639 /* this field is optional, and we always "send" zero, so just */
3640 /* remove it. This is consistent with our assumptions in the */
3641 /* frames compiler; c.f. bug 15234: */
3642 /* http://gold.woodsidenet.com/bugzilla/show_bug.cgi?id=15234 */
3643
3644 /* Add in the fixed fields plus 1 Unicast cypher, less the IE Header length */
3645 /* Add in the size of the Auth suite (count plus a single OUI) */
3646 pWpaIe->IeHeader.Length =
3647 sizeof(*pWpaIe) - sizeof(pWpaIe->IeHeader) +
3648 sizeof(*pAuthSuite);
3649
3650 /* return the size of the IE header (total) constructed... */
3651 cbWpaIe = pWpaIe->IeHeader.Length + sizeof(pWpaIe->IeHeader);
3652
3653 } while (0);
3654
3655 if (!pIes && pIesLocal) {
3656 /* locally allocated */
3657 cdf_mem_free(pIesLocal);
3658 }
3659
3660 return cbWpaIe;
3661}
3662
3663/* If a WPAIE exists in the profile, just use it. Or else construct one from the BSS */
3664/* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */
3665uint8_t csr_retrieve_wpa_ie(tHalHandle hHal, tCsrRoamProfile *pProfile,
3666 tSirBssDescription *pSirBssDesc,
3667 tDot11fBeaconIEs *pIes, tCsrWpaIe *pWpaIe)
3668{
3669 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3670 uint8_t cbWpaIe = 0;
3671
3672 do {
3673 if (!csr_is_profile_wpa(pProfile))
3674 break;
3675 if (pProfile->nWPAReqIELength && pProfile->pWPAReqIE) {
3676 if (SIR_MAC_WPA_IE_MAX_LENGTH >=
3677 pProfile->nWPAReqIELength) {
3678 cbWpaIe = (uint8_t) pProfile->nWPAReqIELength;
3679 cdf_mem_copy(pWpaIe, pProfile->pWPAReqIE,
3680 cbWpaIe);
3681 } else {
3682 sms_log(pMac, LOGW,
3683 " csr_retrieve_wpa_ie detect invalid WPA IE length (%d) ",
3684 pProfile->nWPAReqIELength);
3685 }
3686 } else {
3687 cbWpaIe =
3688 csr_construct_wpa_ie(pMac, pProfile, pSirBssDesc, pIes,
3689 pWpaIe);
3690 }
3691 } while (0);
3692
3693 return cbWpaIe;
3694}
3695
3696/* If a RSNIE exists in the profile, just use it. Or else construct one from the BSS */
3697/* Caller allocated memory for pWpaIe and guarrantee it can contain a max length WPA IE */
3698uint8_t csr_retrieve_rsn_ie(tHalHandle hHal, uint32_t sessionId,
3699 tCsrRoamProfile *pProfile,
3700 tSirBssDescription *pSirBssDesc,
3701 tDot11fBeaconIEs *pIes, tCsrRSNIe *pRsnIe)
3702{
3703 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3704 uint8_t cbRsnIe = 0;
3705
3706 do {
3707 if (!csr_is_profile_rsn(pProfile))
3708 break;
3709#ifdef FEATURE_WLAN_LFR
3710 if (csr_roam_is_fast_roam_enabled(pMac, sessionId)) {
3711 /* If "Legacy Fast Roaming" is enabled ALWAYS rebuild the RSN IE from */
3712 /* scratch. So it contains the current PMK-IDs */
3713 cbRsnIe =
3714 csr_construct_rsn_ie(pMac, sessionId, pProfile,
3715 pSirBssDesc, pIes, pRsnIe);
3716 } else
3717#endif
3718 if (pProfile->nRSNReqIELength && pProfile->pRSNReqIE) {
3719 /* If you have one started away, re-use it. */
3720 if (SIR_MAC_WPA_IE_MAX_LENGTH >=
3721 pProfile->nRSNReqIELength) {
3722 cbRsnIe = (uint8_t) pProfile->nRSNReqIELength;
3723 cdf_mem_copy(pRsnIe, pProfile->pRSNReqIE,
3724 cbRsnIe);
3725 } else {
3726 sms_log(pMac, LOGW,
3727 " csr_retrieve_rsn_ie detect invalid RSN IE length (%d) ",
3728 pProfile->nRSNReqIELength);
3729 }
3730 } else {
3731 cbRsnIe =
3732 csr_construct_rsn_ie(pMac, sessionId, pProfile,
3733 pSirBssDesc, pIes, pRsnIe);
3734 }
3735 } while (0);
3736
3737 return cbRsnIe;
3738}
3739
3740#ifdef FEATURE_WLAN_WAPI
3741/* If a WAPI IE exists in the profile, just use it. Or else construct one from the BSS */
3742/* Caller allocated memory for pWapiIe and guarrantee it can contain a max length WAPI IE */
3743uint8_t csr_retrieve_wapi_ie(tHalHandle hHal, uint32_t sessionId,
3744 tCsrRoamProfile *pProfile,
3745 tSirBssDescription *pSirBssDesc,
3746 tDot11fBeaconIEs *pIes, tCsrWapiIe *pWapiIe)
3747{
3748 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
3749 uint8_t cbWapiIe = 0;
3750
3751 do {
3752 if (!csr_is_profile_wapi(pProfile))
3753 break;
3754 if (pProfile->nWAPIReqIELength && pProfile->pWAPIReqIE) {
3755 if (DOT11F_IE_WAPI_MAX_LEN >=
3756 pProfile->nWAPIReqIELength) {
3757 cbWapiIe = (uint8_t) pProfile->nWAPIReqIELength;
3758 cdf_mem_copy(pWapiIe, pProfile->pWAPIReqIE,
3759 cbWapiIe);
3760 } else {
3761 sms_log(pMac, LOGW,
3762 " csr_retrieve_wapi_ie detect invalid WAPI IE length (%d) ",
3763 pProfile->nWAPIReqIELength);
3764 }
3765 } else {
3766 cbWapiIe =
3767 csr_construct_wapi_ie(pMac, sessionId, pProfile,
3768 pSirBssDesc, pIes, pWapiIe);
3769 }
3770 } while (0);
3771
3772 return cbWapiIe;
3773}
3774#endif /* FEATURE_WLAN_WAPI */
3775
3776bool csr_rates_is_dot11_rate11b_supported_rate(uint8_t dot11Rate)
3777{
3778 bool fSupported = false;
3779 uint16_t nonBasicRate =
3780 (uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
3781
3782 switch (nonBasicRate) {
3783 case eCsrSuppRate_1Mbps:
3784 case eCsrSuppRate_2Mbps:
3785 case eCsrSuppRate_5_5Mbps:
3786 case eCsrSuppRate_11Mbps:
3787 fSupported = true;
3788 break;
3789
3790 default:
3791 break;
3792 }
3793
3794 return fSupported;
3795}
3796
3797bool csr_rates_is_dot11_rate11a_supported_rate(uint8_t dot11Rate)
3798{
3799 bool fSupported = false;
3800 uint16_t nonBasicRate =
3801 (uint16_t) (BITS_OFF(dot11Rate, CSR_DOT11_BASIC_RATE_MASK));
3802
3803 switch (nonBasicRate) {
3804 case eCsrSuppRate_6Mbps:
3805 case eCsrSuppRate_9Mbps:
3806 case eCsrSuppRate_12Mbps:
3807 case eCsrSuppRate_18Mbps:
3808 case eCsrSuppRate_24Mbps:
3809 case eCsrSuppRate_36Mbps:
3810 case eCsrSuppRate_48Mbps:
3811 case eCsrSuppRate_54Mbps:
3812 fSupported = true;
3813 break;
3814
3815 default:
3816 break;
3817 }
3818
3819 return fSupported;
3820}
3821
3822tAniEdType csr_translate_encrypt_type_to_ed_type(eCsrEncryptionType EncryptType)
3823{
3824 tAniEdType edType;
3825
3826 switch (EncryptType) {
3827 default:
3828 case eCSR_ENCRYPT_TYPE_NONE:
3829 edType = eSIR_ED_NONE;
3830 break;
3831
3832 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3833 case eCSR_ENCRYPT_TYPE_WEP40:
3834 edType = eSIR_ED_WEP40;
3835 break;
3836
3837 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3838 case eCSR_ENCRYPT_TYPE_WEP104:
3839 edType = eSIR_ED_WEP104;
3840 break;
3841
3842 case eCSR_ENCRYPT_TYPE_TKIP:
3843 edType = eSIR_ED_TKIP;
3844 break;
3845
3846 case eCSR_ENCRYPT_TYPE_AES:
3847 edType = eSIR_ED_CCMP;
3848 break;
3849#ifdef FEATURE_WLAN_WAPI
3850 case eCSR_ENCRYPT_TYPE_WPI:
3851 edType = eSIR_ED_WPI;
3852 break;
3853#endif
3854#ifdef WLAN_FEATURE_11W
3855 /* 11w BIP */
3856 case eCSR_ENCRYPT_TYPE_AES_CMAC:
3857 edType = eSIR_ED_AES_128_CMAC;
3858 break;
3859#endif
3860 }
3861
3862 return edType;
3863}
3864
3865/**
3866 * csr_validate_wep() - to validate wep
3867 * @uc_encry_type: unicast encryption type
3868 * @auth_list: Auth list
3869 * @mc_encryption_list: multicast encryption type
3870 * @negotiated_authtype: negotiated auth type
3871 * @negotiated_mc_encry: negotiated mc encry type
3872 * @bss_descr: BSS description
3873 * @ie_ptr: IE pointer
3874 *
3875 * This function just checks whether HDD is giving correct values for
3876 * Multicast cipher and Auth
3877 *
3878 * Return: bool
3879 */
3880bool csr_validate_wep(tpAniSirGlobal mac_ctx, eCsrEncryptionType uc_encry_type,
3881 tCsrAuthList *auth_list,
3882 tCsrEncryptionList *mc_encryption_list,
3883 eCsrAuthType *negotiated_authtype,
3884 eCsrEncryptionType *negotiated_mc_encry,
3885 tSirBssDescription *bss_descr, tDot11fBeaconIEs *ie_ptr)
3886{
3887 uint32_t idx;
3888 bool match = false;
3889 eCsrAuthType negotiated_auth = eCSR_AUTH_TYPE_OPEN_SYSTEM;
3890 eCsrEncryptionType negotiated_mccipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
3891
3892 /* If privacy bit is not set, consider no match */
3893 if (!csr_is_privacy(bss_descr))
3894 goto end;
3895
3896 for (idx = 0; idx < mc_encryption_list->numEntries; idx++) {
3897 switch (mc_encryption_list->encryptionType[idx]) {
3898 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
3899 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
3900 case eCSR_ENCRYPT_TYPE_WEP40:
3901 case eCSR_ENCRYPT_TYPE_WEP104:
3902 /*
3903 * Multicast list may contain WEP40/WEP104.
3904 * Check whether it matches UC.
3905 */
3906 if (uc_encry_type ==
3907 mc_encryption_list->encryptionType[idx]) {
3908 match = true;
3909 negotiated_mccipher =
3910 mc_encryption_list->encryptionType[idx];
3911 }
3912 break;
3913 default:
3914 match = false;
3915 break;
3916 }
3917 if (match)
3918 break;
3919 }
3920
3921 if (!match)
3922 goto end;
3923
3924 for (idx = 0; idx < auth_list->numEntries; idx++) {
3925 switch (auth_list->authType[idx]) {
3926 case eCSR_AUTH_TYPE_OPEN_SYSTEM:
3927 case eCSR_AUTH_TYPE_SHARED_KEY:
3928 case eCSR_AUTH_TYPE_AUTOSWITCH:
3929 match = true;
3930 negotiated_auth = auth_list->authType[idx];
3931 break;
3932 default:
3933 match = false;
3934 }
3935 if (match)
3936 break;
3937 }
3938
3939 if (!match)
3940 goto end;
3941
3942 if (!ie_ptr)
3943 goto end;
3944
3945 /*
3946 * In case of WPA / WPA2, check whether it supports WEP as well.
3947 * Prepare the encryption type for WPA/WPA2 functions
3948 */
3949 if (eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == uc_encry_type)
3950 uc_encry_type = eCSR_ENCRYPT_TYPE_WEP40;
3951 else if (eCSR_ENCRYPT_TYPE_WEP104 == uc_encry_type)
3952 uc_encry_type = eCSR_ENCRYPT_TYPE_WEP104;
3953
3954 /* else we can use the encryption type directly */
3955 if (ie_ptr->WPA.present) {
3956 match = cdf_mem_compare(ie_ptr->WPA.multicast_cipher,
3957 csr_wpa_oui[csr_get_oui_index_from_cipher(
3958 uc_encry_type)],
3959 CSR_WPA_OUI_SIZE);
3960 if (match)
3961 goto end;
3962 }
3963 if (ie_ptr->RSN.present) {
3964 match = cdf_mem_compare(ie_ptr->RSN.gp_cipher_suite,
3965 csr_rsn_oui[csr_get_oui_index_from_cipher(
3966 uc_encry_type)],
3967 CSR_RSN_OUI_SIZE);
3968 }
3969
3970
3971end:
3972 if (match) {
3973 if (negotiated_authtype)
3974 *negotiated_authtype = negotiated_auth;
3975 if (negotiated_mc_encry)
3976 *negotiated_mc_encry = negotiated_mccipher;
3977 }
3978 return match;
3979}
3980
3981/**
3982 * csr_validate_open_none() - Check if the security is matching
3983 * @bss_desc: BSS Descriptor on which the check is done
3984 * @mc_enc_type: Multicast encryption type
3985 * @mc_cipher: Multicast Cipher
3986 * @auth_type: Authentication type
3987 * @neg_auth_type: Negotiated Auth type with the AP
3988 *
3989 * Return: Boolean value to tell if matched or not.
3990 */
3991static bool csr_validate_open_none(tSirBssDescription *bss_desc,
3992 tCsrEncryptionList *mc_enc_type, eCsrEncryptionType *mc_cipher,
3993 tCsrAuthList *auth_type, eCsrAuthType *neg_auth_type)
3994{
3995 bool match;
3996 uint8_t idx;
3997
3998 /*
3999 * for NO encryption, if the Bss description has the
4000 * Privacy bit turned on, then encryption is required
4001 * so we have to reject this Bss.
4002 */
4003 if (csr_is_privacy(bss_desc))
4004 match = false;
4005 else
4006 match = true;
4007 if (match) {
4008 match = false;
4009 /* Check MC cipher and Auth type requested. */
4010 for (idx = 0; idx < mc_enc_type->numEntries; idx++) {
4011 if (eCSR_ENCRYPT_TYPE_NONE ==
4012 mc_enc_type->encryptionType[idx]) {
4013 match = true;
4014 *mc_cipher = mc_enc_type->encryptionType[idx];
4015 break;
4016 }
4017 }
4018 if (!match)
4019 return match;
4020
4021 match = false;
4022 /* Check Auth list. It should contain AuthOpen. */
4023 for (idx = 0; idx < auth_type->numEntries; idx++) {
4024 if ((eCSR_AUTH_TYPE_OPEN_SYSTEM ==
4025 auth_type->authType[idx]) ||
4026 (eCSR_AUTH_TYPE_AUTOSWITCH ==
4027 auth_type->authType[idx])) {
4028 match = true;
4029 *neg_auth_type =
4030 eCSR_AUTH_TYPE_OPEN_SYSTEM;
4031 break;
4032 }
4033 }
4034 if (!match)
4035 return match;
4036
4037 }
4038 return match;
4039}
4040
4041/**
4042 * csr_validate_any_default() - Check if the security is matching
4043 * @hal: Global HAL handle
4044 * @auth_type: Authentication type
4045 * @mc_enc_type: Multicast encryption type
4046 * @mfp_enabled: Management frame protection feature
4047 * @mfp_required: Mangement frame protection mandatory
4048 * @mfp_capable: Device capable of MFP
4049 * @ies_ptr: Pointer to the IE fields
4050 * @neg_auth_type: Negotiated Auth type with the AP
4051 * @bss_desc: BSS Descriptor
4052 * @neg_uc_cipher: Negotiated unicast cipher suite
4053 * @neg_mc_cipher: Negotiated multicast cipher
4054 *
4055 * Return: Boolean value to tell if matched or not.
4056 */
4057static bool csr_validate_any_default(tHalHandle hal, tCsrAuthList *auth_type,
4058 tCsrEncryptionList *mc_enc_type, bool *mfp_enabled,
4059 uint8_t *mfp_required, uint8_t *mfp_capable,
4060 tDot11fBeaconIEs *ies_ptr, eCsrAuthType *neg_auth_type,
4061 tSirBssDescription *bss_desc, eCsrEncryptionType *uc_cipher,
4062 eCsrEncryptionType *mc_cipher)
4063{
4064 bool match_any = false;
4065 bool match = true;
4066 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4067 /* It is allowed to match anything. Try the more secured ones first. */
4068 if (ies_ptr) {
4069 /* Check AES first */
4070 *uc_cipher = eCSR_ENCRYPT_TYPE_AES;
4071 match_any = csr_is_rsn_match(hal, auth_type,
4072 *uc_cipher, mc_enc_type, mfp_enabled,
4073 mfp_required, mfp_capable, ies_ptr,
4074 neg_auth_type, mc_cipher);
4075 if (!match_any) {
4076 /* Check TKIP */
4077 *uc_cipher = eCSR_ENCRYPT_TYPE_TKIP;
4078 match_any = csr_is_rsn_match(hal, auth_type, *uc_cipher,
4079 mc_enc_type, mfp_enabled, mfp_required,
4080 mfp_capable, ies_ptr, neg_auth_type,
4081 mc_cipher);
4082 }
4083#ifdef FEATURE_WLAN_WAPI
4084 if (!match_any) {
4085 /* Check WAPI */
4086 *uc_cipher = eCSR_ENCRYPT_TYPE_WPI;
4087 match_any = csr_is_wapi_match(hal, auth_type,
4088 *uc_cipher, mc_enc_type, ies_ptr,
4089 neg_auth_type, mc_cipher);
4090 }
4091#endif
4092 }
4093 if (match_any)
4094 return match;
4095 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP104;
4096 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4097 neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4098 return match;
4099 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP40;
4100 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4101 neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4102 return match;
4103 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
4104 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4105 neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4106 return match;
4107 *uc_cipher = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
4108 if (csr_validate_wep(mac_ctx, *uc_cipher, auth_type, mc_enc_type,
4109 neg_auth_type, mc_cipher, bss_desc, ies_ptr))
4110 return match;
4111 /* It must be open and no enc */
4112 if (csr_is_privacy(bss_desc)) {
4113 match = false;
4114 return match;
4115 }
4116
4117 *neg_auth_type = eCSR_AUTH_TYPE_OPEN_SYSTEM;
4118 *mc_cipher = eCSR_ENCRYPT_TYPE_NONE;
4119 *uc_cipher = eCSR_ENCRYPT_TYPE_NONE;
4120 return match;
4121
4122}
4123
4124/**
4125 * csr_is_security_match() - Check if the security is matching
4126 * @hal: Global HAL handle
4127 * @auth_type: Authentication type
4128 * @uc_enc_type: Unicast Encryption type
4129 * @mc_enc_type: Multicast encryption type
4130 * @mfp_enabled: Management frame protection feature
4131 * @mfp_required: Mangement frame protection mandatory
4132 * @mfp_capable: Device capable of MFP
4133 * @bss_desc: BSS Descriptor
4134 * @ies_ptr: Pointer to the IE fields
4135 * @neg_auth_type: Negotiated Auth type with the AP
4136 * @neg_uc_cipher: Negotiated unicast cipher suite
4137 * @neg_mc_cipher: Negotiated multicast cipher
4138 *
4139 * Return: Boolean value to tell if matched or not.
4140 */
4141bool csr_is_security_match(tHalHandle hal, tCsrAuthList *auth_type,
4142 tCsrEncryptionList *uc_enc_type,
4143 tCsrEncryptionList *mc_enc_type, bool *mfp_enabled,
4144 uint8_t *mfp_required, uint8_t *mfp_capable,
4145 tSirBssDescription *bss_desc, tDot11fBeaconIEs *ies_ptr,
4146 eCsrAuthType *neg_auth_type,
4147 eCsrEncryptionType *neg_uc_cipher,
4148 eCsrEncryptionType *neg_mc_cipher)
4149{
4150 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4151 bool match = false;
4152 uint8_t i;
4153 eCsrEncryptionType mc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
4154 eCsrEncryptionType uc_cipher = eCSR_ENCRYPT_TYPE_UNKNOWN;
4155 eCsrAuthType local_neg_auth_type = eCSR_AUTH_TYPE_UNKNOWN;
4156
4157 for (i = 0; ((i < uc_enc_type->numEntries) && (!match)); i++) {
4158 uc_cipher = uc_enc_type->encryptionType[i];
4159 /*
4160 * If the Bss description shows the Privacy bit is on, then we
4161 * must have some sort of encryption configured for the profile
4162 * to work. Don't attempt to join networks with Privacy bit
4163 * set when profiles say NONE for encryption type.
4164 */
4165 switch (uc_cipher) {
4166 case eCSR_ENCRYPT_TYPE_NONE:
4167 match = csr_validate_open_none(bss_desc, mc_enc_type,
4168 &mc_cipher, auth_type,
4169 &local_neg_auth_type);
4170 break;
4171
4172 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
4173 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
4174 /*
4175 * !! might want to check for WEP keys set in the
4176 * Profile.... ? !! don't need to have the privacy bit
4177 * in the Bss description. Many AP policies make
4178 * legacy encryption 'optional' so we don't know if we
4179 * can associate or not. The AP will reject if
4180 * encryption is not allowed without the Privacy bit
4181 * turned on.
4182 */
4183 match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
4184 mc_enc_type, &local_neg_auth_type,
4185 &mc_cipher, bss_desc, ies_ptr);
4186
4187 break;
4188 /* these are all of the WPA encryption types... */
4189 case eCSR_ENCRYPT_TYPE_WEP40:
4190 case eCSR_ENCRYPT_TYPE_WEP104:
4191 match = csr_validate_wep(mac_ctx, uc_cipher, auth_type,
4192 mc_enc_type, &local_neg_auth_type,
4193 &mc_cipher, bss_desc, ies_ptr);
4194 break;
4195
4196 case eCSR_ENCRYPT_TYPE_TKIP:
4197 case eCSR_ENCRYPT_TYPE_AES:
4198 if (!ies_ptr) {
4199 match = false;
4200 break;
4201 }
4202 /* First check if there is a RSN match */
4203 match = csr_is_rsn_match(mac_ctx, auth_type,
4204 uc_cipher, mc_enc_type,
4205 mfp_enabled, mfp_required,
4206 mfp_capable, ies_ptr,
4207 &local_neg_auth_type,
4208 &mc_cipher);
4209 /* If not RSN, then check WPA match */
4210 if (!match)
4211 match = csr_is_wpa_encryption_match(
4212 mac_ctx, auth_type,
4213 uc_cipher, mc_enc_type,
4214 ies_ptr,
4215 &local_neg_auth_type,
4216 &mc_cipher);
4217 break;
4218#ifdef FEATURE_WLAN_WAPI
4219 case eCSR_ENCRYPT_TYPE_WPI: /* WAPI */
4220 if (ies_ptr)
4221 match = csr_is_wapi_match(hal, auth_type,
4222 uc_cipher, mc_enc_type, ies_ptr,
4223 &local_neg_auth_type,
4224 &mc_cipher);
4225 else
4226 match = false;
4227 break;
4228#endif /* FEATURE_WLAN_WAPI */
4229 case eCSR_ENCRYPT_TYPE_ANY:
4230 default:
4231 match = csr_validate_any_default(hal, auth_type,
4232 mc_enc_type, mfp_enabled, mfp_required,
4233 mfp_capable, ies_ptr,
4234 &local_neg_auth_type, bss_desc,
4235 &uc_cipher, &mc_cipher);
4236 break;
4237 }
4238
4239 }
4240
4241 if (match) {
4242 if (neg_uc_cipher)
4243 *neg_uc_cipher = uc_cipher;
4244 if (neg_mc_cipher)
4245 *neg_mc_cipher = mc_cipher;
4246 if (neg_auth_type)
4247 *neg_auth_type = local_neg_auth_type;
4248 }
4249 return match;
4250}
4251
4252bool csr_is_ssid_match(tpAniSirGlobal pMac, uint8_t *ssid1, uint8_t ssid1Len,
4253 uint8_t *bssSsid, uint8_t bssSsidLen, bool fSsidRequired)
4254{
4255 bool fMatch = false;
4256
4257 do {
4258 /*
4259 * Check for the specification of the Broadcast SSID at the
4260 * beginning of the list. If specified, then all SSIDs are
4261 * matches (broadcast SSID means accept all SSIDs).
4262 */
4263 if (ssid1Len == 0) {
4264 fMatch = true;
4265 break;
4266 }
4267
4268 /* There are a few special cases. If the Bss description has a Broadcast SSID, */
4269 /* then our Profile must have a single SSID without Wildcards so we can program */
4270 /* the SSID. */
4271 /* SSID could be suppressed in beacons. In that case SSID IE has valid length */
4272 /* but the SSID value is all NULL characters. That condition is trated same */
4273 /* as NULL SSID */
4274 if (csr_is_nullssid(bssSsid, bssSsidLen)) {
4275 if (false == fSsidRequired) {
4276 fMatch = true;
4277 break;
4278 }
4279 }
4280
4281 if (ssid1Len != bssSsidLen)
4282 break;
4283 if (cdf_mem_compare(bssSsid, ssid1, bssSsidLen)) {
4284 fMatch = true;
4285 break;
4286 }
4287
4288 } while (0);
4289
4290 return fMatch;
4291}
4292
4293/* Null ssid means match */
4294bool csr_is_ssid_in_list(tHalHandle hHal, tSirMacSSid *pSsid,
4295 tCsrSSIDs *pSsidList)
4296{
4297 bool fMatch = false;
4298 uint32_t i;
4299
4300 if (pSsidList && pSsid) {
4301 for (i = 0; i < pSsidList->numOfSSIDs; i++) {
4302 if (csr_is_nullssid
4303 (pSsidList->SSIDList[i].SSID.ssId,
4304 pSsidList->SSIDList[i].SSID.length)
4305 ||
4306 ((pSsidList->SSIDList[i].SSID.length ==
4307 pSsid->length)
4308 && cdf_mem_compare(pSsid->ssId,
4309 pSsidList->SSIDList[i].SSID.
4310 ssId, pSsid->length))) {
4311 fMatch = true;
4312 break;
4313 }
4314 }
4315 }
4316
4317 return fMatch;
4318}
4319
4320bool csr_is_bssid_match(tHalHandle hHal, struct cdf_mac_addr *pProfBssid,
4321 struct cdf_mac_addr *BssBssid)
4322{
4323 bool fMatch = false;
4324 struct cdf_mac_addr ProfileBssid;
4325
4326 /* for efficiency of the MAC_ADDRESS functions, move the */
4327 /* Bssid's into MAC_ADDRESS structs. */
4328 cdf_mem_copy(&ProfileBssid, pProfBssid, sizeof(struct cdf_mac_addr));
4329
4330 do {
4331
4332 /* Give the profile the benefit of the doubt... accept either all 0 or */
4333 /* the real broadcast Bssid (all 0xff) as broadcast Bssids (meaning to */
4334 /* match any Bssids). */
4335 if (cdf_is_macaddr_zero(&ProfileBssid) ||
4336 cdf_is_macaddr_broadcast(&ProfileBssid)) {
4337 fMatch = true;
4338 break;
4339 }
4340
4341 if (cdf_is_macaddr_equal(BssBssid, &ProfileBssid)) {
4342 fMatch = true;
4343 break;
4344 }
4345
4346 } while (0);
4347
4348 return fMatch;
4349}
4350
4351bool csr_is_bss_type_match(eCsrRoamBssType bssType1, eCsrRoamBssType bssType2)
4352{
4353 if ((eCSR_BSS_TYPE_ANY != bssType1 && eCSR_BSS_TYPE_ANY != bssType2)
4354 && (bssType1 != bssType2))
4355 return false;
4356 else
4357 return true;
4358}
4359
4360bool csr_is_bss_type_ibss(eCsrRoamBssType bssType)
4361{
4362 return (bool)
4363 (eCSR_BSS_TYPE_START_IBSS == bssType
4364 || eCSR_BSS_TYPE_IBSS == bssType);
4365}
4366
4367bool csr_is_bss_type_wds(eCsrRoamBssType bssType)
4368{
4369 return (bool)
4370 (eCSR_BSS_TYPE_WDS_STA == bssType
4371 || eCSR_BSS_TYPE_WDS_AP == bssType);
4372}
4373
4374bool csr_is_bss_type_caps_match(eCsrRoamBssType bssType,
4375 tSirBssDescription *pSirBssDesc)
4376{
4377 bool fMatch = true;
4378
4379 do {
4380 switch (bssType) {
4381 case eCSR_BSS_TYPE_ANY:
4382 break;
4383
4384 case eCSR_BSS_TYPE_INFRASTRUCTURE:
4385 case eCSR_BSS_TYPE_WDS_STA:
4386 if (!csr_is_infra_bss_desc(pSirBssDesc))
4387 fMatch = false;
4388
4389 break;
4390
4391 case eCSR_BSS_TYPE_IBSS:
4392 case eCSR_BSS_TYPE_START_IBSS:
4393 if (!csr_is_ibss_bss_desc(pSirBssDesc))
4394 fMatch = false;
4395
4396 break;
4397
4398 case eCSR_BSS_TYPE_WDS_AP: /* For WDS AP, no need to match anything */
4399 default:
4400 fMatch = false;
4401 break;
4402 }
4403 } while (0);
4404
4405 return fMatch;
4406}
4407
4408static bool csr_is_capabilities_match(tpAniSirGlobal pMac, eCsrRoamBssType bssType,
4409 tSirBssDescription *pSirBssDesc)
4410{
4411 return csr_is_bss_type_caps_match(bssType, pSirBssDesc);
4412}
4413
4414static bool csr_is_specific_channel_match(tpAniSirGlobal pMac,
4415 tSirBssDescription *pSirBssDesc,
4416 uint8_t Channel)
4417{
4418 bool fMatch = true;
4419
4420 do {
4421 /* if the channel is ANY, then always match... */
4422 if (eCSR_OPERATING_CHANNEL_ANY == Channel)
4423 break;
4424 if (Channel == pSirBssDesc->channelId)
4425 break;
4426
4427 /* didn't match anything.. so return NO match */
4428 fMatch = false;
4429
4430 } while (0);
4431
4432 return fMatch;
4433}
4434
4435bool csr_is_channel_band_match(tpAniSirGlobal pMac, uint8_t channelId,
4436 tSirBssDescription *pSirBssDesc)
4437{
4438 bool fMatch = true;
4439
4440 do {
4441 /* if the profile says Any channel AND the global settings says ANY channel, then we */
4442 /* always match... */
4443 if (eCSR_OPERATING_CHANNEL_ANY == channelId)
4444 break;
4445
4446 if (eCSR_OPERATING_CHANNEL_ANY != channelId) {
4447 fMatch =
4448 csr_is_specific_channel_match(pMac, pSirBssDesc,
4449 channelId);
4450 }
4451
4452 } while (0);
4453
4454 return fMatch;
4455}
4456
4457/**
4458 * csr_is_aggregate_rate_supported() - to check if aggregate rate is supported
4459 * @mac_ctx: pointer to mac context
4460 * @rate: A rate in units of 500kbps
4461 *
4462 *
4463 * The rate encoding is just as in 802.11 Information Elements, except
4464 * that the high bit is \em not interpreted as indicating a Basic Rate,
4465 * and proprietary rates are allowed, too.
4466 *
4467 * Note that if the adapter's dot11Mode is g, we don't restrict the
4468 * rates. According to hwReadEepromParameters, this will happen when:
4469 * ... the card is configured for ALL bands through the property
4470 * page. If this occurs, and the card is not an ABG card ,then this
4471 * code is setting the dot11Mode to assume the mode that the
4472 * hardware can support. For example, if the card is an 11BG card
4473 * and we are configured to support ALL bands, then we change the
4474 * dot11Mode to 11g because ALL in this case is only what the
4475 * hardware can support.
4476 *
4477 * Return: true if the adapter is currently capable of supporting this rate
4478 */
4479
4480static bool csr_is_aggregate_rate_supported(tpAniSirGlobal mac_ctx,
4481 uint16_t rate)
4482{
4483 bool supported = false;
4484 uint16_t idx, new_rate;
4485
4486 /* In case basic rate flag is set */
4487 new_rate = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
4488 if (eCSR_CFG_DOT11_MODE_11A ==
4489 mac_ctx->roam.configParam.uCfgDot11Mode) {
4490 switch (new_rate) {
4491 case eCsrSuppRate_6Mbps:
4492 case eCsrSuppRate_9Mbps:
4493 case eCsrSuppRate_12Mbps:
4494 case eCsrSuppRate_18Mbps:
4495 case eCsrSuppRate_24Mbps:
4496 case eCsrSuppRate_36Mbps:
4497 case eCsrSuppRate_48Mbps:
4498 case eCsrSuppRate_54Mbps:
4499 supported = true;
4500 break;
4501 default:
4502 supported = false;
4503 break;
4504 }
4505
4506 } else if (eCSR_CFG_DOT11_MODE_11B ==
4507 mac_ctx->roam.configParam.uCfgDot11Mode) {
4508 switch (new_rate) {
4509 case eCsrSuppRate_1Mbps:
4510 case eCsrSuppRate_2Mbps:
4511 case eCsrSuppRate_5_5Mbps:
4512 case eCsrSuppRate_11Mbps:
4513 supported = true;
4514 break;
4515 default:
4516 supported = false;
4517 break;
4518 }
4519 } else if (!mac_ctx->roam.configParam.ProprietaryRatesEnabled) {
4520
4521 switch (new_rate) {
4522 case eCsrSuppRate_1Mbps:
4523 case eCsrSuppRate_2Mbps:
4524 case eCsrSuppRate_5_5Mbps:
4525 case eCsrSuppRate_6Mbps:
4526 case eCsrSuppRate_9Mbps:
4527 case eCsrSuppRate_11Mbps:
4528 case eCsrSuppRate_12Mbps:
4529 case eCsrSuppRate_18Mbps:
4530 case eCsrSuppRate_24Mbps:
4531 case eCsrSuppRate_36Mbps:
4532 case eCsrSuppRate_48Mbps:
4533 case eCsrSuppRate_54Mbps:
4534 supported = true;
4535 break;
4536 default:
4537 supported = false;
4538 break;
4539 }
4540 } else if (eCsrSuppRate_1Mbps == new_rate ||
4541 eCsrSuppRate_2Mbps == new_rate ||
4542 eCsrSuppRate_5_5Mbps == new_rate ||
4543 eCsrSuppRate_11Mbps == new_rate) {
4544 supported = true;
4545 } else {
4546 idx = 0x1;
4547
4548 switch (new_rate) {
4549 case eCsrSuppRate_6Mbps:
4550 supported = g_phy_rates_suppt[0][idx];
4551 break;
4552 case eCsrSuppRate_9Mbps:
4553 supported = g_phy_rates_suppt[1][idx];
4554 break;
4555 case eCsrSuppRate_12Mbps:
4556 supported = g_phy_rates_suppt[2][idx];
4557 break;
4558 case eCsrSuppRate_18Mbps:
4559 supported = g_phy_rates_suppt[3][idx];
4560 break;
4561 case eCsrSuppRate_20Mbps:
4562 supported = g_phy_rates_suppt[4][idx];
4563 break;
4564 case eCsrSuppRate_24Mbps:
4565 supported = g_phy_rates_suppt[5][idx];
4566 break;
4567 case eCsrSuppRate_36Mbps:
4568 supported = g_phy_rates_suppt[6][idx];
4569 break;
4570 case eCsrSuppRate_40Mbps:
4571 supported = g_phy_rates_suppt[7][idx];
4572 break;
4573 case eCsrSuppRate_42Mbps:
4574 supported = g_phy_rates_suppt[8][idx];
4575 break;
4576 case eCsrSuppRate_48Mbps:
4577 supported = g_phy_rates_suppt[9][idx];
4578 break;
4579 case eCsrSuppRate_54Mbps:
4580 supported = g_phy_rates_suppt[10][idx];
4581 break;
4582 case eCsrSuppRate_72Mbps:
4583 supported = g_phy_rates_suppt[11][idx];
4584 break;
4585 case eCsrSuppRate_80Mbps:
4586 supported = g_phy_rates_suppt[12][idx];
4587 break;
4588 case eCsrSuppRate_84Mbps:
4589 supported = g_phy_rates_suppt[13][idx];
4590 break;
4591 case eCsrSuppRate_96Mbps:
4592 supported = g_phy_rates_suppt[14][idx];
4593 break;
4594 case eCsrSuppRate_108Mbps:
4595 supported = g_phy_rates_suppt[15][idx];
4596 break;
4597 case eCsrSuppRate_120Mbps:
4598 supported = g_phy_rates_suppt[16][idx];
4599 break;
4600 case eCsrSuppRate_126Mbps:
4601 supported = g_phy_rates_suppt[17][idx];
4602 break;
4603 case eCsrSuppRate_144Mbps:
4604 supported = g_phy_rates_suppt[18][idx];
4605 break;
4606 case eCsrSuppRate_160Mbps:
4607 supported = g_phy_rates_suppt[19][idx];
4608 break;
4609 case eCsrSuppRate_168Mbps:
4610 supported = g_phy_rates_suppt[20][idx];
4611 break;
4612 case eCsrSuppRate_192Mbps:
4613 supported = g_phy_rates_suppt[21][idx];
4614 break;
4615 case eCsrSuppRate_216Mbps:
4616 supported = g_phy_rates_suppt[22][idx];
4617 break;
4618 case eCsrSuppRate_240Mbps:
4619 supported = g_phy_rates_suppt[23][idx];
4620 break;
4621 default:
4622 supported = false;
4623 break;
4624 }
4625 }
4626 return supported;
4627}
4628
4629/**
4630 * csr_is_rate_set_match() - to check if rate set is matching
4631 * @mac_ctx: pointer to mac context
4632 * @bss_supported_rates: supported rates of BSS
4633 * @bss_ext_supp_rates: extended rates of bss
4634 *
4635 * This routine is to checke if rate set is matched or no
4636 *
4637 * Return: bool
4638 */
4639static bool csr_is_rate_set_match(tpAniSirGlobal mac_ctx,
4640 tDot11fIESuppRates *bss_supported_rates,
4641 tDot11fIEExtSuppRates *bss_ext_supp_rates)
4642{
4643 bool match = true;
4644 uint32_t i;
4645
4646 /*
4647 * Validate that all of the Basic rates advertised in the Bss
4648 * description are supported
4649 */
4650 if (bss_supported_rates) {
4651 for (i = 0; i < bss_supported_rates->num_rates; i++) {
4652 if (!CSR_IS_BASIC_RATE(bss_supported_rates->rates[i]))
4653 continue;
4654 if (!csr_is_aggregate_rate_supported(mac_ctx,
4655 bss_supported_rates->rates[i])) {
4656 match = false;
4657 break;
4658 }
4659 }
4660 }
4661 if (match && bss_ext_supp_rates) {
4662 for (i = 0; i < bss_ext_supp_rates->num_rates; i++) {
4663 if (!CSR_IS_BASIC_RATE(bss_ext_supp_rates->rates[i]))
4664 continue;
4665 if (!csr_is_aggregate_rate_supported(mac_ctx,
4666 bss_ext_supp_rates->rates[i])) {
4667 match = false;
4668 break;
4669 }
4670 }
4671 }
4672 return match;
4673}
4674
4675/**
4676 * csr_match_bss() - to compare the bss
4677 * @hal: pointer to hal context
4678 * @bss_descr: pointer bss description
4679 * @filter: scan filter
4680 * @neg_auth: negotiated auth
4681 * @neg_uc: negotiated for unicast
4682 * @neg_mc: negotiated for multicast
4683 * @ie_dblptr: double pointer to IE
4684 *
4685 * This routine will be called to match the bss
4686 * If caller want to get the *ie_dblptr allocated by this function,
4687 * pass in *ie_dblptr = NULL
4688 *
4689 * Return: bool
4690 */
4691bool csr_match_bss(tHalHandle hal, tSirBssDescription *bss_descr,
4692 tCsrScanResultFilter *filter, eCsrAuthType *neg_auth,
4693 eCsrEncryptionType *neg_uc, eCsrEncryptionType *neg_mc,
4694 tDot11fBeaconIEs **ie_dblptr)
4695{
4696 tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
4697 bool rc = false, check, blacklist_check;
4698 uint32_t i;
4699 tDot11fBeaconIEs *ie_ptr = NULL;
4700 uint8_t *pb;
4701 struct roam_ext_params *roam_params;
4702 uint8_t *p2p_macaddr = NULL;
4703
4704 roam_params = &mac_ctx->roam.configParam.roam_params;
4705 if ((NULL == ie_dblptr) || (*ie_dblptr) == NULL) {
4706 /* If no IEs passed in, get our own. */
4707 if (!CDF_IS_STATUS_SUCCESS(
4708 csr_get_parsed_bss_description_ies(mac_ctx,
4709 bss_descr, &ie_ptr))) {
4710 goto end;
4711 }
4712 } else {
4713 /* Save the one pass in for local use */
4714 ie_ptr = *ie_dblptr;
4715 }
4716
4717 /* Check if caller wants P2P */
4718 check = (!filter->p2pResult || ie_ptr->P2PBeaconProbeRes.present);
4719 if (!check)
4720 goto end;
4721
4722 /* Check for Blacklist BSSID's and avoid connections */
4723 blacklist_check = false;
4724 for (i = 0; i < roam_params->num_bssid_avoid_list; i++) {
4725 if (cdf_is_macaddr_equal((struct cdf_mac_addr *)
4726 &roam_params->bssid_avoid_list[i],
4727 (struct cdf_mac_addr *)bss_descr->bssId)) {
4728 blacklist_check = true;
4729 break;
4730 }
4731 }
4732 if (blacklist_check) {
4733 sms_log(mac_ctx, LOGE,
4734 FL("Don't Attempt connect to blacklist bssid"));
4735 goto end;
4736 }
4737
4738 if (ie_ptr->SSID.present) {
4739 for (i = 0; i < filter->SSIDs.numOfSSIDs; i++) {
4740 check = csr_is_ssid_match(mac_ctx,
4741 filter->SSIDs.SSIDList[i].SSID.ssId,
4742 filter->SSIDs.SSIDList[i].SSID.length,
4743 ie_ptr->SSID.ssid,
4744 ie_ptr->SSID.num_ssid, true);
4745 if (check)
4746 break;
4747 }
4748 if (!check)
4749 goto end;
4750 }
4751 check = true;
4752 p2p_macaddr = ie_ptr->P2PBeaconProbeRes.P2PDeviceInfo.P2PDeviceAddress;
4753 for (i = 0; i < filter->BSSIDs.numOfBSSIDs; i++) {
4754 check = csr_is_bssid_match(mac_ctx,
4755 (struct cdf_mac_addr *)&filter->BSSIDs.bssid[i],
4756 (struct cdf_mac_addr *)bss_descr->bssId);
4757 if (check)
4758 break;
4759
4760 if (filter->p2pResult && ie_ptr->P2PBeaconProbeRes.present) {
4761 check = csr_is_bssid_match(mac_ctx,
4762 (struct cdf_mac_addr *)
4763 &filter->BSSIDs.bssid[i],
4764 (struct cdf_mac_addr *)p2p_macaddr);
4765 if (check)
4766 break;
4767 }
4768 }
4769 if (!check)
4770 goto end;
4771
4772 check = true;
4773 for (i = 0; i < filter->ChannelInfo.numOfChannels; i++) {
4774 check = csr_is_channel_band_match(mac_ctx,
4775 filter->ChannelInfo.ChannelList[i], bss_descr);
4776 if (check)
4777 break;
4778 }
4779 if (!check)
4780 goto end;
4781#if defined WLAN_FEATURE_VOWIFI
4782 /* If this is for measurement filtering */
4783 if (filter->fMeasurement) {
4784 rc = true;
4785 goto end;
4786 }
4787#endif
4788 if (!csr_is_phy_mode_match(mac_ctx, filter->phyMode, bss_descr,
4789 NULL, NULL, ie_ptr))
4790 goto end;
4791
4792#ifdef WLAN_FEATURE_11W
4793 if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) &&
4794 !csr_is_security_match(mac_ctx, &filter->authType,
4795 &filter->EncryptionType,
4796 &filter->mcEncryptionType,
4797 &filter->MFPEnabled,
4798 &filter->MFPRequired,
4799 &filter->MFPCapable,
4800 bss_descr, ie_ptr, neg_auth,
4801 neg_uc, neg_mc))
4802#else
4803 if ((!filter->bWPSAssociation) && (!filter->bOSENAssociation) &&
4804 !csr_is_security_match(mac_ctx, &filter->authType,
4805 &filter->EncryptionType,
4806 &filter->mcEncryptionType,
4807 NULL, NULL, NULL,
4808 bss_descr, ie_ptr, neg_auth,
4809 neg_uc, neg_mc))
4810#endif
4811 goto end;
4812 if (!csr_is_capabilities_match(mac_ctx, filter->BSSType, bss_descr))
4813 goto end;
4814 if (!csr_is_rate_set_match(mac_ctx, &ie_ptr->SuppRates,
4815 &ie_ptr->ExtSuppRates))
4816 goto end;
4817 if ((eCsrRoamWmmQbssOnly == mac_ctx->roam.configParam.WMMSupportMode)
4818 && !CSR_IS_QOS_BSS(ie_ptr))
4819 goto end;
4820 /*
4821 * Check country. check even when pb is NULL because we may
4822 * want to make sure
4823 */
4824 pb = (filter->countryCode[0]) ? (filter->countryCode) : NULL;
4825 check = csr_match_country_code(mac_ctx, pb, ie_ptr);
4826 if (!check)
4827 goto end;
4828
4829#ifdef WLAN_FEATURE_VOWIFI_11R
4830 if (filter->MDID.mdiePresent && csr_roam_is11r_assoc(mac_ctx,
4831 mac_ctx->roam.roamSession->sessionId)) {
4832 if (bss_descr->mdiePresent) {
4833 if (filter->MDID.mobilityDomain !=
4834 (bss_descr->mdie[1] << 8 |
4835 bss_descr->mdie[0]))
4836 goto end;
4837 } else {
4838 goto end;
4839 }
4840 }
4841#endif
4842 rc = true;
4843
4844end:
4845 if (ie_dblptr)
4846 *ie_dblptr = ie_ptr;
4847 else if (ie_ptr)
4848 cdf_mem_free(ie_ptr);
4849 return rc;
4850}
4851
4852bool csr_match_connected_bss_security(tpAniSirGlobal pMac,
4853 tCsrRoamConnectedProfile *pProfile,
4854 tSirBssDescription *pBssDesc,
4855 tDot11fBeaconIEs *pIes)
4856{
4857 tCsrEncryptionList ucEncryptionList, mcEncryptionList;
4858 tCsrAuthList authList;
4859
4860 ucEncryptionList.numEntries = 1;
4861 ucEncryptionList.encryptionType[0] = pProfile->EncryptionType;
4862
4863 mcEncryptionList.numEntries = 1;
4864 mcEncryptionList.encryptionType[0] = pProfile->mcEncryptionType;
4865
4866 authList.numEntries = 1;
4867 authList.authType[0] = pProfile->AuthType;
4868
4869 return csr_is_security_match(pMac, &authList, &ucEncryptionList,
4870 &mcEncryptionList, NULL, NULL, NULL,
4871 pBssDesc, pIes, NULL, NULL, NULL);
4872
4873}
4874
4875bool csr_match_bss_to_connect_profile(tHalHandle hHal,
4876 tCsrRoamConnectedProfile *pProfile,
4877 tSirBssDescription *pBssDesc,
4878 tDot11fBeaconIEs *pIes)
4879{
4880 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
4881 bool fRC = false, fCheck;
4882 tDot11fBeaconIEs *pIesLocal = pIes;
4883
4884 do {
4885 if (!pIes) {
4886 if (!CDF_IS_STATUS_SUCCESS
4887 (csr_get_parsed_bss_description_ies
4888 (pMac, pBssDesc, &pIesLocal))) {
4889 break;
4890 }
4891 }
4892 fCheck = true;
4893 if (pIesLocal->SSID.present) {
4894 bool fCheckSsid = false;
4895 if (pProfile->SSID.length) {
4896 fCheckSsid = true;
4897 }
4898 fCheck =
4899 csr_is_ssid_match(pMac, pProfile->SSID.ssId,
4900 pProfile->SSID.length,
4901 pIesLocal->SSID.ssid,
4902 pIesLocal->SSID.num_ssid,
4903 fCheckSsid);
4904 if (!fCheck)
4905 break;
4906 }
4907 if (!csr_match_connected_bss_security
4908 (pMac, pProfile, pBssDesc, pIesLocal))
4909 break;
4910 if (!csr_is_capabilities_match(pMac, pProfile->BSSType, pBssDesc))
4911 break;
4912 if (!csr_is_rate_set_match
4913 (pMac, &pIesLocal->SuppRates, &pIesLocal->ExtSuppRates))
4914 break;
4915 fCheck =
4916 csr_is_channel_band_match(pMac, pProfile->operationChannel,
4917 pBssDesc);
4918 if (!fCheck)
4919 break;
4920
4921 fRC = true;
4922
4923 } while (0);
4924
4925 if (!pIes && pIesLocal) {
4926 /* locally allocated */
4927 cdf_mem_free(pIesLocal);
4928 }
4929
4930 return fRC;
4931}
4932
4933void csr_add_rate_bitmap(uint8_t rate, uint16_t *pRateBitmap)
4934{
4935 uint16_t rateBitmap;
4936 uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
4937 rateBitmap = *pRateBitmap;
4938 switch (n) {
4939 case SIR_MAC_RATE_1:
4940 rateBitmap |= SIR_MAC_RATE_1_BITMAP;
4941 break;
4942 case SIR_MAC_RATE_2:
4943 rateBitmap |= SIR_MAC_RATE_2_BITMAP;
4944 break;
4945 case SIR_MAC_RATE_5_5:
4946 rateBitmap |= SIR_MAC_RATE_5_5_BITMAP;
4947 break;
4948 case SIR_MAC_RATE_11:
4949 rateBitmap |= SIR_MAC_RATE_11_BITMAP;
4950 break;
4951 case SIR_MAC_RATE_6:
4952 rateBitmap |= SIR_MAC_RATE_6_BITMAP;
4953 break;
4954 case SIR_MAC_RATE_9:
4955 rateBitmap |= SIR_MAC_RATE_9_BITMAP;
4956 break;
4957 case SIR_MAC_RATE_12:
4958 rateBitmap |= SIR_MAC_RATE_12_BITMAP;
4959 break;
4960 case SIR_MAC_RATE_18:
4961 rateBitmap |= SIR_MAC_RATE_18_BITMAP;
4962 break;
4963 case SIR_MAC_RATE_24:
4964 rateBitmap |= SIR_MAC_RATE_24_BITMAP;
4965 break;
4966 case SIR_MAC_RATE_36:
4967 rateBitmap |= SIR_MAC_RATE_36_BITMAP;
4968 break;
4969 case SIR_MAC_RATE_48:
4970 rateBitmap |= SIR_MAC_RATE_48_BITMAP;
4971 break;
4972 case SIR_MAC_RATE_54:
4973 rateBitmap |= SIR_MAC_RATE_54_BITMAP;
4974 break;
4975 }
4976 *pRateBitmap = rateBitmap;
4977}
4978
4979bool csr_check_rate_bitmap(uint8_t rate, uint16_t rateBitmap)
4980{
4981 uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
4982
4983 switch (n) {
4984 case SIR_MAC_RATE_1:
4985 rateBitmap &= SIR_MAC_RATE_1_BITMAP;
4986 break;
4987 case SIR_MAC_RATE_2:
4988 rateBitmap &= SIR_MAC_RATE_2_BITMAP;
4989 break;
4990 case SIR_MAC_RATE_5_5:
4991 rateBitmap &= SIR_MAC_RATE_5_5_BITMAP;
4992 break;
4993 case SIR_MAC_RATE_11:
4994 rateBitmap &= SIR_MAC_RATE_11_BITMAP;
4995 break;
4996 case SIR_MAC_RATE_6:
4997 rateBitmap &= SIR_MAC_RATE_6_BITMAP;
4998 break;
4999 case SIR_MAC_RATE_9:
5000 rateBitmap &= SIR_MAC_RATE_9_BITMAP;
5001 break;
5002 case SIR_MAC_RATE_12:
5003 rateBitmap &= SIR_MAC_RATE_12_BITMAP;
5004 break;
5005 case SIR_MAC_RATE_18:
5006 rateBitmap &= SIR_MAC_RATE_18_BITMAP;
5007 break;
5008 case SIR_MAC_RATE_24:
5009 rateBitmap &= SIR_MAC_RATE_24_BITMAP;
5010 break;
5011 case SIR_MAC_RATE_36:
5012 rateBitmap &= SIR_MAC_RATE_36_BITMAP;
5013 break;
5014 case SIR_MAC_RATE_48:
5015 rateBitmap &= SIR_MAC_RATE_48_BITMAP;
5016 break;
5017 case SIR_MAC_RATE_54:
5018 rateBitmap &= SIR_MAC_RATE_54_BITMAP;
5019 break;
5020 }
5021 return !!rateBitmap;
5022}
5023
5024bool csr_rates_is_dot11_rate_supported(tHalHandle hHal, uint8_t rate)
5025{
5026 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
5027 uint16_t n = BITS_OFF(rate, CSR_DOT11_BASIC_RATE_MASK);
5028
5029 return csr_is_aggregate_rate_supported(pMac, n);
5030}
5031
5032uint16_t csr_rates_mac_prop_to_dot11(uint16_t Rate)
5033{
5034 uint16_t ConvertedRate = Rate;
5035
5036 switch (Rate) {
5037 case SIR_MAC_RATE_1:
5038 ConvertedRate = 2;
5039 break;
5040 case SIR_MAC_RATE_2:
5041 ConvertedRate = 4;
5042 break;
5043 case SIR_MAC_RATE_5_5:
5044 ConvertedRate = 11;
5045 break;
5046 case SIR_MAC_RATE_11:
5047 ConvertedRate = 22;
5048 break;
5049
5050 case SIR_MAC_RATE_6:
5051 ConvertedRate = 12;
5052 break;
5053 case SIR_MAC_RATE_9:
5054 ConvertedRate = 18;
5055 break;
5056 case SIR_MAC_RATE_12:
5057 ConvertedRate = 24;
5058 break;
5059 case SIR_MAC_RATE_18:
5060 ConvertedRate = 36;
5061 break;
5062 case SIR_MAC_RATE_24:
5063 ConvertedRate = 48;
5064 break;
5065 case SIR_MAC_RATE_36:
5066 ConvertedRate = 72;
5067 break;
5068 case SIR_MAC_RATE_42:
5069 ConvertedRate = 84;
5070 break;
5071 case SIR_MAC_RATE_48:
5072 ConvertedRate = 96;
5073 break;
5074 case SIR_MAC_RATE_54:
5075 ConvertedRate = 108;
5076 break;
5077
5078 case SIR_MAC_RATE_72:
5079 ConvertedRate = 144;
5080 break;
5081 case SIR_MAC_RATE_84:
5082 ConvertedRate = 168;
5083 break;
5084 case SIR_MAC_RATE_96:
5085 ConvertedRate = 192;
5086 break;
5087 case SIR_MAC_RATE_108:
5088 ConvertedRate = 216;
5089 break;
5090 case SIR_MAC_RATE_126:
5091 ConvertedRate = 252;
5092 break;
5093 case SIR_MAC_RATE_144:
5094 ConvertedRate = 288;
5095 break;
5096 case SIR_MAC_RATE_168:
5097 ConvertedRate = 336;
5098 break;
5099 case SIR_MAC_RATE_192:
5100 ConvertedRate = 384;
5101 break;
5102 case SIR_MAC_RATE_216:
5103 ConvertedRate = 432;
5104 break;
5105 case SIR_MAC_RATE_240:
5106 ConvertedRate = 480;
5107 break;
5108
5109 case 0xff:
5110 ConvertedRate = 0;
5111 break;
5112 }
5113
5114 return ConvertedRate;
5115}
5116
5117uint16_t csr_rates_find_best_rate(tSirMacRateSet *pSuppRates,
5118 tSirMacRateSet *pExtRates,
5119 tSirMacPropRateSet *pPropRates)
5120{
5121 uint8_t i;
5122 uint16_t nBest;
5123
5124 nBest = pSuppRates->rate[0] & (~CSR_DOT11_BASIC_RATE_MASK);
5125
5126 if (pSuppRates->numRates > SIR_MAC_RATESET_EID_MAX) {
5127 pSuppRates->numRates = SIR_MAC_RATESET_EID_MAX;
5128 }
5129
5130 for (i = 1U; i < pSuppRates->numRates; ++i) {
5131 nBest =
5132 (uint16_t) CSR_MAX(nBest,
5133 pSuppRates->
5134 rate[i] & (~CSR_DOT11_BASIC_RATE_MASK));
5135 }
5136
5137 if (NULL != pExtRates) {
5138 for (i = 0U; i < pExtRates->numRates; ++i) {
5139 nBest =
5140 (uint16_t) CSR_MAX(nBest,
5141 pExtRates->
5142 rate[i] &
5143 (~CSR_DOT11_BASIC_RATE_MASK));
5144 }
5145 }
5146
5147 if (NULL != pPropRates) {
5148 for (i = 0U; i < pPropRates->numPropRates; ++i) {
5149 nBest =
5150 (uint16_t) CSR_MAX(nBest,
5151 csr_rates_mac_prop_to_dot11
5152 (pPropRates->propRate[i]));
5153 }
5154 }
5155
5156 return nBest;
5157}
5158
5159void csr_release_profile(tpAniSirGlobal pMac, tCsrRoamProfile *pProfile)
5160{
5161 if (pProfile) {
5162 if (pProfile->BSSIDs.bssid) {
5163 cdf_mem_free(pProfile->BSSIDs.bssid);
5164 pProfile->BSSIDs.bssid = NULL;
5165 }
5166 if (pProfile->SSIDs.SSIDList) {
5167 cdf_mem_free(pProfile->SSIDs.SSIDList);
5168 pProfile->SSIDs.SSIDList = NULL;
5169 }
5170 if (pProfile->pWPAReqIE) {
5171 cdf_mem_free(pProfile->pWPAReqIE);
5172 pProfile->pWPAReqIE = NULL;
5173 }
5174 if (pProfile->pRSNReqIE) {
5175 cdf_mem_free(pProfile->pRSNReqIE);
5176 pProfile->pRSNReqIE = NULL;
5177 }
5178#ifdef FEATURE_WLAN_WAPI
5179 if (pProfile->pWAPIReqIE) {
5180 cdf_mem_free(pProfile->pWAPIReqIE);
5181 pProfile->pWAPIReqIE = NULL;
5182 }
5183#endif /* FEATURE_WLAN_WAPI */
5184
5185 if (pProfile->pAddIEScan) {
5186 cdf_mem_free(pProfile->pAddIEScan);
5187 pProfile->pAddIEScan = NULL;
5188 }
5189
5190 if (pProfile->pAddIEAssoc) {
5191 cdf_mem_free(pProfile->pAddIEAssoc);
5192 pProfile->pAddIEAssoc = NULL;
5193 }
5194 if (pProfile->ChannelInfo.ChannelList) {
5195 cdf_mem_free(pProfile->ChannelInfo.ChannelList);
5196 pProfile->ChannelInfo.ChannelList = NULL;
5197 }
5198 cdf_mem_set(pProfile, sizeof(tCsrRoamProfile), 0);
5199 }
5200}
5201
5202void csr_free_scan_filter(tpAniSirGlobal pMac, tCsrScanResultFilter *pScanFilter)
5203{
5204 if (pScanFilter->BSSIDs.bssid) {
5205 cdf_mem_free(pScanFilter->BSSIDs.bssid);
5206 pScanFilter->BSSIDs.bssid = NULL;
5207 }
5208 if (pScanFilter->ChannelInfo.ChannelList) {
5209 cdf_mem_free(pScanFilter->ChannelInfo.ChannelList);
5210 pScanFilter->ChannelInfo.ChannelList = NULL;
5211 }
5212 if (pScanFilter->SSIDs.SSIDList) {
5213 cdf_mem_free(pScanFilter->SSIDs.SSIDList);
5214 pScanFilter->SSIDs.SSIDList = NULL;
5215 }
5216}
5217
5218void csr_free_roam_profile(tpAniSirGlobal pMac, uint32_t sessionId)
5219{
5220 tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
5221
5222 if (pSession->pCurRoamProfile) {
5223 csr_release_profile(pMac, pSession->pCurRoamProfile);
5224 cdf_mem_free(pSession->pCurRoamProfile);
5225 pSession->pCurRoamProfile = NULL;
5226 }
5227}
5228
5229void csr_free_connect_bss_desc(tpAniSirGlobal pMac, uint32_t sessionId)
5230{
5231 tCsrRoamSession *pSession = &pMac->roam.roamSession[sessionId];
5232
5233 if (pSession->pConnectBssDesc) {
5234 cdf_mem_free(pSession->pConnectBssDesc);
5235 pSession->pConnectBssDesc = NULL;
5236 }
5237}
5238
5239tSirResultCodes csr_get_disassoc_rsp_status_code(tSirSmeDisassocRsp *
5240 pSmeDisassocRsp)
5241{
5242 uint8_t *pBuffer = (uint8_t *) pSmeDisassocRsp;
5243 uint32_t ret;
5244
5245 pBuffer += (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(tSirMacAddr));
5246 /* tSirResultCodes is an enum, assuming is 32bit */
5247 /* If we cannot make this assumption, use copymemory */
5248 cdf_get_u32(pBuffer, &ret);
5249
5250 return (tSirResultCodes) ret;
5251}
5252
5253tSirResultCodes csr_get_de_auth_rsp_status_code(tSirSmeDeauthRsp *pSmeRsp)
5254{
5255 uint8_t *pBuffer = (uint8_t *) pSmeRsp;
5256 uint32_t ret;
5257
5258 pBuffer +=
5259 (sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint8_t) +
5260 sizeof(uint16_t));
5261 /* tSirResultCodes is an enum, assuming is 32bit */
5262 /* If we cannot make this assumption, use copymemory */
5263 cdf_get_u32(pBuffer, &ret);
5264
5265 return (tSirResultCodes) ret;
5266}
5267
5268tSirScanType csr_get_scan_type(tpAniSirGlobal pMac, uint8_t chnId)
5269{
5270 tSirScanType scanType = eSIR_PASSIVE_SCAN;
5271 CHANNEL_STATE channelEnabledType;
5272
5273 channelEnabledType = cds_get_channel_state(chnId);
5274 if (CHANNEL_STATE_ENABLE == channelEnabledType) {
5275 scanType = eSIR_ACTIVE_SCAN;
5276 }
5277 return scanType;
5278}
5279
5280uint8_t csr_to_upper(uint8_t ch)
5281{
5282 uint8_t chOut;
5283
5284 if (ch >= 'a' && ch <= 'z') {
5285 chOut = ch - 'a' + 'A';
5286 } else {
5287 chOut = ch;
5288 }
5289 return chOut;
5290}
5291
5292tSirBssType csr_translate_bsstype_to_mac_type(eCsrRoamBssType csrtype)
5293{
5294 tSirBssType ret;
5295
5296 switch (csrtype) {
5297 case eCSR_BSS_TYPE_INFRASTRUCTURE:
5298 ret = eSIR_INFRASTRUCTURE_MODE;
5299 break;
5300 case eCSR_BSS_TYPE_IBSS:
5301 case eCSR_BSS_TYPE_START_IBSS:
5302 ret = eSIR_IBSS_MODE;
5303 break;
5304 case eCSR_BSS_TYPE_WDS_AP:
5305 ret = eSIR_BTAMP_AP_MODE;
5306 break;
5307 case eCSR_BSS_TYPE_WDS_STA:
5308 ret = eSIR_BTAMP_STA_MODE;
5309 break;
5310 case eCSR_BSS_TYPE_INFRA_AP:
5311 ret = eSIR_INFRA_AP_MODE;
5312 break;
5313 case eCSR_BSS_TYPE_ANY:
5314 default:
5315 ret = eSIR_AUTO_MODE;
5316 break;
5317 }
5318
5319 return ret;
5320}
5321
5322/* This function use the parameters to decide the CFG value. */
5323/* CSR never sets WNI_CFG_DOT11_MODE_ALL to the CFG */
5324/* So PE should not see WNI_CFG_DOT11_MODE_ALL when it gets the CFG value */
5325eCsrCfgDot11Mode csr_get_cfg_dot11_mode_from_csr_phy_mode(tCsrRoamProfile *pProfile,
5326 eCsrPhyMode phyMode,
5327 bool fProprietary)
5328{
5329 uint32_t cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
5330
5331 switch (phyMode) {
5332 case eCSR_DOT11_MODE_11a:
5333 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11A;
5334 break;
5335 case eCSR_DOT11_MODE_11b:
5336 case eCSR_DOT11_MODE_11b_ONLY:
5337 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11B;
5338 break;
5339 case eCSR_DOT11_MODE_11g:
5340 case eCSR_DOT11_MODE_11g_ONLY:
5341 if (pProfile && (CSR_IS_INFRA_AP(pProfile))
5342 && (phyMode == eCSR_DOT11_MODE_11g_ONLY))
5343 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G_ONLY;
5344 else
5345 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11G;
5346 break;
5347 case eCSR_DOT11_MODE_11n:
5348 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5349 break;
5350 case eCSR_DOT11_MODE_11n_ONLY:
5351 if (pProfile && CSR_IS_INFRA_AP(pProfile))
5352 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N_ONLY;
5353 else
5354 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5355 break;
5356 case eCSR_DOT11_MODE_abg:
5357 cfgDot11Mode = eCSR_CFG_DOT11_MODE_ABG;
5358 break;
5359 case eCSR_DOT11_MODE_AUTO:
5360 cfgDot11Mode = eCSR_CFG_DOT11_MODE_AUTO;
5361 break;
5362
5363#ifdef WLAN_FEATURE_11AC
5364 case eCSR_DOT11_MODE_11ac:
5365 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
5366 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC;
5367 } else {
5368 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5369 }
5370 break;
5371 case eCSR_DOT11_MODE_11ac_ONLY:
5372 if (IS_FEATURE_SUPPORTED_BY_FW(DOT11AC)) {
5373 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11AC_ONLY;
5374 } else {
5375 cfgDot11Mode = eCSR_CFG_DOT11_MODE_11N;
5376 }
5377 break;
5378#endif
5379 default:
5380 /* No need to assign anything here */
5381 break;
5382 }
5383
5384 return cfgDot11Mode;
5385}
5386
5387CDF_STATUS csr_get_regulatory_domain_for_country
5388 (tpAniSirGlobal pMac,
5389 uint8_t *pCountry,
5390 v_REGDOMAIN_t *pDomainId, v_CountryInfoSource_t source) {
5391 CDF_STATUS status = CDF_STATUS_E_INVAL;
5392 CDF_STATUS cdf_status;
5393 country_code_t countryCode;
5394 v_REGDOMAIN_t domainId;
5395
5396 if (pCountry) {
5397 countryCode[0] = pCountry[0];
5398 countryCode[1] = pCountry[1];
5399 cdf_status = cds_get_reg_domain_from_country_code(&domainId,
5400 countryCode,
5401 source);
5402
5403 if (CDF_IS_STATUS_SUCCESS(cdf_status)) {
5404 if (pDomainId) {
5405 *pDomainId = domainId;
5406 }
5407 status = CDF_STATUS_SUCCESS;
5408 } else {
5409 sms_log(pMac, LOGW,
5410 FL
5411 (" Couldn't find domain for country code %c%c"),
5412 pCountry[0], pCountry[1]);
5413 status = CDF_STATUS_E_INVAL;
5414 }
5415 }
5416
5417 return status;
5418}
5419
5420/* To check whether a country code matches the one in the IE */
5421/* Only check the first two characters, ignoring in/outdoor */
5422/* pCountry -- caller allocated buffer contain the country code that is checking against */
5423/* the one in pIes. It can be NULL. */
5424/* caller must provide pIes, it cannot be NULL */
5425/* This function always return true if 11d support is not turned on. */
5426bool csr_match_country_code(tpAniSirGlobal pMac, uint8_t *pCountry,
5427 tDot11fBeaconIEs *pIes)
5428{
5429 bool fRet = true;
5430
5431 do {
5432 if (!csr_is11d_supported(pMac)) {
5433 break;
5434 }
5435 if (!pIes) {
5436 sms_log(pMac, LOGE, FL(" No IEs"));
5437 break;
5438 }
5439
5440 if (pCountry) {
5441 uint32_t i;
5442
5443 if (!pIes->Country.present) {
5444 fRet = false;
5445 break;
5446 }
5447 /* Convert the CountryCode characters to upper */
5448 for (i = 0; i < WNI_CFG_COUNTRY_CODE_LEN - 1; i++) {
5449 pCountry[i] = csr_to_upper(pCountry[i]);
5450 }
5451 if (!cdf_mem_compare(pIes->Country.country, pCountry,
5452 WNI_CFG_COUNTRY_CODE_LEN - 1)) {
5453 fRet = false;
5454 break;
5455 }
5456 }
5457 } while (0);
5458
5459 return fRet;
5460}
5461
5462CDF_STATUS csr_get_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId,
5463 tCsrRoamModifyProfileFields *
5464 pModifyProfileFields)
5465{
5466
5467 if (!pModifyProfileFields) {
5468 return CDF_STATUS_E_FAILURE;
5469 }
5470
5471 cdf_mem_copy(pModifyProfileFields,
5472 &pMac->roam.roamSession[sessionId].connectedProfile.
5473 modifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
5474
5475 return CDF_STATUS_SUCCESS;
5476}
5477
5478CDF_STATUS csr_set_modify_profile_fields(tpAniSirGlobal pMac, uint32_t sessionId,
5479 tCsrRoamModifyProfileFields *
5480 pModifyProfileFields)
5481{
5482 tCsrRoamSession *pSession = CSR_GET_SESSION(pMac, sessionId);
5483
5484 cdf_mem_copy(&pSession->connectedProfile.modifyProfileFields,
5485 pModifyProfileFields, sizeof(tCsrRoamModifyProfileFields));
5486
5487 return CDF_STATUS_SUCCESS;
5488}
5489
5490
5491bool csr_is_set_key_allowed(tpAniSirGlobal pMac, uint32_t sessionId)
5492{
5493 bool fRet = true;
5494 tCsrRoamSession *pSession;
5495
5496 pSession = CSR_GET_SESSION(pMac, sessionId);
5497
5498 /*
5499 * This condition is not working for infra state. When infra is in
5500 * not-connected state the pSession->pCurRoamProfile is NULL, this
5501 * function returns true, that is incorrect.
5502 * Since SAP requires to set key without any BSS started, it needs
5503 * this condition to be met. In other words, this function is useless.
5504 * The current work-around is to process setcontext_rsp no matter
5505 * what the state is.
5506 */
5507 sms_log(pMac, LOG2,
5508 FL(" is not what it intends to. Must be revisit or removed"));
5509 if ((NULL == pSession)
5510 || (csr_is_conn_state_disconnected(pMac, sessionId)
5511 && (pSession->pCurRoamProfile != NULL)
5512 && (!(CSR_IS_INFRA_AP(pSession->pCurRoamProfile))))
5513 ) {
5514 fRet = false;
5515 }
5516
5517 return fRet;
5518}
5519
5520/* no need to acquire lock for this basic function */
5521uint16_t sme_chn_to_freq(uint8_t chanNum)
5522{
5523 int i;
5524
5525 for (i = 0; i < NUM_RF_CHANNELS; i++) {
5526 if (rf_channels[i].channelNum == chanNum) {
5527 return rf_channels[i].targetFreq;
5528 }
5529 }
5530
5531 return 0;
5532}
5533
5534/* Disconnect all active sessions by sending disassoc. This is mainly used to disconnect the remaining session when we
5535 * transition from concurrent sessions to a single session. The use case is Infra STA and wifi direct multiple sessions are up and
5536 * P2P session is removed. The Infra STA session remains and should resume BMPS if BMPS is enabled by default. However, there
5537 * are some issues seen with BMPS resume during this transition and this is a workaround which will allow the Infra STA session to
5538 * disconnect and auto connect back and enter BMPS this giving the same effect as resuming BMPS
5539 */
5540
5541/* Remove this code once SLM_Sessionization is supported */
5542/* BMPS_WORKAROUND_NOT_NEEDED */
5543void csr_disconnect_all_active_sessions(tpAniSirGlobal pMac)
5544{
5545 uint8_t i;
5546
5547 /* Disconnect all the active sessions */
5548 for (i = 0; i < CSR_ROAM_SESSION_MAX; i++) {
5549 if (CSR_IS_SESSION_VALID(pMac, i)
5550 && !csr_is_conn_state_disconnected(pMac, i)) {
5551 csr_roam_disconnect_internal(pMac, i,
5552 eCSR_DISCONNECT_REASON_UNSPECIFIED);
5553 }
5554 }
5555}
5556
5557#ifdef FEATURE_WLAN_LFR
5558bool csr_is_channel_present_in_list(uint8_t *pChannelList,
5559 int numChannels, uint8_t channel)
5560{
5561 int i = 0;
5562
5563 /* Check for NULL pointer */
5564 if (!pChannelList || (numChannels == 0)) {
5565 return false;
5566 }
5567 /* Look for the channel in the list */
5568 for (i = 0; (i < numChannels) &&
5569 (i < WNI_CFG_VALID_CHANNEL_LIST_LEN); i++) {
5570 if (pChannelList[i] == channel)
5571 return true;
5572 }
5573
5574 return false;
5575}
5576
5577CDF_STATUS csr_add_to_channel_list_front(uint8_t *pChannelList,
5578 int numChannels, uint8_t channel)
5579{
5580 int i = 0;
5581
5582 /* Check for NULL pointer */
5583 if (!pChannelList)
5584 return CDF_STATUS_E_NULL_VALUE;
5585
5586 /* Make room for the addition. (Start moving from the back.) */
5587 for (i = numChannels; i > 0; i--) {
5588 pChannelList[i] = pChannelList[i - 1];
5589 }
5590
5591 /* Now add the NEW channel...at the front */
5592 pChannelList[0] = channel;
5593
5594 return CDF_STATUS_SUCCESS;
5595}
5596#endif
5597#ifdef FEATURE_WLAN_DIAG_SUPPORT
5598/**
5599 * csr_diag_event_report() - send PE diag event
5600 * @pmac: pointer to global MAC context.
5601 * @event_typev: sub event type for DIAG event.
5602 * @status: status of the event
5603 * @reasoncode: reasoncode for the given status
5604 *
5605 * This function is called to send diag event
5606 *
5607 * Return: NA
5608 */
5609void csr_diag_event_report(tpAniSirGlobal pmac, uint16_t event_type,
5610 uint16_t status, uint16_t reasoncode)
5611{
5612 WLAN_HOST_DIAG_EVENT_DEF(diag_event, host_event_wlan_pe_payload_type);
5613
5614 cdf_mem_zero(&diag_event, sizeof(host_event_wlan_pe_payload_type));
5615
5616 /* diag_event.bssid is already all zeroes */
5617 diag_event.sme_state = sme_get_lim_sme_state(pmac);
5618 diag_event.mlm_state = sme_get_lim_mlm_state(pmac);
5619 diag_event.event_type = event_type;
5620 diag_event.status = status;
5621 diag_event.reason_code = reasoncode;
5622
5623 WLAN_HOST_DIAG_EVENT_REPORT(&diag_event, EVENT_WLAN_PE);
5624 return;
5625}
5626#endif