2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/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.
20 * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
23 * [WPD00003833][MT6620 and MT5931] Driver migration
26 * 03 16 2010 kevin.huang
27 * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
31 * [BORA00000018]Integrate WIFI part into BORA for the 1st time
34 * Nov 23 2009 mtk01461
35 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
38 * Nov 16 2009 mtk01461
39 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
43 * [BORA00000018] Integrate WIFI part into BORA for the 1st time
45 ** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461
46 ** Fix the problem that do not ASSERT the length of Supported Rate IE == 8
47 ** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088
48 ** fixed the lint "possible using null pointer" warning
49 ** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461
50 ** Update for Driver Review
51 ** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461
52 ** Revise GEN Link Speed OID
53 ** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461
54 ** Add rateGetRateSetFromDataRates() for set desired rate OID
55 ** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461
56 ** Add adopt operational rate as ACK rate if BasicRateSet was not found
58 ** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461
59 ** Add initial rate according rx signal quality support
60 ** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461
61 ** Fix typo of rate adaptation of CtrlResp Frame
62 ** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461
63 ** Add VOIP SCAN Support & Refine Roaming
66 /*******************************************************************************
67 * C O M P I L E R F L A G S
68 ********************************************************************************
71 /*******************************************************************************
72 * E X T E R N A L R E F E R E N C E S
73 ********************************************************************************
77 /*******************************************************************************
79 ********************************************************************************
81 /* The list of valid data rates. */
82 const UINT_8 aucDataRate
[] = {
83 RATE_1M
, /* RATE_1M_INDEX = 0 */
84 RATE_2M
, /* RATE_2M_INDEX */
85 RATE_5_5M
, /* RATE_5_5M_INDEX */
86 RATE_11M
, /* RATE_11M_INDEX */
87 RATE_22M
, /* RATE_22M_INDEX */
88 RATE_33M
, /* RATE_33M_INDEX */
89 RATE_6M
, /* RATE_6M_INDEX */
90 RATE_9M
, /* RATE_9M_INDEX */
91 RATE_12M
, /* RATE_12M_INDEX */
92 RATE_18M
, /* RATE_18M_INDEX */
93 RATE_24M
, /* RATE_24M_INDEX */
94 RATE_36M
, /* RATE_36M_INDEX */
95 RATE_48M
, /* RATE_48M_INDEX */
96 RATE_54M
, /* RATE_54M_INDEX */
97 RATE_HT_PHY
/* RATE_HT_PHY_INDEX */
100 static const UINT_8 aucDefaultAckCtsRateIndex
[RATE_NUM
] = {
101 RATE_1M_INDEX
, /* RATE_1M_INDEX = 0 */
102 RATE_2M_INDEX
, /* RATE_2M_INDEX */
103 RATE_5_5M_INDEX
, /* RATE_5_5M_INDEX */
104 RATE_11M_INDEX
, /* RATE_11M_INDEX */
105 RATE_1M_INDEX
, /* RATE_22M_INDEX - Not supported */
106 RATE_1M_INDEX
, /* RATE_33M_INDEX - Not supported */
107 RATE_6M_INDEX
, /* RATE_6M_INDEX */
108 RATE_6M_INDEX
, /* RATE_9M_INDEX */
109 RATE_12M_INDEX
, /* RATE_12M_INDEX */
110 RATE_12M_INDEX
, /* RATE_18M_INDEX */
111 RATE_24M_INDEX
, /* RATE_24M_INDEX */
112 RATE_24M_INDEX
, /* RATE_36M_INDEX */
113 RATE_24M_INDEX
, /* RATE_48M_INDEX */
114 RATE_24M_INDEX
/* RATE_54M_INDEX */
117 const BOOLEAN afgIsOFDMRate
[RATE_NUM
] = {
118 FALSE
, /* RATE_1M_INDEX = 0 */
119 FALSE
, /* RATE_2M_INDEX */
120 FALSE
, /* RATE_5_5M_INDEX */
121 FALSE
, /* RATE_11M_INDEX */
122 FALSE
, /* RATE_22M_INDEX - Not supported */
123 FALSE
, /* RATE_33M_INDEX - Not supported */
124 TRUE
, /* RATE_6M_INDEX */
125 TRUE
, /* RATE_9M_INDEX */
126 TRUE
, /* RATE_12M_INDEX */
127 TRUE
, /* RATE_18M_INDEX */
128 TRUE
, /* RATE_24M_INDEX */
129 TRUE
, /* RATE_36M_INDEX */
130 TRUE
, /* RATE_48M_INDEX */
131 TRUE
/* RATE_54M_INDEX */
134 /*******************************************************************************
136 ********************************************************************************
139 /*******************************************************************************
140 * P U B L I C D A T A
141 ********************************************************************************
144 /*******************************************************************************
145 * P R I V A T E D A T A
146 ********************************************************************************
149 /*******************************************************************************
151 ********************************************************************************
154 /*******************************************************************************
155 * F U N C T I O N D E C L A R A T I O N S
156 ********************************************************************************
159 /*******************************************************************************
161 ********************************************************************************
163 /*----------------------------------------------------------------------------*/
165 * @brief Convert the given Supported Rate & Extended Supported Rate IE to the
166 * Operational Rate Set and Basic Rate Set, and also check if any Basic
167 * Rate Code is unknown by driver.
169 * @param[in] prIeSupportedRate Pointer to the Supported Rate IE
170 * @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE
171 * @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set
172 * @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set
173 * @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic
174 * Rate Set has unknown Rate Code
178 /*----------------------------------------------------------------------------*/
180 rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate
,
181 IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate
,
182 OUT PUINT_16 pu2OperationalRateSet
,
183 OUT PUINT_16 pu2BSSBasicRateSet
, OUT PBOOLEAN pfgIsUnknownBSSBasicRate
)
185 UINT_16 u2OperationalRateSet
= 0;
186 UINT_16 u2BSSBasicRateSet
= 0;
187 BOOLEAN fgIsUnknownBSSBasicRate
= FALSE
;
192 ASSERT(pu2OperationalRateSet
);
193 ASSERT(pu2BSSBasicRateSet
);
194 ASSERT(pfgIsUnknownBSSBasicRate
);
196 if (prIeSupportedRate
) {
197 /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
198 * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
199 * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
201 /* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */
202 ASSERT(prIeSupportedRate
->ucLength
<= RATE_NUM
);
204 for (i
= 0; i
< prIeSupportedRate
->ucLength
; i
++) {
205 ucRate
= prIeSupportedRate
->aucSupportedRates
[i
] & RATE_MASK
;
207 /* Search all valid data rates */
208 for (j
= 0; j
< sizeof(aucDataRate
) / sizeof(UINT_8
); j
++) {
209 if (ucRate
== aucDataRate
[j
]) {
210 u2OperationalRateSet
|= BIT(j
);
212 if (prIeSupportedRate
->
213 aucSupportedRates
[i
] & RATE_BASIC_BIT
) {
214 u2BSSBasicRateSet
|= BIT(j
);
221 if ((j
== sizeof(aucDataRate
) / sizeof(UINT_8
)) &&
222 (prIeSupportedRate
->aucSupportedRates
[i
] & RATE_BASIC_BIT
)) {
223 fgIsUnknownBSSBasicRate
= TRUE
; /* A data rate not list in the aucDataRate[] */
229 if (prIeExtSupportedRate
) {
230 /* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */
232 for (i
= 0; i
< prIeExtSupportedRate
->ucLength
; i
++) {
233 ucRate
= prIeExtSupportedRate
->aucExtSupportedRates
[i
] & RATE_MASK
;
235 /* Search all valid data rates */
236 for (j
= 0; j
< sizeof(aucDataRate
) / sizeof(UINT_8
); j
++) {
237 if (ucRate
== aucDataRate
[j
]) {
238 u2OperationalRateSet
|= BIT(j
);
240 if (prIeExtSupportedRate
->
241 aucExtSupportedRates
[i
] & RATE_BASIC_BIT
) {
242 u2BSSBasicRateSet
|= BIT(j
);
249 if ((j
== sizeof(aucDataRate
) / sizeof(UINT_8
)) &&
250 (prIeExtSupportedRate
->aucExtSupportedRates
[i
] & RATE_BASIC_BIT
)) {
251 fgIsUnknownBSSBasicRate
= TRUE
; /* A data rate not list in the aucDataRate[] */
256 *pu2OperationalRateSet
= u2OperationalRateSet
;
257 *pu2BSSBasicRateSet
= u2BSSBasicRateSet
;
258 *pfgIsUnknownBSSBasicRate
= fgIsUnknownBSSBasicRate
;
262 } /* end of rateGetRateSetFromIEs() */
265 /*----------------------------------------------------------------------------*/
267 * @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code
268 * Format for used in (Ext)Supportec Rate IE.
270 * @param[in] u2OperationalRateSet Operational Rate Set
271 * @param[in] u2BSSBasicRateSet Basic Rate Set
272 * @param[out] pucDataRates Pointer to the Data Rate Buffer
273 * @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length
277 /*----------------------------------------------------------------------------*/
279 rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet
,
280 IN UINT_16 u2BSSBasicRateSet
,
281 OUT PUINT_8 pucDataRates
, OUT PUINT_8 pucDataRatesLen
)
286 ASSERT(pucDataRates
);
287 ASSERT(pucDataRatesLen
);
289 ASSERT(u2BSSBasicRateSet
== (u2OperationalRateSet
& u2BSSBasicRateSet
));
291 for (i
= RATE_1M_INDEX
, j
= 0; i
< RATE_NUM
; i
++) {
292 if (u2OperationalRateSet
& BIT(i
)) {
294 *(pucDataRates
+ j
) = aucDataRate
[i
];
296 if (u2BSSBasicRateSet
& BIT(i
)) {
297 *(pucDataRates
+ j
) |= RATE_BASIC_BIT
;
304 *pucDataRatesLen
= (UINT_8
) j
;
308 } /* end of rateGetDataRatesFromRateSet() */
311 /*----------------------------------------------------------------------------*/
313 * \brief Get the highest rate from given Rate Set.
315 * \param[in] u2RateSet Rate Set
316 * \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index
318 * \retval TRUE Highest Rate Index was found
319 * \retval FALSE Highest Rate Index was not found
321 /*----------------------------------------------------------------------------*/
322 BOOLEAN
rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet
, OUT PUINT_8 pucHighestRateIndex
)
327 ASSERT(pucHighestRateIndex
);
329 for (i
= RATE_54M_INDEX
; i
>= RATE_1M_INDEX
; i
--) {
330 if (u2RateSet
& BIT(i
)) {
331 *pucHighestRateIndex
= (UINT_8
) i
;
338 } /* end of rateGetHighestRateIndexFromRateSet() */
341 /*----------------------------------------------------------------------------*/
343 * \brief Get the lowest rate from given Rate Set.
345 * \param[in] u2RateSet Rate Set
346 * \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index
348 * \retval TRUE Lowest Rate Index was found
349 * \retval FALSE Lowest Rate Index was not found
351 /*----------------------------------------------------------------------------*/
352 BOOLEAN
rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet
, OUT PUINT_8 pucLowestRateIndex
)
356 ASSERT(pucLowestRateIndex
);
358 for (i
= RATE_1M_INDEX
; i
<= RATE_54M_INDEX
; i
++) {
359 if (u2RateSet
& BIT(i
)) {
360 *pucLowestRateIndex
= (UINT_8
) i
;
367 } /* end of rateGetLowestRateIndexFromRateSet() */
370 #if 0 /* NOTE(Kevin): For reference */
371 /*----------------------------------------------------------------------------*/
373 * \brief Convert the given Data Rates to the Rate Set.
375 * \param[in] pucDataRates Pointer to the Data Rates
376 * \param[in] ucDataRatesLen Length of given Data Rates
377 * \param[out] pu2RateSet Pointer to the Rate Set
381 /*----------------------------------------------------------------------------*/
383 rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates
,
384 IN UINT_8 ucDataRatesLen
, OUT PUINT_16 pu2RateSet
)
386 UINT_16 u2RateSet
= 0;
391 ASSERT(pucDataRates
);
395 for (i
= 0; i
< ucDataRatesLen
; i
++) {
396 ucRate
= pucDataRates
[i
] & RATE_MASK
;
398 /* Search all valid data rates */
399 for (j
= 0; j
< sizeof(aucDataRate
) / sizeof(UINT_8
); j
++) {
400 if (ucRate
== aucDataRate
[j
]) {
408 *pu2RateSet
= u2RateSet
;
412 } /* end of rateGetRateSetFromDataRates() */
415 /*----------------------------------------------------------------------------*/
417 * \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding
418 * ACK/CTS(Respnose) TX Rates.
420 * \param[in] u2OperationalRateSet Operational Rate Set
421 * \param[in] u2BSSBasicRateSet Basic Rate Set
422 * \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer
426 /*----------------------------------------------------------------------------*/
428 rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet
,
429 IN UINT_16 u2BSSBasicRateSet
, IN OUT UINT_8 aucAckCtsRateIndex
[]
435 ASSERT(aucAckCtsRateIndex
);
436 ASSERT(u2BSSBasicRateSet
== (u2OperationalRateSet
& u2BSSBasicRateSet
));
438 /* Setup default ACK/CTS response rate */
439 kalMemCopy(aucAckCtsRateIndex
, (PVOID
) aucDefaultAckCtsRateIndex
,
440 sizeof(aucDefaultAckCtsRateIndex
));
443 for (i
= RATE_54M_INDEX
; i
>= RATE_1M_INDEX
; i
--) {
444 if (u2OperationalRateSet
& BIT(i
)) {
445 for (j
= i
; j
>= RATE_1M_INDEX
; j
--) {
446 if (u2BSSBasicRateSet
& BIT(j
)) {
447 if ((afgIsOFDMRate
[i
] && afgIsOFDMRate
[j
]) || (!afgIsOFDMRate
[i
] && !afgIsOFDMRate
[j
])) /* Reply ACK Frame at the same Modulation Scheme. */
448 aucAckCtsRateIndex
[i
] = (UINT_8
) j
;
453 /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has
455 * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL.
456 * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"].
457 * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M],
458 * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still
459 * use highest mandatory rate as default.
461 if (j
< RATE_1M_INDEX
) { /* The ACK/CTS rate was not found in BasicRateSet */
462 if (!(BIT(aucAckCtsRateIndex
[i
]) & u2OperationalRateSet
)) {
463 aucAckCtsRateIndex
[i
] = (UINT_8
) i
;
471 } /* end of rateSetAckCtsDataRatesFromRateSet() */
474 /*----------------------------------------------------------------------------*/
476 * \brief Get the proper initial rate from Rate Set according to given RCPI value
478 * \param[in] u2RateSet Rate Set
479 * \param[in] rRcpi RCPI value from AP or Peer STA
480 * \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index
482 * \retval TRUE Initial Rate Index was found
483 * \retval FALSE Initial Rate Index was not found
485 /*----------------------------------------------------------------------------*/
487 rateGetBestInitialRateIndex(IN UINT_16 u2RateSet
, IN RCPI rRcpi
, OUT PUINT_8 pucInitialRateIndex
)
489 UINT_16 u2InitRateSet
;
493 ASSERT(pucInitialRateIndex
);
495 DBGLOG(MGT
, TRACE
, ("rRcpi = %d\n", rRcpi
));
497 if (rRcpi
>= RCPI_100
) { /* Best Signal */
498 u2InitRateSet
= INITIAL_RATE_SET(RCPI_100
);
499 } else if (rRcpi
>= RCPI_80
) { /* Better Signal */
500 u2InitRateSet
= INITIAL_RATE_SET(RCPI_80
);
501 } else if (rRcpi
>= RCPI_60
) { /* Good Signal */
502 u2InitRateSet
= INITIAL_RATE_SET(RCPI_60
);
503 } else { /* Worse Signal */
504 /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index
505 * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in
506 * function - bssUpdateTxRateForControlFrame().
511 u2RateSet
&= u2InitRateSet
;
513 for (i
= RATE_54M_INDEX
; i
>= RATE_1M_INDEX
; i
--) {
514 if (u2RateSet
& BIT(i
)) {
515 *pucInitialRateIndex
= (UINT_8
) i
;
522 } /* end of rateGetBestInitialRateIndex() */