rate.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /*
  2. ** Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_3/mgmt/rate.c#1
  3. */
  4. /*! \file "rate.c"
  5. \brief This file contains the transmission rate handling routines.
  6. This file contains the transmission rate handling routines for setting up
  7. ACK/CTS Rate, Highest Tx Rate, Lowest Tx Rate, Initial Tx Rate and do
  8. conversion between Rate Set and Data Rates.
  9. */
  10. /*
  11. ** Log: rate.c
  12. *
  13. * 07 08 2010 cp.wu
  14. *
  15. * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
  16. *
  17. * 06 08 2010 cp.wu
  18. * [WPD00003833][MT6620 and MT5931] Driver migration
  19. * add rate.c.
  20. *
  21. * 03 16 2010 kevin.huang
  22. * [BORA00000663][WIFISYS][New Feature] AdHoc Mode Support
  23. * Add AdHoc Mode
  24. *
  25. * 12 18 2009 cm.chang
  26. * [BORA00000018]Integrate WIFI part into BORA for the 1st time
  27. * .
  28. *
  29. * Nov 23 2009 mtk01461
  30. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  31. * Update comments
  32. *
  33. * Nov 16 2009 mtk01461
  34. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  35. * Fix DBGLOG
  36. *
  37. * Nov 5 2009 mtk01461
  38. * [BORA00000018] Integrate WIFI part into BORA for the 1st time
  39. *
  40. ** \main\maintrunk.MT5921\12 2008-12-19 17:19:32 GMT mtk01461
  41. ** Fix the problem that do not ASSERT the length of Supported Rate IE == 8
  42. ** \main\maintrunk.MT5921\11 2008-12-01 18:17:42 GMT mtk01088
  43. ** fixed the lint "possible using null pointer" warning
  44. ** \main\maintrunk.MT5921\10 2008-08-20 00:16:36 GMT mtk01461
  45. ** Update for Driver Review
  46. ** \main\maintrunk.MT5921\9 2008-04-13 21:17:13 GMT mtk01461
  47. ** Revise GEN Link Speed OID
  48. ** \main\maintrunk.MT5921\8 2008-03-28 10:40:13 GMT mtk01461
  49. ** Add rateGetRateSetFromDataRates() for set desired rate OID
  50. ** \main\maintrunk.MT5921\7 2008-03-26 09:16:20 GMT mtk01461
  51. ** Add adopt operational rate as ACK rate if BasicRateSet was not found
  52. ** Add comments
  53. ** \main\maintrunk.MT5921\6 2008-02-21 15:01:39 GMT mtk01461
  54. ** Add initial rate according rx signal quality support
  55. ** \main\maintrunk.MT5921\5 2008-01-07 15:06:44 GMT mtk01461
  56. ** Fix typo of rate adaptation of CtrlResp Frame
  57. ** \main\maintrunk.MT5921\4 2007-10-25 18:05:12 GMT mtk01461
  58. ** Add VOIP SCAN Support & Refine Roaming
  59. */
  60. /*******************************************************************************
  61. * C O M P I L E R F L A G S
  62. ********************************************************************************
  63. */
  64. /*******************************************************************************
  65. * E X T E R N A L R E F E R E N C E S
  66. ********************************************************************************
  67. */
  68. #include "precomp.h"
  69. /*******************************************************************************
  70. * C O N S T A N T S
  71. ********************************************************************************
  72. */
  73. /* The list of valid data rates. */
  74. const UINT_8 aucDataRate[] = {
  75. RATE_1M, /* RATE_1M_INDEX = 0 */
  76. RATE_2M, /* RATE_2M_INDEX */
  77. RATE_5_5M, /* RATE_5_5M_INDEX */
  78. RATE_11M, /* RATE_11M_INDEX */
  79. RATE_22M, /* RATE_22M_INDEX */
  80. RATE_33M, /* RATE_33M_INDEX */
  81. RATE_6M, /* RATE_6M_INDEX */
  82. RATE_9M, /* RATE_9M_INDEX */
  83. RATE_12M, /* RATE_12M_INDEX */
  84. RATE_18M, /* RATE_18M_INDEX */
  85. RATE_24M, /* RATE_24M_INDEX */
  86. RATE_36M, /* RATE_36M_INDEX */
  87. RATE_48M, /* RATE_48M_INDEX */
  88. RATE_54M, /* RATE_54M_INDEX */
  89. RATE_HT_PHY /* RATE_HT_PHY_INDEX */
  90. };
  91. static const UINT_8 aucDefaultAckCtsRateIndex[RATE_NUM] = {
  92. RATE_1M_INDEX, /* RATE_1M_INDEX = 0 */
  93. RATE_2M_INDEX, /* RATE_2M_INDEX */
  94. RATE_5_5M_INDEX, /* RATE_5_5M_INDEX */
  95. RATE_11M_INDEX, /* RATE_11M_INDEX */
  96. RATE_1M_INDEX, /* RATE_22M_INDEX - Not supported */
  97. RATE_1M_INDEX, /* RATE_33M_INDEX - Not supported */
  98. RATE_6M_INDEX, /* RATE_6M_INDEX */
  99. RATE_6M_INDEX, /* RATE_9M_INDEX */
  100. RATE_12M_INDEX, /* RATE_12M_INDEX */
  101. RATE_12M_INDEX, /* RATE_18M_INDEX */
  102. RATE_24M_INDEX, /* RATE_24M_INDEX */
  103. RATE_24M_INDEX, /* RATE_36M_INDEX */
  104. RATE_24M_INDEX, /* RATE_48M_INDEX */
  105. RATE_24M_INDEX /* RATE_54M_INDEX */
  106. };
  107. const BOOLEAN afgIsOFDMRate[RATE_NUM] = {
  108. FALSE, /* RATE_1M_INDEX = 0 */
  109. FALSE, /* RATE_2M_INDEX */
  110. FALSE, /* RATE_5_5M_INDEX */
  111. FALSE, /* RATE_11M_INDEX */
  112. FALSE, /* RATE_22M_INDEX - Not supported */
  113. FALSE, /* RATE_33M_INDEX - Not supported */
  114. TRUE, /* RATE_6M_INDEX */
  115. TRUE, /* RATE_9M_INDEX */
  116. TRUE, /* RATE_12M_INDEX */
  117. TRUE, /* RATE_18M_INDEX */
  118. TRUE, /* RATE_24M_INDEX */
  119. TRUE, /* RATE_36M_INDEX */
  120. TRUE, /* RATE_48M_INDEX */
  121. TRUE /* RATE_54M_INDEX */
  122. };
  123. /*******************************************************************************
  124. * D A T A T Y P E S
  125. ********************************************************************************
  126. */
  127. /*******************************************************************************
  128. * P U B L I C D A T A
  129. ********************************************************************************
  130. */
  131. /*******************************************************************************
  132. * P R I V A T E D A T A
  133. ********************************************************************************
  134. */
  135. /*******************************************************************************
  136. * M A C R O S
  137. ********************************************************************************
  138. */
  139. /*******************************************************************************
  140. * F U N C T I O N D E C L A R A T I O N S
  141. ********************************************************************************
  142. */
  143. /*******************************************************************************
  144. * F U N C T I O N S
  145. ********************************************************************************
  146. */
  147. /*----------------------------------------------------------------------------*/
  148. /*!
  149. * @brief Convert the given Supported Rate & Extended Supported Rate IE to the
  150. * Operational Rate Set and Basic Rate Set, and also check if any Basic
  151. * Rate Code is unknown by driver.
  152. *
  153. * @param[in] prIeSupportedRate Pointer to the Supported Rate IE
  154. * @param[in] prIeExtSupportedRate Pointer to the Ext Supported Rate IE
  155. * @param[out] pu2OperationalRateSet Pointer to the Operational Rate Set
  156. * @param[out] pu2BSSBasicRateSet Pointer to the Basic Rate Set
  157. * @param[out] pfgIsUnknownBSSBasicRate Pointer to a Flag to indicate that Basic
  158. * Rate Set has unknown Rate Code
  159. *
  160. * \return (none)
  161. */
  162. /*----------------------------------------------------------------------------*/
  163. VOID
  164. rateGetRateSetFromIEs(IN P_IE_SUPPORTED_RATE_T prIeSupportedRate,
  165. IN P_IE_EXT_SUPPORTED_RATE_T prIeExtSupportedRate,
  166. OUT PUINT_16 pu2OperationalRateSet,
  167. OUT PUINT_16 pu2BSSBasicRateSet, OUT PBOOLEAN pfgIsUnknownBSSBasicRate)
  168. {
  169. UINT_16 u2OperationalRateSet = 0;
  170. UINT_16 u2BSSBasicRateSet = 0;
  171. BOOLEAN fgIsUnknownBSSBasicRate = FALSE;
  172. UINT_8 ucRate;
  173. UINT_32 i, j;
  174. ASSERT(pu2OperationalRateSet);
  175. ASSERT(pu2BSSBasicRateSet);
  176. ASSERT(pfgIsUnknownBSSBasicRate);
  177. if (prIeSupportedRate) {
  178. /* NOTE(Kevin): Buffalo WHR-G54S's supported rate set IE exceed 8.
  179. * IE_LEN(pucIE) == 12, "1(B), 2(B), 5.5(B), 6(B), 9(B), 11(B),
  180. * 12(B), 18(B), 24(B), 36(B), 48(B), 54(B)"
  181. */
  182. /* ASSERT(prIeSupportedRate->ucLength <= ELEM_MAX_LEN_SUP_RATES); */
  183. ASSERT(prIeSupportedRate->ucLength <= RATE_NUM);
  184. for (i = 0; i < prIeSupportedRate->ucLength; i++) {
  185. ucRate = prIeSupportedRate->aucSupportedRates[i] & RATE_MASK;
  186. /* Search all valid data rates */
  187. for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) {
  188. if (ucRate == aucDataRate[j]) {
  189. u2OperationalRateSet |= BIT(j);
  190. if (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)
  191. u2BSSBasicRateSet |= BIT(j);
  192. break;
  193. }
  194. }
  195. if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) &&
  196. (prIeSupportedRate->aucSupportedRates[i] & RATE_BASIC_BIT)) {
  197. fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */
  198. }
  199. }
  200. }
  201. if (prIeExtSupportedRate) {
  202. /* ASSERT(prIeExtSupportedRate->ucLength <= ELEM_MAX_LEN_EXTENDED_SUP_RATES); */
  203. for (i = 0; i < prIeExtSupportedRate->ucLength; i++) {
  204. ucRate = prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_MASK;
  205. /* Search all valid data rates */
  206. for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) {
  207. if (ucRate == aucDataRate[j]) {
  208. u2OperationalRateSet |= BIT(j);
  209. if (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)
  210. u2BSSBasicRateSet |= BIT(j);
  211. break;
  212. }
  213. }
  214. if ((j == sizeof(aucDataRate) / sizeof(UINT_8)) &&
  215. (prIeExtSupportedRate->aucExtSupportedRates[i] & RATE_BASIC_BIT)) {
  216. fgIsUnknownBSSBasicRate = TRUE; /* A data rate not list in the aucDataRate[] */
  217. }
  218. }
  219. }
  220. *pu2OperationalRateSet = u2OperationalRateSet;
  221. *pu2BSSBasicRateSet = u2BSSBasicRateSet;
  222. *pfgIsUnknownBSSBasicRate = fgIsUnknownBSSBasicRate;
  223. return;
  224. } /* end of rateGetRateSetFromIEs() */
  225. /*----------------------------------------------------------------------------*/
  226. /*!
  227. * @brief Convert the given Operational Rate Set & Basic Rate Set to the Rate Code
  228. * Format for used in (Ext)Supportec Rate IE.
  229. *
  230. * @param[in] u2OperationalRateSet Operational Rate Set
  231. * @param[in] u2BSSBasicRateSet Basic Rate Set
  232. * @param[out] pucDataRates Pointer to the Data Rate Buffer
  233. * @param[out] pucDataRatesLen Pointer to the Data Rate Buffer Length
  234. *
  235. * @return (none)
  236. */
  237. /*----------------------------------------------------------------------------*/
  238. VOID
  239. rateGetDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet,
  240. IN UINT_16 u2BSSBasicRateSet, OUT PUINT_8 pucDataRates, OUT PUINT_8 pucDataRatesLen)
  241. {
  242. UINT_32 i, j;
  243. ASSERT(pucDataRates);
  244. ASSERT(pucDataRatesLen);
  245. ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
  246. for (i = RATE_1M_INDEX, j = 0; i < RATE_NUM; i++) {
  247. if (u2OperationalRateSet & BIT(i)) {
  248. *(pucDataRates + j) = aucDataRate[i];
  249. if (u2BSSBasicRateSet & BIT(i))
  250. *(pucDataRates + j) |= RATE_BASIC_BIT;
  251. j++;
  252. }
  253. }
  254. *pucDataRatesLen = (UINT_8) j;
  255. return;
  256. } /* end of rateGetDataRatesFromRateSet() */
  257. /*----------------------------------------------------------------------------*/
  258. /*!
  259. * \brief Get the highest rate from given Rate Set.
  260. *
  261. * \param[in] u2RateSet Rate Set
  262. * \param[out] pucHighestRateIndex Pointer to buffer of the Highest Rate Index
  263. *
  264. * \retval TRUE Highest Rate Index was found
  265. * \retval FALSE Highest Rate Index was not found
  266. */
  267. /*----------------------------------------------------------------------------*/
  268. BOOLEAN rateGetHighestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucHighestRateIndex)
  269. {
  270. INT_32 i;
  271. ASSERT(pucHighestRateIndex);
  272. for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
  273. if (u2RateSet & BIT(i)) {
  274. *pucHighestRateIndex = (UINT_8) i;
  275. return TRUE;
  276. }
  277. }
  278. return FALSE;
  279. } /* end of rateGetHighestRateIndexFromRateSet() */
  280. /*----------------------------------------------------------------------------*/
  281. /*!
  282. * \brief Get the lowest rate from given Rate Set.
  283. *
  284. * \param[in] u2RateSet Rate Set
  285. * \param[out] pucLowestRateIndex Pointer to buffer of the Lowest Rate Index
  286. *
  287. * \retval TRUE Lowest Rate Index was found
  288. * \retval FALSE Lowest Rate Index was not found
  289. */
  290. /*----------------------------------------------------------------------------*/
  291. BOOLEAN rateGetLowestRateIndexFromRateSet(IN UINT_16 u2RateSet, OUT PUINT_8 pucLowestRateIndex)
  292. {
  293. UINT_32 i;
  294. ASSERT(pucLowestRateIndex);
  295. for (i = RATE_1M_INDEX; i <= RATE_54M_INDEX; i++) {
  296. if (u2RateSet & BIT(i)) {
  297. *pucLowestRateIndex = (UINT_8) i;
  298. return TRUE;
  299. }
  300. }
  301. return FALSE;
  302. } /* end of rateGetLowestRateIndexFromRateSet() */
  303. #if 0 /* NOTE(Kevin): For reference */
  304. /*----------------------------------------------------------------------------*/
  305. /*!
  306. * \brief Convert the given Data Rates to the Rate Set.
  307. *
  308. * \param[in] pucDataRates Pointer to the Data Rates
  309. * \param[in] ucDataRatesLen Length of given Data Rates
  310. * \param[out] pu2RateSet Pointer to the Rate Set
  311. *
  312. * \return (none)
  313. */
  314. /*----------------------------------------------------------------------------*/
  315. VOID rateGetRateSetFromDataRates(IN PUINT_8 pucDataRates, IN UINT_8 ucDataRatesLen, OUT PUINT_16 pu2RateSet)
  316. {
  317. UINT_16 u2RateSet = 0;
  318. UINT_8 ucRate;
  319. UINT_32 i, j;
  320. ASSERT(pucDataRates);
  321. ASSERT(pu2RateSet);
  322. if (pucDataRates) {
  323. for (i = 0; i < ucDataRatesLen; i++) {
  324. ucRate = pucDataRates[i] & RATE_MASK;
  325. /* Search all valid data rates */
  326. for (j = 0; j < sizeof(aucDataRate) / sizeof(UINT_8); j++) {
  327. if (ucRate == aucDataRate[j]) {
  328. u2RateSet |= BIT(j);
  329. break;
  330. }
  331. }
  332. }
  333. }
  334. *pu2RateSet = u2RateSet;
  335. return;
  336. } /* end of rateGetRateSetFromDataRates() */
  337. /*----------------------------------------------------------------------------*/
  338. /*!
  339. * \brief Parse the Operational Rate Set and Basic Rate Set to get the corresponding
  340. * ACK/CTS(Respnose) TX Rates.
  341. *
  342. * \param[in] u2OperationalRateSet Operational Rate Set
  343. * \param[in] u2BSSBasicRateSet Basic Rate Set
  344. * \param[out] aucAckCtsRateIndex Pointer to the Ack/Cts Data Rate Buffer
  345. *
  346. * \return (none)
  347. */
  348. /*----------------------------------------------------------------------------*/
  349. VOID
  350. rateSetAckCtsDataRatesFromRateSet(IN UINT_16 u2OperationalRateSet,
  351. IN UINT_16 u2BSSBasicRateSet, IN OUT UINT_8 aucAckCtsRateIndex[])
  352. {
  353. INT_32 i, j;
  354. ASSERT(aucAckCtsRateIndex);
  355. ASSERT(u2BSSBasicRateSet == (u2OperationalRateSet & u2BSSBasicRateSet));
  356. /* Setup default ACK/CTS response rate */
  357. kalMemCopy(aucAckCtsRateIndex, (PVOID) aucDefaultAckCtsRateIndex, sizeof(aucDefaultAckCtsRateIndex));
  358. for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
  359. if (u2OperationalRateSet & BIT(i)) {
  360. for (j = i; j >= RATE_1M_INDEX; j--) {
  361. if (u2BSSBasicRateSet & BIT(j)) {
  362. /* Reply ACK Frame at the same Modulation Scheme. */
  363. if ((afgIsOFDMRate[i] && afgIsOFDMRate[j]) ||
  364. (!afgIsOFDMRate[i] && !afgIsOFDMRate[j]))
  365. aucAckCtsRateIndex[i] = (UINT_8) j;
  366. break;
  367. }
  368. }
  369. /* NOTE(Kevin 2008/03/25): Following code is used for those AP which has
  370. * NULL BasicRateSet.
  371. * e.g. If input Operational Rate Set = [18M 12M 9M], Basic Rate Set = NULL.
  372. * Originally we'll get Ack Rate for [18M 12M 9M] is [12M 12M "6M"].
  373. * Now we'll get Ack Rate for [18M 12M 9M] is [12M 12M 9M],
  374. * The Ack Rate for Tx Rates which are not list in Operational Rate Set is still
  375. * use highest mandatory rate as default.
  376. */
  377. if (j < RATE_1M_INDEX) { /* The ACK/CTS rate was not found in BasicRateSet */
  378. if (!(BIT(aucAckCtsRateIndex[i]) & u2OperationalRateSet))
  379. aucAckCtsRateIndex[i] = (UINT_8) i;
  380. }
  381. }
  382. }
  383. return;
  384. } /* end of rateSetAckCtsDataRatesFromRateSet() */
  385. /*----------------------------------------------------------------------------*/
  386. /*!
  387. * \brief Get the proper initial rate from Rate Set according to given RCPI value
  388. *
  389. * \param[in] u2RateSet Rate Set
  390. * \param[in] rRcpi RCPI value from AP or Peer STA
  391. * \param[out] pucInitialRateIndex Pointer to buffer of the initial Rate Index
  392. *
  393. * \retval TRUE Initial Rate Index was found
  394. * \retval FALSE Initial Rate Index was not found
  395. */
  396. /*----------------------------------------------------------------------------*/
  397. BOOLEAN rateGetBestInitialRateIndex(IN UINT_16 u2RateSet, IN RCPI rRcpi, OUT PUINT_8 pucInitialRateIndex)
  398. {
  399. UINT_16 u2InitRateSet;
  400. INT_32 i;
  401. ASSERT(pucInitialRateIndex);
  402. DBGLOG(MGT, TRACE, "rRcpi = %d\n", rRcpi);
  403. if (rRcpi >= RCPI_100) { /* Best Signal */
  404. u2InitRateSet = INITIAL_RATE_SET(RCPI_100);
  405. } else if (rRcpi >= RCPI_80) { /* Better Signal */
  406. u2InitRateSet = INITIAL_RATE_SET(RCPI_80);
  407. } else if (rRcpi >= RCPI_60) { /* Good Signal */
  408. u2InitRateSet = INITIAL_RATE_SET(RCPI_60);
  409. } else { /* Worse Signal */
  410. /* NOTE(Kevin): If return FALSE, we should assign the BSS Basic Rate Index
  411. * (prBssInfo->ucBasicRateIndex) to the initial rate. It was determined in
  412. * function - bssUpdateTxRateForControlFrame().
  413. */
  414. return FALSE;
  415. }
  416. u2RateSet &= u2InitRateSet;
  417. for (i = RATE_54M_INDEX; i >= RATE_1M_INDEX; i--) {
  418. if (u2RateSet & BIT(i)) {
  419. *pucInitialRateIndex = (UINT_8) i;
  420. return TRUE;
  421. }
  422. }
  423. return FALSE;
  424. } /* end of rateGetBestInitialRateIndex() */
  425. #endif