c63fe7b7d64159802d76f687f6f50ddad5e2753b
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / combo_mt66xx / mt6628 / wlan / mgmt / rate.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/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
15 /*
16 ** $Log: rate.c $
17  *
18  * 07 08 2010 cp.wu
19  * 
20  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
21  *
22  * 06 08 2010 cp.wu
23  * [WPD00003833][MT6620 and MT5931] Driver migration 
24  * add rate.c.
25  *
26  * 03 16 2010 kevin.huang
27  * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support 
28  * Add AdHoc Mode
29  *
30  * 12 18 2009 cm.chang
31  * [BORA00000018]Integrate WIFI part into BORA for the 1st time 
32  * .
33  *
34  * Nov 23 2009 mtk01461
35  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
36  * Update comments
37  *
38  * Nov 16 2009 mtk01461
39  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
40  * Fix DBGLOG
41  *
42  * Nov 5 2009 mtk01461
43  * [BORA00000018] Integrate WIFI part into BORA for the 1st time
44  *
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
57 **  Add comments
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
64 */
65
66 /*******************************************************************************
67 *                         C O M P I L E R   F L A G S
68 ********************************************************************************
69 */
70
71 /*******************************************************************************
72 *                    E X T E R N A L   R E F E R E N C E S
73 ********************************************************************************
74 */
75 #include "precomp.h"
76
77 /*******************************************************************************
78 *                              C O N S T A N T S
79 ********************************************************************************
80 */
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 */
98 };
99
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 */
115 };
116
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 */
132 };
133
134 /*******************************************************************************
135 *                             D A T A   T Y P E S
136 ********************************************************************************
137 */
138
139 /*******************************************************************************
140 *                            P U B L I C   D A T A
141 ********************************************************************************
142 */
143
144 /*******************************************************************************
145 *                           P R I V A T E   D A T A
146 ********************************************************************************
147 */
148
149 /*******************************************************************************
150 *                                 M A C R O S
151 ********************************************************************************
152 */
153
154 /*******************************************************************************
155 *                   F U N C T I O N   D E C L A R A T I O N S
156 ********************************************************************************
157 */
158
159 /*******************************************************************************
160 *                              F U N C T I O N S
161 ********************************************************************************
162 */
163 /*----------------------------------------------------------------------------*/
164 /*!
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.
168 *
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
175 *
176 * \return (none)
177 */
178 /*----------------------------------------------------------------------------*/
179 VOID
180 rateGetRateSetFromIEs (
181     IN P_IE_SUPPORTED_RATE_T prIeSupportedRate,
182     IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate,
183     OUT PUINT_16 pu2OperationalRateSet,
184     OUT PUINT_16 pu2BSSBasicRateSet,
185     OUT PBOOLEAN pfgIsUnknownBSSBasicRate
186     )
187 {
188     UINT_16 u2OperationalRateSet = 0;
189     UINT_16 u2BSSBasicRateSet = 0;
190     BOOLEAN fgIsUnknownBSSBasicRate = FALSE;
191     UINT_8 ucRate;
192     UINT_32 i, j;
193
194
195     ASSERT(pu2OperationalRateSet);
196     ASSERT(pu2BSSBasicRateSet);
197     ASSERT(pfgIsUnknownBSSBasicRate);
198
199     if (prIeSupportedRate) {
200         /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
201          * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
202          * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
203          */
204         //ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES);
205         ASSERT(prIeSupportedRate->ucLength <= RATE_NUM);
206
207         for (i = 0; i < prIeSupportedRate->ucLength; i++) {
208             ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK;
209
210             /* Search all valid data rates */
211             for (j = 0; j < sizeof(aucDataRate)/sizeof(UINT_8); j++) {
212                 if (ucRate == aucDataRate[j]) {
213                     u2OperationalRateSet |= BIT(j);
214
215                     if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT) {
216                         u2BSSBasicRateSet |= BIT(j);
217                     }
218
219                     break;
220                 }
221             }
222
223             if ((j == sizeof(aucDataRate)/sizeof(UINT_8)) &&
224                 (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) {
225                 fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */
226             }
227         }
228     }
229
230
231     if (prIeExtSupportedRate) {
232         //ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES);
233
234         for (i = 0; i < prIeExtSupportedRate->ucLength; i++) {
235             ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK;
236
237             /* Search all valid data rates */
238             for (j = 0; j < sizeof(aucDataRate)/sizeof(UINT_8); j++) {
239                 if (ucRate == aucDataRate[j]) {
240                     u2OperationalRateSet |= BIT(j);
241
242                     if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT) {
243                         u2BSSBasicRateSet |= BIT(j);
244                     }
245
246                     break;
247                 }
248             }
249
250             if ((j == sizeof(aucDataRate)/sizeof(UINT_8)) &&
251                 (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) {
252                 fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */
253             }
254         }
255     }
256
257     *pu2OperationalRateSet = u2OperationalRateSet;
258     *pu2BSSBasicRateSet = u2BSSBasicRateSet;
259     *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate;
260
261     return;
262
263 } /* end of rateGetRateSetFromIEs() */
264
265
266 /*----------------------------------------------------------------------------*/
267 /*!
268 * @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code
269 *        Format for used in (Ext)Supportec Rate IE.
270 *
271 * @param[in] u2OperationalRateSet   Operational Rate Set
272 * @param[in] u2BSSBasicRateSet      Basic Rate Set
273 * @param[out] pucDataRates          Pointer to the Data Rate Buffer
274 * @param[out] pucDataRatesLen       Pointer to the Data Rate Buffer Length
275 *
276 * @return (none)
277 */
278 /*----------------------------------------------------------------------------*/
279 VOID
280 rateGetDataRatesFromRateSet (
281     IN UINT_16 u2OperationalRateSet,
282     IN UINT_16 u2BSSBasicRateSet,
283     OUT PUINT_8 pucDataRates,
284     OUT PUINT_8 pucDataRatesLen
285     )
286 {
287     UINT_32 i, j;
288
289
290     ASSERT(pucDataRates);
291     ASSERT(pucDataRatesLen);
292
293     ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
294
295     for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) {
296         if (u2OperationalRateSet & BIT(i)) {
297
298             *(pucDataRates + j) = aucDataRate[i];
299
300             if (u2BSSBasicRateSet & BIT(i)) {
301                 *(pucDataRates + j) |= RATE_BASIC_BIT;
302             }
303
304             j++;
305         }
306     }
307
308     *pucDataRatesLen = (UINT_8)j;
309
310     return;
311
312 } /* end of rateGetDataRatesFromRateSet() */
313
314
315 /*----------------------------------------------------------------------------*/
316 /*!
317 * \brief Get the highest rate from given Rate Set.
318 *
319 * \param[in] u2RateSet              Rate Set
320 * \param[out] pucHighestRateIndex   Pointer to buffer of the Highest Rate Index
321 *
322 * \retval TRUE  Highest Rate Index was found
323 * \retval FALSE Highest Rate Index was not found
324 */
325 /*----------------------------------------------------------------------------*/
326 BOOLEAN
327 rateGetHighestRateIndexFromRateSet (
328     IN UINT_16 u2RateSet,
329     OUT PUINT_8 pucHighestRateIndex
330     )
331 {
332     INT_32 i;
333
334
335     ASSERT(pucHighestRateIndex);
336
337     for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
338         if (u2RateSet & BIT(i)) {
339             *pucHighestRateIndex = (UINT_8)i;
340             return TRUE;
341         }
342     }
343
344     return FALSE;
345
346 } /* end of rateGetHighestRateIndexFromRateSet() */
347
348
349 /*----------------------------------------------------------------------------*/
350 /*!
351 * \brief Get the lowest rate from given Rate Set.
352 *
353 * \param[in] u2RateSet              Rate Set
354 * \param[out] pucLowestRateIndex    Pointer to buffer of the Lowest Rate Index
355 *
356 * \retval TRUE  Lowest Rate Index was found
357 * \retval FALSE Lowest Rate Index was not found
358 */
359 /*----------------------------------------------------------------------------*/
360 BOOLEAN
361 rateGetLowestRateIndexFromRateSet (
362     IN UINT_16 u2RateSet,
363     OUT PUINT_8 pucLowestRateIndex
364     )
365 {
366     UINT_32 i;
367
368     ASSERT(pucLowestRateIndex);
369
370     for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) {
371         if (u2RateSet & BIT(i)) {
372             *pucLowestRateIndex = (UINT_8)i;
373             return TRUE;
374         }
375     }
376
377     return FALSE;
378
379 } /* end of rateGetLowestRateIndexFromRateSet() */
380
381
382 #if 0 // NOTE(Kevin): For reference
383 /*----------------------------------------------------------------------------*/
384 /*!
385 * \brief Convert the given Data Rates to the Rate Set.
386 *
387 * \param[in] pucDataRates       Pointer to the Data Rates
388 * \param[in] ucDataRatesLen     Length of given Data Rates
389 * \param[out] pu2RateSet        Pointer to the Rate Set
390 *
391 * \return (none)
392 */
393 /*----------------------------------------------------------------------------*/
394 VOID
395 rateGetRateSetFromDataRates (
396     IN PUINT_8 pucDataRates,
397     IN UINT_8 ucDataRatesLen,
398     OUT PUINT_16 pu2RateSet
399     )
400 {
401     UINT_16 u2RateSet = 0;
402     UINT_8 ucRate;
403     UINT_32 i, j;
404
405
406     ASSERT(pucDataRates);
407     ASSERT(pu2RateSet);
408
409     if (pucDataRates) {
410         for (i = 0; i < ucDataRatesLen; i++) {
411             ucRate = pucDataRates[i] & RATE_MASK;
412
413             /* Search all valid data rates */
414             for (j = 0; j < sizeof(aucDataRate)/sizeof(UINT_8); j++) {
415                 if (ucRate == aucDataRate[j]) {
416                     u2RateSet |= BIT(j);
417                     break;
418                 }
419             }
420         }
421     }
422
423     *pu2RateSet = u2RateSet;
424
425     return;
426
427 } /* end of rateGetRateSetFromDataRates() */
428
429
430 /*----------------------------------------------------------------------------*/
431 /*!
432 * \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding
433 *        ACK/CTS(Respnose) TX Rates.
434 *
435 * \param[in] u2OperationalRateSet   Operational Rate Set
436 * \param[in] u2BSSBasicRateSet      Basic Rate Set
437 * \param[out] aucAckCtsRateIndex    Pointer to the Ack/Cts Data Rate Buffer
438 *
439 * \return (none)
440 */
441 /*----------------------------------------------------------------------------*/
442 VOID
443 rateSetAckCtsDataRatesFromRateSet (
444     IN UINT_16 u2OperationalRateSet,
445     IN UINT_16 u2BSSBasicRateSet,
446     IN OUT UINT_8 aucAckCtsRateIndex[]
447     )
448 {
449     INT_32 i,j;
450
451
452     ASSERT(aucAckCtsRateIndex);
453     ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
454
455     /* Setup default ACK/CTS response rate */
456     kalMemCopy(aucAckCtsRateIndex, (PVOID)aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex));
457
458
459     for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
460         if (u2OperationalRateSet & BIT(i)) {
461             for (j = i; j >= RATE_1M_INDEX; j--) {
462                 if (u2BSSBasicRateSet & BIT(j)) {
463                     if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) || (!afgIsOFDMRate[i] && !afgIsOFDMRate[j])) // Reply ACK Frame at the same Modulation Scheme.
464                         aucAckCtsRateIndex[i] = (UINT_8)j;
465                     break;
466                 }
467             }
468
469             /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has
470              * NULL BasicRateSet.
471              * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL.
472              * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"].
473              * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M],
474              * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still
475              * use highest mandatory rate as default.
476              */
477             if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */
478                 if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet)) {
479                     aucAckCtsRateIndex[i] = (UINT_8)i;
480                 }
481             }
482         }
483     }
484
485     return;
486
487 } /* end of rateSetAckCtsDataRatesFromRateSet() */
488
489
490 /*----------------------------------------------------------------------------*/
491 /*!
492 * \brief Get the proper initial rate from Rate Set according to given RCPI value
493 *
494 * \param[in] u2RateSet              Rate Set
495 * \param[in] rRcpi                  RCPI value from AP or Peer STA
496 * \param[out] pucInitialRateIndex   Pointer to buffer of the initial Rate Index
497 *
498 * \retval TRUE  Initial Rate Index was found
499 * \retval FALSE Initial Rate Index was not found
500 */
501 /*----------------------------------------------------------------------------*/
502 BOOLEAN
503 rateGetBestInitialRateIndex (
504     IN UINT_16 u2RateSet,
505     IN RCPI rRcpi,
506     OUT PUINT_8 pucInitialRateIndex
507     )
508 {
509     UINT_16 u2InitRateSet;
510     INT_32 i;
511
512
513     ASSERT(pucInitialRateIndex);
514
515     DBGLOG(MGT, TRACE, ("rRcpi = %d\n", rRcpi));
516
517     if (rRcpi >= RCPI_100) { /* Best Signal */
518         u2InitRateSet = INITIAL_RATE_SET(RCPI_100);
519     }
520     else if (rRcpi >= RCPI_80) { /* Better Signal */
521         u2InitRateSet = INITIAL_RATE_SET(RCPI_80);
522     }
523     else if (rRcpi >= RCPI_60) { /* Good Signal */
524         u2InitRateSet = INITIAL_RATE_SET(RCPI_60);
525     }
526     else { /* Worse Signal */
527         /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index
528          * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in
529          * function - bssUpdateTxRateForControlFrame().
530          */
531         return FALSE;
532     }
533
534     u2RateSet &= u2InitRateSet;
535
536     for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
537         if (u2RateSet & BIT(i)) {
538             *pucInitialRateIndex = (UINT_8)i;
539             return TRUE;
540         }
541     }
542
543     return FALSE;
544
545 } /* end of rateGetBestInitialRateIndex() */
546 #endif
547