add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / mgmt / rate.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/mgmt/rate.c#1 $
3 */
4
5 /*! \file   "rate.c"
6     \brief  This file contains the transmission rate handling routines.
7
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.
11 */
12
13 /*******************************************************************************
14 * Copyright (c) 2007 MediaTek Inc.
15 *
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
19 * MediaTek Inc.
20 ********************************************************************************
21 */
22
23 /*******************************************************************************
24 * LEGAL DISCLAIMER
25 *
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.
39 *
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.
45 *
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
51 * (ICC).
52 ********************************************************************************
53 */
54
55 /*
56 ** $Log: rate.c $
57  *
58  * 03 18 2011 cp.wu
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
61  *
62  * 07 08 2010 cp.wu
63  * 
64  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
65  *
66  * 06 08 2010 cp.wu
67  * [WPD00003833][MT6620 and MT5931] Driver migration 
68  * add rate.c.
69  *
70  * 03 16 2010 kevin.huang
71  * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support 
72  * Add AdHoc Mode
73  *
74  * 12 18 2009 cm.chang
75  * [BORA00000018]Integrate WIFI part into BORA for the 1st time 
76  * .
77  *
78  * Nov 23 2009 mtk01461
79  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
80  * Update comments
81  *
82  * Nov 16 2009 mtk01461
83  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
84  * Fix DBGLOG
85  *
86  * Nov 5 2009 mtk01461
87  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
88  *
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
101 **  Add comments
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
108 */
109
110 /*******************************************************************************
111 *                         C O M P I L E R   F L A G S
112 ********************************************************************************
113 */
114
115 /*******************************************************************************
116 *                    E X T E R N A L   R E F E R E N C E S
117 ********************************************************************************
118 */
119 #include "precomp.h"
120
121 /*******************************************************************************
122 *                              C O N S T A N T S
123 ********************************************************************************
124 */
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 */
142 };
143
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 */
159 };
160
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 */
176 };
177
178 /*******************************************************************************
179 *                             D A T A   T Y P E S
180 ********************************************************************************
181 */
182
183 /*******************************************************************************
184 *                            P U B L I C   D A T A
185 ********************************************************************************
186 */
187
188 /*******************************************************************************
189 *                           P R I V A T E   D A T A
190 ********************************************************************************
191 */
192
193 /*******************************************************************************
194 *                                 M A C R O S
195 ********************************************************************************
196 */
197
198 /*******************************************************************************
199 *                   F U N C T I O N   D E C L A R A T I O N S
200 ********************************************************************************
201 */
202
203 /*******************************************************************************
204 *                              F U N C T I O N S
205 ********************************************************************************
206 */
207 /*----------------------------------------------------------------------------*/
208 /*!
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.
212 *
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
219 *
220 * \return (none)
221 */
222 /*----------------------------------------------------------------------------*/
223 VOID
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
230     )
231 {
232     UINT_16 u2OperationalRateSet = 0;
233     UINT_16 u2BSSBasicRateSet = 0;
234     BOOLEAN fgIsUnknownBSSBasicRate = FALSE;
235     UINT_8 ucRate;
236     UINT_32 i, j;
237
238
239     ASSERT(pu2OperationalRateSet);
240     ASSERT(pu2BSSBasicRateSet);
241     ASSERT(pfgIsUnknownBSSBasicRate);
242
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)"
247          */
248         //ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES);
249         ASSERT(prIeSupportedRate->ucLength <= RATE_NUM);
250
251         for (i = 0; i < prIeSupportedRate->ucLength; i++) {
252             ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK;
253
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);
258
259                     if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) {
260                         u2BSSBasicRateSet |= BIT(j);
261                     }
262
263                     break;
264                 }
265             }
266
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[] */
270             }
271         }
272     }
273
274
275     if (prIeExtSupportedRate) {
276         //ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES);
277
278         for (i = 0; i < prIeExtSupportedRate->ucLength; i++) {
279             ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK;
280
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);
285
286                     if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) {
287                         u2BSSBasicRateSet |= BIT(j);
288                     }
289
290                     break;
291                 }
292             }
293
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[] */
297             }
298         }
299     }
300
301     *pu2OperationalRateSet = u2OperationalRateSet;
302     *pu2BSSBasicRateSet = u2BSSBasicRateSet;
303     *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate;
304
305     return;
306
307 } /* end of rateGetRateSetFromIEs() */
308
309
310 /*----------------------------------------------------------------------------*/
311 /*!
312 * @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code
313 *        Format for used in (Ext)Supportec Rate IE.
314 *
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
319 *
320 * @return (none)
321 */
322 /*----------------------------------------------------------------------------*/
323 VOID
324 rateGetDataRatesFromRateSet (
325     IN UINT_16 u2OperationalRateSet,
326     IN UINT_16 u2BSSBasicRateSet,
327     OUT PUINT_8 pucDataRates,
328     OUT PUINT_8 pucDataRatesLen
329     )
330 {
331     UINT_32 i, j;
332
333
334     ASSERT(pucDataRates);
335     ASSERT(pucDataRatesLen);
336
337     ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
338
339     for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) {
340         if (u2OperationalRateSet & BIT(i)) {
341
342             *(pucDataRates + j) = aucDataRate[i];
343
344             if (u2BSSBasicRateSet & BIT(i)) {
345                 *(pucDataRates + j) |= RATE_BASIC_BIT;
346             }
347
348             j++;
349         }
350     }
351
352     *pucDataRatesLen = (UINT_8)j;
353
354     return;
355
356 } /* end of rateGetDataRatesFromRateSet() */
357
358
359 /*----------------------------------------------------------------------------*/
360 /*!
361 * \brief Get the highest rate from given Rate Set.
362 *
363 * \param[in] u2RateSet              Rate Set
364 * \param[out] pucHighestRateIndex   Pointer to buffer of the Highest Rate Index
365 *
366 * \retval TRUE  Highest Rate Index was found
367 * \retval FALSE Highest Rate Index was not found
368 */
369 /*----------------------------------------------------------------------------*/
370 BOOLEAN
371 rateGetHighestRateIndexFromRateSet (
372     IN UINT_16 u2RateSet,
373     OUT PUINT_8 pucHighestRateIndex
374     )
375 {
376     INT_32 i;
377
378
379     ASSERT(pucHighestRateIndex);
380
381     for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
382         if (u2RateSet & BIT(i)) {
383             *pucHighestRateIndex = (UINT_8)i;
384             return TRUE;
385         }
386     }
387
388     return FALSE;
389
390 } /* end of rateGetHighestRateIndexFromRateSet() */
391
392
393 /*----------------------------------------------------------------------------*/
394 /*!
395 * \brief Get the lowest rate from given Rate Set.
396 *
397 * \param[in] u2RateSet              Rate Set
398 * \param[out] pucLowestRateIndex    Pointer to buffer of the Lowest Rate Index
399 *
400 * \retval TRUE  Lowest Rate Index was found
401 * \retval FALSE Lowest Rate Index was not found
402 */
403 /*----------------------------------------------------------------------------*/
404 BOOLEAN
405 rateGetLowestRateIndexFromRateSet (
406     IN UINT_16 u2RateSet,
407     OUT PUINT_8 pucLowestRateIndex
408     )
409 {
410     UINT_32 i;
411
412     ASSERT(pucLowestRateIndex);
413
414     for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) {
415         if (u2RateSet & BIT(i)) {
416             *pucLowestRateIndex = (UINT_8)i;
417             return TRUE;
418         }
419     }
420
421     return FALSE;
422
423 } /* end of rateGetLowestRateIndexFromRateSet() */
424
425
426 #if 0 // NOTE(Kevin): For reference
427 /*----------------------------------------------------------------------------*/
428 /*!
429 * \brief Convert the given Data Rates to the Rate Set.
430 *
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
434 *
435 * \return (none)
436 */
437 /*----------------------------------------------------------------------------*/
438 VOID
439 rateGetRateSetFromDataRates (
440     IN PUINT_8 pucDataRates,
441     IN UINT_8 ucDataRatesLen,
442     OUT PUINT_16 pu2RateSet
443     )
444 {
445     UINT_16 u2RateSet = 0;
446     UINT_8 ucRate;
447     UINT_32 i, j;
448
449
450     ASSERT(pucDataRates);
451     ASSERT(pu2RateSet);
452
453     if (pucDataRates) {
454         for (i = 0; i < ucDataRatesLen; i++) {
455             ucRate = pucDataRates[i] & RATE_MASK;
456
457             /* Search all valid data rates */
458             for (j = 0; j < sizeof(aucDataRate)/sizeof(UINT_8); j++) {
459                 if (ucRate == aucDataRate[j]) {
460                     u2RateSet |= BIT(j);
461                     break;
462                 }
463             }
464         }
465     }
466
467     *pu2RateSet = u2RateSet;
468
469     return;
470
471 } /* end of rateGetRateSetFromDataRates() */
472
473
474 /*----------------------------------------------------------------------------*/
475 /*!
476 * \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding
477 *        ACK/CTS(Respnose) TX Rates.
478 *
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
482 *
483 * \return (none)
484 */
485 /*----------------------------------------------------------------------------*/
486 VOID
487 rateSetAckCtsDataRatesFromRateSet (
488     IN UINT_16 u2OperationalRateSet,
489     IN UINT_16 u2BSSBasicRateSet,
490     IN OUT UINT_8 aucAckCtsRateIndex[]
491     )
492 {
493     INT_32 i,j;
494
495
496     ASSERT(aucAckCtsRateIndex);
497     ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
498
499     /* Setup default ACK/CTS response rate */
500     kalMemCopy(aucAckCtsRateIndex, (PVOID)aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex));
501
502
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;
509                     break;
510                 }
511             }
512
513             /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has
514              * NULL BasicRateSet.
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.
520              */
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;
524                 }
525             }
526         }
527     }
528
529     return;
530
531 } /* end of rateSetAckCtsDataRatesFromRateSet() */
532
533
534 /*----------------------------------------------------------------------------*/
535 /*!
536 * \brief Get the proper initial rate from Rate Set according to given RCPI value
537 *
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
541 *
542 * \retval TRUE  Initial Rate Index was found
543 * \retval FALSE Initial Rate Index was not found
544 */
545 /*----------------------------------------------------------------------------*/
546 BOOLEAN
547 rateGetBestInitialRateIndex (
548     IN UINT_16 u2RateSet,
549     IN RCPI rRcpi,
550     OUT PUINT_8 pucInitialRateIndex
551     )
552 {
553     UINT_16 u2InitRateSet;
554     INT_32 i;
555
556
557     ASSERT(pucInitialRateIndex);
558
559     DBGLOG(MGT, TRACE, ("rRcpi = %d\n", rRcpi));
560
561     if (rRcpi >= RCPI_100) { /* Best Signal */
562         u2InitRateSet = INITIAL_RATE_SET(RCPI_100);
563     }
564     else if (rRcpi >= RCPI_80) { /* Better Signal */
565         u2InitRateSet = INITIAL_RATE_SET(RCPI_80);
566     }
567     else if (rRcpi >= RCPI_60) { /* Good Signal */
568         u2InitRateSet = INITIAL_RATE_SET(RCPI_60);
569     }
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().
574          */
575         return FALSE;
576     }
577
578     u2RateSet &= u2InitRateSet;
579
580     for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
581         if (u2RateSet & BIT(i)) {
582             *pucInitialRateIndex = (UINT_8)i;
583             return TRUE;
584         }
585     }
586
587     return FALSE;
588
589 } /* end of rateGetBestInitialRateIndex() */
590 #endif
591