2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/rate.c#1 $
6 \brief This file contains the transmission rate handling routines.
8 This file contains the transmission rate handling routines for setting up
9 ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do
10 conversion between Rate Set and Data Rates.
13 /*******************************************************************************
14 * Copyright (c) 2007 MediaTek Inc.
16 * All rights reserved. Copying, compilation, modification, distribution
17 * or any other use whatsoever of this material is strictly prohibited
18 * except in accordance with a Software License Agreement with
20 ********************************************************************************
23 /*******************************************************************************
26 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
27 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
28 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
29 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
30 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
31 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
32 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
33 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
34 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
35 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
36 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
37 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
38 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
40 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
41 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
42 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
43 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
44 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
46 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
47 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
48 * OF LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
49 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
50 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
52 ********************************************************************************
59 * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
60 * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
64 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
67 * [WPD00003833][MT6620 and MT5931] Driver migration
70 * 03 16 2010 kevin.huang
71 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
75 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
78 * Nov 23 2009 mtk01461
79 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
82 * Nov 16 2009 mtk01461
83 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
87 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
89 ** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461
90 ** Fix the problem that do not ASSERT the length of Supported Rate IE == 8
91 ** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088
92 ** fixed the lint "possible using null pointer" warning
93 ** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461
94 ** Update for Driver Review
95 ** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461
96 ** Revise GEN Link Speed OID
97 ** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461
98 ** Add rateGetRateSetFromDataRates() for set desired rate OID
99 ** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461
100 ** Add adopt operational rate as ACK rate if BasicRateSet was not found
102 ** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461
103 ** Add initial rate according rx signal quality support
104 ** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461
105 ** Fix typo of rate adaptation of CtrlResp Frame
106 ** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461
107 ** Add VOIP SCAN Support & Refine Roaming
110 /*******************************************************************************
111 * C O M P I L E R F L A G S
112 ********************************************************************************
115 /*******************************************************************************
116 * E X T E R N A L R E F E R E N C E S
117 ********************************************************************************
121 /*******************************************************************************
123 ********************************************************************************
125 /* The list of valid data rates. */
126 const UINT_8 aucDataRate[] = {
127 RATE_1M, /* RATE_1M_INDEX = 0 */
128 RATE_2M, /* RATE_2M_INDEX */
129 RATE_5_5M, /* RATE_5_5M_INDEX */
130 RATE_11M, /* RATE_11M_INDEX */
131 RATE_22M, /* RATE_22M_INDEX */
132 RATE_33M, /* RATE_33M_INDEX */
133 RATE_6M, /* RATE_6M_INDEX */
134 RATE_9M, /* RATE_9M_INDEX */
135 RATE_12M, /* RATE_12M_INDEX */
136 RATE_18M, /* RATE_18M_INDEX */
137 RATE_24M, /* RATE_24M_INDEX */
138 RATE_36M, /* RATE_36M_INDEX */
139 RATE_48M, /* RATE_48M_INDEX */
140 RATE_54M, /* RATE_54M_INDEX */
141 RATE_HT_PHY /* RATE_HT_PHY_INDEX */
144 static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = {
145 RATE_1M_INDEX, /* RATE_1M_INDEX = 0 */
146 RATE_2M_INDEX, /* RATE_2M_INDEX */
147 RATE_5_5M_INDEX, /* RATE_5_5M_INDEX */
148 RATE_11M_INDEX, /* RATE_11M_INDEX */
149 RATE_1M_INDEX, /* RATE_22M_INDEX - Not supported */
150 RATE_1M_INDEX, /* RATE_33M_INDEX - Not supported */
151 RATE_6M_INDEX, /* RATE_6M_INDEX */
152 RATE_6M_INDEX, /* RATE_9M_INDEX */
153 RATE_12M_INDEX, /* RATE_12M_INDEX */
154 RATE_12M_INDEX, /* RATE_18M_INDEX */
155 RATE_24M_INDEX, /* RATE_24M_INDEX */
156 RATE_24M_INDEX, /* RATE_36M_INDEX */
157 RATE_24M_INDEX, /* RATE_48M_INDEX */
158 RATE_24M_INDEX /* RATE_54M_INDEX */
161 const BOOLEAN afgIsOFDMRate[RATE_NUM] = {
162 FALSE, /* RATE_1M_INDEX = 0 */
163 FALSE, /* RATE_2M_INDEX */
164 FALSE, /* RATE_5_5M_INDEX */
165 FALSE, /* RATE_11M_INDEX */
166 FALSE, /* RATE_22M_INDEX - Not supported */
167 FALSE, /* RATE_33M_INDEX - Not supported */
168 TRUE, /* RATE_6M_INDEX */
169 TRUE, /* RATE_9M_INDEX */
170 TRUE, /* RATE_12M_INDEX */
171 TRUE, /* RATE_18M_INDEX */
172 TRUE, /* RATE_24M_INDEX */
173 TRUE, /* RATE_36M_INDEX */
174 TRUE, /* RATE_48M_INDEX */
175 TRUE /* RATE_54M_INDEX */
178 /*******************************************************************************
180 ********************************************************************************
183 /*******************************************************************************
184 * P U B L I C D A T A
185 ********************************************************************************
188 /*******************************************************************************
189 * P R I V A T E D A T A
190 ********************************************************************************
193 /*******************************************************************************
195 ********************************************************************************
198 /*******************************************************************************
199 * F U N C T I O N D E C L A R A T I O N S
200 ********************************************************************************
203 /*******************************************************************************
205 ********************************************************************************
207 /*----------------------------------------------------------------------------*/
209 * @brief Convert the given Supported Rate & Extended Supported Rate IE to the
210 * Operational Rate Set and Basic Rate Set, and also check if any Basic
211 * Rate Code is unknown by driver.
213 * @param[in] prIeSupportedRate Pointer to the Supported Rate IE
214 * @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE
215 * @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set
216 * @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set
217 * @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic
218 * Rate Set has unknown Rate Code
222 /*----------------------------------------------------------------------------*/
224 rateGetRateSetFromIEs (
225 IN P_IE_SUPPORTED_RATE_T prIeSupportedRate,
226 IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate,
227 OUT PUINT_16 pu2OperationalRateSet,
228 OUT PUINT_16 pu2BSSBasicRateSet,
229 OUT PBOOLEAN pfgIsUnknownBSSBasicRate
232 UINT_16 u2OperationalRateSet = 0;
233 UINT_16 u2BSSBasicRateSet = 0;
234 BOOLEAN fgIsUnknownBSSBasicRate = FALSE;
239 ASSERT(pu2OperationalRateSet);
240 ASSERT(pu2BSSBasicRateSet);
241 ASSERT(pfgIsUnknownBSSBasicRate);
243 if (prIeSupportedRate) {
244 /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
245 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
246 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
248 //ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES);
249 ASSERT(prIeSupportedRate->ucLength <= RATE_NUM);
251 for (i = 0; i < prIeSupportedRate->ucLength; i++) {
252 ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK;
254 /* Search all valid data rates */
255 for (j = 0; j < sizeof(aucDataRate)/sizeof(UINT_8); j++) {
256 if (ucRate == aucDataRate[j]) {
257 u2OperationalRateSet |= BIT(j);
259 if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) {
260 u2BSSBasicRateSet |= BIT(j);
267 if ((j == sizeof(aucDataRate)/sizeof(UINT_8)) &&
268 (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) {
269 fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */
275 if (prIeExtSupportedRate) {
276 //ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES);
278 for (i = 0; i < prIeExtSupportedRate->ucLength; i++) {
279 ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK;
281 /* Search all valid data rates */
282 for (j = 0; j < sizeof(aucDataRate)/sizeof(UINT_8); j++) {
283 if (ucRate == aucDataRate[j]) {
284 u2OperationalRateSet |= BIT(j);
286 if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) {
287 u2BSSBasicRateSet |= BIT(j);
294 if ((j == sizeof(aucDataRate)/sizeof(UINT_8)) &&
295 (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) {
296 fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */
301 *pu2OperationalRateSet = u2OperationalRateSet;
302 *pu2BSSBasicRateSet = u2BSSBasicRateSet;
303 *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate;
307 } /* end of rateGetRateSetFromIEs() */
310 /*----------------------------------------------------------------------------*/
312 * @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code
313 * Format for used in (Ext)Supportec Rate IE.
315 * @param[in] u2OperationalRateSet Operational Rate Set
316 * @param[in] u2BSSBasicRateSet Basic Rate Set
317 * @param[out] pucDataRates Pointer to the Data Rate Buffer
318 * @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length
322 /*----------------------------------------------------------------------------*/
324 rateGetDataRatesFromRateSet (
325 IN UINT_16 u2OperationalRateSet,
326 IN UINT_16 u2BSSBasicRateSet,
327 OUT PUINT_8 pucDataRates,
328 OUT PUINT_8 pucDataRatesLen
334 ASSERT(pucDataRates);
335 ASSERT(pucDataRatesLen);
337 ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
339 for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) {
340 if (u2OperationalRateSet & BIT(i)) {
342 *(pucDataRates + j) = aucDataRate[i];
344 if (u2BSSBasicRateSet & BIT(i)) {
345 *(pucDataRates + j) |= RATE_BASIC_BIT;
352 *pucDataRatesLen = (UINT_8)j;
356 } /* end of rateGetDataRatesFromRateSet() */
359 /*----------------------------------------------------------------------------*/
361 * \brief Get the highest rate from given Rate Set.
363 * \param[in] u2RateSet Rate Set
364 * \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index
366 * \retval TRUE Highest Rate Index was found
367 * \retval FALSE Highest Rate Index was not found
369 /*----------------------------------------------------------------------------*/
371 rateGetHighestRateIndexFromRateSet (
372 IN UINT_16 u2RateSet,
373 OUT PUINT_8 pucHighestRateIndex
379 ASSERT(pucHighestRateIndex);
381 for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
382 if (u2RateSet & BIT(i)) {
383 *pucHighestRateIndex = (UINT_8)i;
390 } /* end of rateGetHighestRateIndexFromRateSet() */
393 /*----------------------------------------------------------------------------*/
395 * \brief Get the lowest rate from given Rate Set.
397 * \param[in] u2RateSet Rate Set
398 * \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index
400 * \retval TRUE Lowest Rate Index was found
401 * \retval FALSE Lowest Rate Index was not found
403 /*----------------------------------------------------------------------------*/
405 rateGetLowestRateIndexFromRateSet (
406 IN UINT_16 u2RateSet,
407 OUT PUINT_8 pucLowestRateIndex
412 ASSERT(pucLowestRateIndex);
414 for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) {
415 if (u2RateSet & BIT(i)) {
416 *pucLowestRateIndex = (UINT_8)i;
423 } /* end of rateGetLowestRateIndexFromRateSet() */
426 #if 0 // NOTE(Kevin): For reference
427 /*----------------------------------------------------------------------------*/
429 * \brief Convert the given Data Rates to the Rate Set.
431 * \param[in] pucDataRates Pointer to the Data Rates
432 * \param[in] ucDataRatesLen Length of given Data Rates
433 * \param[out] pu2RateSet Pointer to the Rate Set
437 /*----------------------------------------------------------------------------*/
439 rateGetRateSetFromDataRates (
440 IN PUINT_8 pucDataRates,
441 IN UINT_8 ucDataRatesLen,
442 OUT PUINT_16 pu2RateSet
445 UINT_16 u2RateSet = 0;
450 ASSERT(pucDataRates);
454 for (i = 0; i < ucDataRatesLen; i++) {
455 ucRate = pucDataRates[i] & RATE_MASK;
457 /* Search all valid data rates */
458 for (j = 0; j < sizeof(aucDataRate)/sizeof(UINT_8); j++) {
459 if (ucRate == aucDataRate[j]) {
467 *pu2RateSet = u2RateSet;
471 } /* end of rateGetRateSetFromDataRates() */
474 /*----------------------------------------------------------------------------*/
476 * \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding
477 * ACK/CTS(Respnose) TX Rates.
479 * \param[in] u2OperationalRateSet Operational Rate Set
480 * \param[in] u2BSSBasicRateSet Basic Rate Set
481 * \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer
485 /*----------------------------------------------------------------------------*/
487 rateSetAckCtsDataRatesFromRateSet (
488 IN UINT_16 u2OperationalRateSet,
489 IN UINT_16 u2BSSBasicRateSet,
490 IN OUT UINT_8 aucAckCtsRateIndex[]
496 ASSERT(aucAckCtsRateIndex);
497 ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
499 /* Setup default ACK/CTS response rate */
500 kalMemCopy(aucAckCtsRateIndex, (PVOID)aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex));
503 for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
504 if (u2OperationalRateSet & BIT(i)) {
505 for (j = i; j >= RATE_1M_INDEX; j--) {
506 if (u2BSSBasicRateSet & BIT(j)) {
507 if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) // Reply ACK Frame at the same Modulation Scheme.
508 aucAckCtsRateIndex[i] = (UINT_8)j;
513 /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has
515 * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL.
516 * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"].
517 * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M],
518 * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still
519 * use highest mandatory rate as default.
521 if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */
522 if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet)) {
523 aucAckCtsRateIndex[i] = (UINT_8)i;
531 } /* end of rateSetAckCtsDataRatesFromRateSet() */
534 /*----------------------------------------------------------------------------*/
536 * \brief Get the proper initial rate from Rate Set according to given RCPI value
538 * \param[in] u2RateSet Rate Set
539 * \param[in] rRcpi RCPI value from AP or Peer STA
540 * \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index
542 * \retval TRUE Initial Rate Index was found
543 * \retval FALSE Initial Rate Index was not found
545 /*----------------------------------------------------------------------------*/
547 rateGetBestInitialRateIndex (
548 IN UINT_16 u2RateSet,
550 OUT PUINT_8 pucInitialRateIndex
553 UINT_16 u2InitRateSet;
557 ASSERT(pucInitialRateIndex);
559 DBGLOG(MGT, TRACE, ("rRcpi = %d\n", rRcpi));
561 if (rRcpi >= RCPI_100) { /* Best Signal */
562 u2InitRateSet = INITIAL_RATE_SET(RCPI_100);
564 else if (rRcpi >= RCPI_80) { /* Better Signal */
565 u2InitRateSet = INITIAL_RATE_SET(RCPI_80);
567 else if (rRcpi >= RCPI_60) { /* Good Signal */
568 u2InitRateSet = INITIAL_RATE_SET(RCPI_60);
570 else { /* Worse Signal */
571 /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index
572 * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in
573 * function - bssUpdateTxRateForControlFrame().
578 u2RateSet &= u2InitRateSet;
580 for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
581 if (u2RateSet & BIT(i)) {
582 *pucInitialRateIndex = (UINT_8)i;
589 } /* end of rateGetBestInitialRateIndex() */