odm_HWConfig.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or modify it
  6. * under the terms of version 2 of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. ******************************************************************************/
  15. /* */
  16. /* include files */
  17. /* */
  18. #include "odm_precomp.h"
  19. static u8 odm_QueryRxPwrPercentage(s8 AntPower)
  20. {
  21. if ((AntPower <= -100) || (AntPower >= 20))
  22. return 0;
  23. else if (AntPower >= 0)
  24. return 100;
  25. else
  26. return 100 + AntPower;
  27. }
  28. static s32 odm_SignalScaleMapping_92CSeries(struct dm_odm_t *pDM_Odm, s32 CurrSig)
  29. {
  30. s32 RetSig = 0;
  31. if (CurrSig >= 51 && CurrSig <= 100)
  32. RetSig = 100;
  33. else if (CurrSig >= 41 && CurrSig <= 50)
  34. RetSig = 80 + ((CurrSig - 40)*2);
  35. else if (CurrSig >= 31 && CurrSig <= 40)
  36. RetSig = 66 + (CurrSig - 30);
  37. else if (CurrSig >= 21 && CurrSig <= 30)
  38. RetSig = 54 + (CurrSig - 20);
  39. else if (CurrSig >= 10 && CurrSig <= 20)
  40. RetSig = 42 + (((CurrSig - 10) * 2) / 3);
  41. else if (CurrSig >= 5 && CurrSig <= 9)
  42. RetSig = 22 + (((CurrSig - 5) * 3) / 2);
  43. else if (CurrSig >= 1 && CurrSig <= 4)
  44. RetSig = 6 + (((CurrSig - 1) * 3) / 2);
  45. else
  46. RetSig = CurrSig;
  47. return RetSig;
  48. }
  49. static s32 odm_SignalScaleMapping(struct dm_odm_t *pDM_Odm, s32 CurrSig)
  50. {
  51. return odm_SignalScaleMapping_92CSeries(pDM_Odm, CurrSig);
  52. }
  53. static u8
  54. odm_EVMdbToPercentage(
  55. s8 Value
  56. )
  57. {
  58. /* */
  59. /* -33dB~0dB to 0%~99% */
  60. /* */
  61. s8 ret_val;
  62. ret_val = Value;
  63. if (ret_val >= 0)
  64. ret_val = 0;
  65. if (ret_val <= -33)
  66. ret_val = -33;
  67. ret_val = 0 - ret_val;
  68. ret_val *= 3;
  69. if (ret_val == 99)
  70. ret_val = 100;
  71. return ret_val;
  72. }
  73. static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t *pDM_Odm,
  74. struct phy_info *pPhyInfo,
  75. u8 *pPhyStatus,
  76. struct odm_packet_info *pPktinfo)
  77. {
  78. struct phy_status_rpt *pPhyStaRpt = (struct phy_status_rpt *)pPhyStatus;
  79. u8 i, Max_spatial_stream;
  80. s8 rx_pwr[4], rx_pwr_all = 0;
  81. u8 EVM, PWDB_ALL = 0, PWDB_ALL_BT;
  82. u8 RSSI, total_rssi = 0;
  83. u8 isCCKrate = 0;
  84. u8 rf_rx_num = 0;
  85. u8 cck_highpwr = 0;
  86. isCCKrate = (pPktinfo->Rate <= DESC92C_RATE11M) ? true : false;
  87. pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = -1;
  88. pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
  89. if (isCCKrate) {
  90. u8 report;
  91. u8 cck_agc_rpt;
  92. pDM_Odm->PhyDbgInfo.NumQryPhyStatusCCK++;
  93. /* (1)Hardware does not provide RSSI for CCK */
  94. /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
  95. cck_highpwr = pDM_Odm->bCckHighPower;
  96. cck_agc_rpt = pPhyStaRpt->cck_agc_rpt_ofdm_cfosho_a;
  97. /* The RSSI formula should be modified according to the gain table */
  98. if (!cck_highpwr) {
  99. report = (cck_agc_rpt & 0xc0)>>6;
  100. switch (report) {
  101. /* Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion */
  102. /* Note: different RF with the different RNA gain. */
  103. case 0x3:
  104. rx_pwr_all = -46 - (cck_agc_rpt & 0x3e);
  105. break;
  106. case 0x2:
  107. rx_pwr_all = -26 - (cck_agc_rpt & 0x3e);
  108. break;
  109. case 0x1:
  110. rx_pwr_all = -12 - (cck_agc_rpt & 0x3e);
  111. break;
  112. case 0x0:
  113. rx_pwr_all = 16 - (cck_agc_rpt & 0x3e);
  114. break;
  115. }
  116. } else {
  117. report = (cck_agc_rpt & 0x60)>>5;
  118. switch (report) {
  119. case 0x3:
  120. rx_pwr_all = -46 - ((cck_agc_rpt & 0x1f)<<1);
  121. break;
  122. case 0x2:
  123. rx_pwr_all = -26 - ((cck_agc_rpt & 0x1f)<<1);
  124. break;
  125. case 0x1:
  126. rx_pwr_all = -12 - ((cck_agc_rpt & 0x1f)<<1);
  127. break;
  128. case 0x0:
  129. rx_pwr_all = 16 - ((cck_agc_rpt & 0x1f)<<1);
  130. break;
  131. }
  132. }
  133. PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all);
  134. /* Modification for ext-LNA board */
  135. if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) {
  136. if ((cck_agc_rpt>>7) == 0) {
  137. PWDB_ALL = (PWDB_ALL > 94) ? 100 : (PWDB_ALL+6);
  138. } else {
  139. if (PWDB_ALL > 38)
  140. PWDB_ALL -= 16;
  141. else
  142. PWDB_ALL = (PWDB_ALL <= 16) ? (PWDB_ALL>>2) : (PWDB_ALL-12);
  143. }
  144. /* CCK modification */
  145. if (PWDB_ALL > 25 && PWDB_ALL <= 60)
  146. PWDB_ALL += 6;
  147. } else { /* Modification for int-LNA board */
  148. if (PWDB_ALL > 99)
  149. PWDB_ALL -= 8;
  150. else if (PWDB_ALL > 50 && PWDB_ALL <= 68)
  151. PWDB_ALL += 4;
  152. }
  153. pPhyInfo->RxPWDBAll = PWDB_ALL;
  154. pPhyInfo->BTRxRSSIPercentage = PWDB_ALL;
  155. pPhyInfo->RecvSignalPower = rx_pwr_all;
  156. /* (3) Get Signal Quality (EVM) */
  157. if (pPktinfo->bPacketMatchBSSID) {
  158. u8 SQ, SQ_rpt;
  159. SQ_rpt = pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all;
  160. if (SQ_rpt > 64)
  161. SQ = 0;
  162. else if (SQ_rpt < 20)
  163. SQ = 100;
  164. else
  165. SQ = ((64-SQ_rpt) * 100) / 44;
  166. pPhyInfo->SignalQuality = SQ;
  167. pPhyInfo->RxMIMOSignalQuality[RF_PATH_A] = SQ;
  168. pPhyInfo->RxMIMOSignalQuality[RF_PATH_B] = -1;
  169. }
  170. } else { /* is OFDM rate */
  171. pDM_Odm->PhyDbgInfo.NumQryPhyStatusOFDM++;
  172. /* (1)Get RSSI for HT rate */
  173. for (i = RF_PATH_A; i < RF_PATH_MAX; i++) {
  174. /* 2008/01/30 MH we will judge RF RX path now. */
  175. if (pDM_Odm->RFPathRxEnable & BIT(i))
  176. rf_rx_num++;
  177. rx_pwr[i] = ((pPhyStaRpt->path_agc[i].gain & 0x3F)*2) - 110;
  178. pPhyInfo->RxPwr[i] = rx_pwr[i];
  179. /* Translate DBM to percentage. */
  180. RSSI = odm_QueryRxPwrPercentage(rx_pwr[i]);
  181. total_rssi += RSSI;
  182. /* Modification for ext-LNA board */
  183. if (pDM_Odm->BoardType == ODM_BOARD_HIGHPWR) {
  184. if ((pPhyStaRpt->path_agc[i].trsw) == 1)
  185. RSSI = (RSSI > 94) ? 100 : (RSSI+6);
  186. else
  187. RSSI = (RSSI <= 16) ? (RSSI>>3) : (RSSI-16);
  188. if ((RSSI <= 34) && (RSSI >= 4))
  189. RSSI -= 4;
  190. }
  191. pPhyInfo->RxMIMOSignalStrength[i] = (u8) RSSI;
  192. /* Get Rx snr value in DB */
  193. pPhyInfo->RxSNR[i] = pDM_Odm->PhyDbgInfo.RxSNRdB[i] = (s32)(pPhyStaRpt->path_rxsnr[i]/2);
  194. }
  195. /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
  196. rx_pwr_all = (((pPhyStaRpt->cck_sig_qual_ofdm_pwdb_all) >> 1) & 0x7f)-110;
  197. PWDB_ALL = odm_QueryRxPwrPercentage(rx_pwr_all);
  198. PWDB_ALL_BT = PWDB_ALL;
  199. pPhyInfo->RxPWDBAll = PWDB_ALL;
  200. pPhyInfo->BTRxRSSIPercentage = PWDB_ALL_BT;
  201. pPhyInfo->RxPower = rx_pwr_all;
  202. pPhyInfo->RecvSignalPower = rx_pwr_all;
  203. /* (3)EVM of HT rate */
  204. if (pPktinfo->Rate >= DESC92C_RATEMCS8 && pPktinfo->Rate <= DESC92C_RATEMCS15)
  205. Max_spatial_stream = 2; /* both spatial stream make sense */
  206. else
  207. Max_spatial_stream = 1; /* only spatial stream 1 makes sense */
  208. for (i = 0; i < Max_spatial_stream; i++) {
  209. /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
  210. /* fill most significant bit to "zero" when doing shifting operation which may change a negative */
  211. /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */
  212. EVM = odm_EVMdbToPercentage((pPhyStaRpt->stream_rxevm[i])); /* dbm */
  213. if (pPktinfo->bPacketMatchBSSID) {
  214. if (i == RF_PATH_A) {
  215. /* Fill value in RFD, Get the first spatial stream only */
  216. pPhyInfo->SignalQuality = (u8)(EVM & 0xff);
  217. }
  218. pPhyInfo->RxMIMOSignalQuality[i] = (u8)(EVM & 0xff);
  219. }
  220. }
  221. }
  222. /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
  223. /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
  224. if (isCCKrate) {
  225. pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(pDM_Odm, PWDB_ALL));/* PWDB_ALL; */
  226. } else {
  227. if (rf_rx_num != 0)
  228. pPhyInfo->SignalStrength = (u8)(odm_SignalScaleMapping(pDM_Odm, total_rssi /= rf_rx_num));
  229. }
  230. }
  231. void odm_Init_RSSIForDM23a(struct dm_odm_t *pDM_Odm)
  232. {
  233. }
  234. static void odm_Process_RSSIForDM(struct dm_odm_t *pDM_Odm,
  235. struct phy_info *pPhyInfo,
  236. struct odm_packet_info *pPktinfo)
  237. {
  238. s32 UndecoratedSmoothedPWDB, UndecoratedSmoothedCCK;
  239. s32 UndecoratedSmoothedOFDM, RSSI_Ave;
  240. u8 isCCKrate = 0;
  241. u8 RSSI_max, RSSI_min, i;
  242. u32 OFDM_pkt = 0;
  243. u32 Weighting = 0;
  244. struct sta_info *pEntry;
  245. if (pPktinfo->StationID == 0xFF)
  246. return;
  247. pEntry = pDM_Odm->pODM_StaInfo[pPktinfo->StationID];
  248. if (!pEntry)
  249. return;
  250. if ((!pPktinfo->bPacketMatchBSSID))
  251. return;
  252. isCCKrate = (pPktinfo->Rate <= DESC92C_RATE11M) ? true : false;
  253. /* Smart Antenna Debug Message------------------*/
  254. UndecoratedSmoothedCCK = pEntry->rssi_stat.UndecoratedSmoothedCCK;
  255. UndecoratedSmoothedOFDM = pEntry->rssi_stat.UndecoratedSmoothedOFDM;
  256. UndecoratedSmoothedPWDB = pEntry->rssi_stat.UndecoratedSmoothedPWDB;
  257. if (pPktinfo->bPacketToSelf || pPktinfo->bPacketBeacon) {
  258. if (!isCCKrate) { /* ofdm rate */
  259. if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_B] == 0) {
  260. RSSI_Ave = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
  261. } else {
  262. if (pPhyInfo->RxMIMOSignalStrength[RF_PATH_A] > pPhyInfo->RxMIMOSignalStrength[RF_PATH_B]) {
  263. RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
  264. RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
  265. } else {
  266. RSSI_max = pPhyInfo->RxMIMOSignalStrength[RF_PATH_B];
  267. RSSI_min = pPhyInfo->RxMIMOSignalStrength[RF_PATH_A];
  268. }
  269. if ((RSSI_max - RSSI_min) < 3)
  270. RSSI_Ave = RSSI_max;
  271. else if ((RSSI_max - RSSI_min) < 6)
  272. RSSI_Ave = RSSI_max - 1;
  273. else if ((RSSI_max - RSSI_min) < 10)
  274. RSSI_Ave = RSSI_max - 2;
  275. else
  276. RSSI_Ave = RSSI_max - 3;
  277. }
  278. /* 1 Process OFDM RSSI */
  279. if (UndecoratedSmoothedOFDM <= 0) {
  280. /* initialize */
  281. UndecoratedSmoothedOFDM = pPhyInfo->RxPWDBAll;
  282. } else {
  283. if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedOFDM) {
  284. UndecoratedSmoothedOFDM =
  285. (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) +
  286. (RSSI_Ave)) / (Rx_Smooth_Factor);
  287. UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM + 1;
  288. } else {
  289. UndecoratedSmoothedOFDM =
  290. (((UndecoratedSmoothedOFDM)*(Rx_Smooth_Factor-1)) +
  291. (RSSI_Ave)) / (Rx_Smooth_Factor);
  292. }
  293. }
  294. pEntry->rssi_stat.PacketMap =
  295. (pEntry->rssi_stat.PacketMap<<1) | BIT(0);
  296. } else {
  297. RSSI_Ave = pPhyInfo->RxPWDBAll;
  298. /* 1 Process CCK RSSI */
  299. if (UndecoratedSmoothedCCK <= 0) {
  300. /* initialize */
  301. UndecoratedSmoothedCCK = pPhyInfo->RxPWDBAll;
  302. } else {
  303. if (pPhyInfo->RxPWDBAll > (u32)UndecoratedSmoothedCCK) {
  304. UndecoratedSmoothedCCK =
  305. (((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) +
  306. (pPhyInfo->RxPWDBAll)) / (Rx_Smooth_Factor);
  307. UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1;
  308. } else {
  309. UndecoratedSmoothedCCK =
  310. (((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) +
  311. (pPhyInfo->RxPWDBAll)) / (Rx_Smooth_Factor);
  312. }
  313. }
  314. pEntry->rssi_stat.PacketMap = pEntry->rssi_stat.PacketMap<<1;
  315. }
  316. /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
  317. if (pEntry->rssi_stat.ValidBit >= 64)
  318. pEntry->rssi_stat.ValidBit = 64;
  319. else
  320. pEntry->rssi_stat.ValidBit++;
  321. for (i = 0; i < pEntry->rssi_stat.ValidBit; i++)
  322. OFDM_pkt +=
  323. (u8)(pEntry->rssi_stat.PacketMap>>i) & BIT(0);
  324. if (pEntry->rssi_stat.ValidBit == 64) {
  325. Weighting = ((OFDM_pkt<<4) > 64)?64:(OFDM_pkt<<4);
  326. UndecoratedSmoothedPWDB = (Weighting*UndecoratedSmoothedOFDM+(64-Weighting)*UndecoratedSmoothedCCK)>>6;
  327. } else {
  328. if (pEntry->rssi_stat.ValidBit != 0)
  329. UndecoratedSmoothedPWDB = (OFDM_pkt*UndecoratedSmoothedOFDM+(pEntry->rssi_stat.ValidBit-OFDM_pkt)*UndecoratedSmoothedCCK)/pEntry->rssi_stat.ValidBit;
  330. else
  331. UndecoratedSmoothedPWDB = 0;
  332. }
  333. pEntry->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
  334. pEntry->rssi_stat.UndecoratedSmoothedOFDM = UndecoratedSmoothedOFDM;
  335. pEntry->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
  336. }
  337. }
  338. void ODM_PhyStatusQuery23a(struct dm_odm_t *pDM_Odm, struct phy_info *pPhyInfo,
  339. u8 *pPhyStatus, struct odm_packet_info *pPktinfo)
  340. {
  341. odm_RxPhyStatus92CSeries_Parsing(pDM_Odm, pPhyInfo,
  342. pPhyStatus, pPktinfo);
  343. odm_Process_RSSIForDM(pDM_Odm, pPhyInfo, pPktinfo);
  344. }