1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
20 #include "odm_precomp.h"
22 static u8
odm_QueryRxPwrPercentage(s8 AntPower
)
24 if ((AntPower
<= -100) || (AntPower
>= 20))
26 else if (AntPower
>= 0)
29 return 100 + AntPower
;
32 static s32
odm_SignalScaleMapping_92CSeries(struct dm_odm_t
*pDM_Odm
, s32 CurrSig
)
36 if (CurrSig
>= 51 && CurrSig
<= 100)
38 else if (CurrSig
>= 41 && CurrSig
<= 50)
39 RetSig
= 80 + ((CurrSig
- 40)*2);
40 else if (CurrSig
>= 31 && CurrSig
<= 40)
41 RetSig
= 66 + (CurrSig
- 30);
42 else if (CurrSig
>= 21 && CurrSig
<= 30)
43 RetSig
= 54 + (CurrSig
- 20);
44 else if (CurrSig
>= 10 && CurrSig
<= 20)
45 RetSig
= 42 + (((CurrSig
- 10) * 2) / 3);
46 else if (CurrSig
>= 5 && CurrSig
<= 9)
47 RetSig
= 22 + (((CurrSig
- 5) * 3) / 2);
48 else if (CurrSig
>= 1 && CurrSig
<= 4)
49 RetSig
= 6 + (((CurrSig
- 1) * 3) / 2);
56 static s32
odm_SignalScaleMapping(struct dm_odm_t
*pDM_Odm
, s32 CurrSig
)
58 return odm_SignalScaleMapping_92CSeries(pDM_Odm
, CurrSig
);
62 odm_EVMdbToPercentage(
67 /* -33dB~0dB to 0%~99% */
78 ret_val
= 0 - ret_val
;
87 static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t
*pDM_Odm
,
88 struct phy_info
*pPhyInfo
,
90 struct odm_packet_info
*pPktinfo
)
92 struct phy_status_rpt
*pPhyStaRpt
= (struct phy_status_rpt
*)pPhyStatus
;
93 u8 i
, Max_spatial_stream
;
94 s8 rx_pwr
[4], rx_pwr_all
= 0;
95 u8 EVM
, PWDB_ALL
= 0, PWDB_ALL_BT
;
96 u8 RSSI
, total_rssi
= 0;
101 isCCKrate
= (pPktinfo
->Rate
<= DESC92C_RATE11M
) ? true : false;
102 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_A
] = -1;
103 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_B
] = -1;
109 pDM_Odm
->PhyDbgInfo
.NumQryPhyStatusCCK
++;
110 /* (1)Hardware does not provide RSSI for CCK */
111 /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
113 cck_highpwr
= pDM_Odm
->bCckHighPower
;
115 cck_agc_rpt
= pPhyStaRpt
->cck_agc_rpt_ofdm_cfosho_a
;
117 /* The RSSI formula should be modified according to the gain table */
119 report
= (cck_agc_rpt
& 0xc0)>>6;
121 /* Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion */
122 /* Note: different RF with the different RNA gain. */
124 rx_pwr_all
= -46 - (cck_agc_rpt
& 0x3e);
127 rx_pwr_all
= -26 - (cck_agc_rpt
& 0x3e);
130 rx_pwr_all
= -12 - (cck_agc_rpt
& 0x3e);
133 rx_pwr_all
= 16 - (cck_agc_rpt
& 0x3e);
137 report
= (cck_agc_rpt
& 0x60)>>5;
140 rx_pwr_all
= -46 - ((cck_agc_rpt
& 0x1f)<<1);
143 rx_pwr_all
= -26 - ((cck_agc_rpt
& 0x1f)<<1);
146 rx_pwr_all
= -12 - ((cck_agc_rpt
& 0x1f)<<1);
149 rx_pwr_all
= 16 - ((cck_agc_rpt
& 0x1f)<<1);
154 PWDB_ALL
= odm_QueryRxPwrPercentage(rx_pwr_all
);
156 /* Modification for ext-LNA board */
157 if (pDM_Odm
->BoardType
== ODM_BOARD_HIGHPWR
) {
158 if ((cck_agc_rpt
>>7) == 0) {
159 PWDB_ALL
= (PWDB_ALL
> 94) ? 100 : (PWDB_ALL
+6);
164 PWDB_ALL
= (PWDB_ALL
<= 16) ? (PWDB_ALL
>>2) : (PWDB_ALL
-12);
167 /* CCK modification */
168 if (PWDB_ALL
> 25 && PWDB_ALL
<= 60)
170 } else { /* Modification for int-LNA board */
173 else if (PWDB_ALL
> 50 && PWDB_ALL
<= 68)
176 pPhyInfo
->RxPWDBAll
= PWDB_ALL
;
177 pPhyInfo
->BTRxRSSIPercentage
= PWDB_ALL
;
178 pPhyInfo
->RecvSignalPower
= rx_pwr_all
;
179 /* (3) Get Signal Quality (EVM) */
180 if (pPktinfo
->bPacketMatchBSSID
) {
183 SQ_rpt
= pPhyStaRpt
->cck_sig_qual_ofdm_pwdb_all
;
187 else if (SQ_rpt
< 20)
190 SQ
= ((64-SQ_rpt
) * 100) / 44;
192 pPhyInfo
->SignalQuality
= SQ
;
193 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_A
] = SQ
;
194 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_B
] = -1;
196 } else { /* is OFDM rate */
197 pDM_Odm
->PhyDbgInfo
.NumQryPhyStatusOFDM
++;
199 /* (1)Get RSSI for HT rate */
201 for (i
= RF_PATH_A
; i
< RF_PATH_MAX
; i
++) {
202 /* 2008/01/30 MH we will judge RF RX path now. */
203 if (pDM_Odm
->RFPathRxEnable
& BIT(i
))
206 rx_pwr
[i
] = ((pPhyStaRpt
->path_agc
[i
].gain
& 0x3F)*2) - 110;
208 pPhyInfo
->RxPwr
[i
] = rx_pwr
[i
];
210 /* Translate DBM to percentage. */
211 RSSI
= odm_QueryRxPwrPercentage(rx_pwr
[i
]);
214 /* Modification for ext-LNA board */
215 if (pDM_Odm
->BoardType
== ODM_BOARD_HIGHPWR
) {
216 if ((pPhyStaRpt
->path_agc
[i
].trsw
) == 1)
217 RSSI
= (RSSI
> 94) ? 100 : (RSSI
+6);
219 RSSI
= (RSSI
<= 16) ? (RSSI
>>3) : (RSSI
-16);
221 if ((RSSI
<= 34) && (RSSI
>= 4))
225 pPhyInfo
->RxMIMOSignalStrength
[i
] = (u8
) RSSI
;
227 /* Get Rx snr value in DB */
228 pPhyInfo
->RxSNR
[i
] = pDM_Odm
->PhyDbgInfo
.RxSNRdB
[i
] = (s32
)(pPhyStaRpt
->path_rxsnr
[i
]/2);
231 /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
232 rx_pwr_all
= (((pPhyStaRpt
->cck_sig_qual_ofdm_pwdb_all
) >> 1) & 0x7f)-110;
234 PWDB_ALL
= odm_QueryRxPwrPercentage(rx_pwr_all
);
235 PWDB_ALL_BT
= PWDB_ALL
;
237 pPhyInfo
->RxPWDBAll
= PWDB_ALL
;
238 pPhyInfo
->BTRxRSSIPercentage
= PWDB_ALL_BT
;
239 pPhyInfo
->RxPower
= rx_pwr_all
;
240 pPhyInfo
->RecvSignalPower
= rx_pwr_all
;
242 /* (3)EVM of HT rate */
243 if (pPktinfo
->Rate
>= DESC92C_RATEMCS8
&& pPktinfo
->Rate
<= DESC92C_RATEMCS15
)
244 Max_spatial_stream
= 2; /* both spatial stream make sense */
246 Max_spatial_stream
= 1; /* only spatial stream 1 makes sense */
248 for (i
= 0; i
< Max_spatial_stream
; i
++) {
249 /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
250 /* fill most significant bit to "zero" when doing shifting operation which may change a negative */
251 /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */
252 EVM
= odm_EVMdbToPercentage((pPhyStaRpt
->stream_rxevm
[i
])); /* dbm */
254 if (pPktinfo
->bPacketMatchBSSID
) {
255 if (i
== RF_PATH_A
) {
256 /* Fill value in RFD, Get the first spatial stream only */
257 pPhyInfo
->SignalQuality
= (u8
)(EVM
& 0xff);
259 pPhyInfo
->RxMIMOSignalQuality
[i
] = (u8
)(EVM
& 0xff);
263 /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
264 /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
266 pPhyInfo
->SignalStrength
= (u8
)(odm_SignalScaleMapping(pDM_Odm
, PWDB_ALL
));/* PWDB_ALL; */
269 pPhyInfo
->SignalStrength
= (u8
)(odm_SignalScaleMapping(pDM_Odm
, total_rssi
/= rf_rx_num
));
273 void odm_Init_RSSIForDM23a(struct dm_odm_t
*pDM_Odm
)
277 static void odm_Process_RSSIForDM(struct dm_odm_t
*pDM_Odm
,
278 struct phy_info
*pPhyInfo
,
279 struct odm_packet_info
*pPktinfo
)
281 s32 UndecoratedSmoothedPWDB
, UndecoratedSmoothedCCK
;
282 s32 UndecoratedSmoothedOFDM
, RSSI_Ave
;
284 u8 RSSI_max
, RSSI_min
, i
;
287 struct sta_info
*pEntry
;
289 if (pPktinfo
->StationID
== 0xFF)
292 pEntry
= pDM_Odm
->pODM_StaInfo
[pPktinfo
->StationID
];
295 if ((!pPktinfo
->bPacketMatchBSSID
))
298 isCCKrate
= (pPktinfo
->Rate
<= DESC92C_RATE11M
) ? true : false;
300 /* Smart Antenna Debug Message------------------*/
302 UndecoratedSmoothedCCK
= pEntry
->rssi_stat
.UndecoratedSmoothedCCK
;
303 UndecoratedSmoothedOFDM
= pEntry
->rssi_stat
.UndecoratedSmoothedOFDM
;
304 UndecoratedSmoothedPWDB
= pEntry
->rssi_stat
.UndecoratedSmoothedPWDB
;
306 if (pPktinfo
->bPacketToSelf
|| pPktinfo
->bPacketBeacon
) {
307 if (!isCCKrate
) { /* ofdm rate */
308 if (pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
] == 0) {
309 RSSI_Ave
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
];
311 if (pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
] > pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
]) {
312 RSSI_max
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
];
313 RSSI_min
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
];
315 RSSI_max
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
];
316 RSSI_min
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
];
318 if ((RSSI_max
- RSSI_min
) < 3)
320 else if ((RSSI_max
- RSSI_min
) < 6)
321 RSSI_Ave
= RSSI_max
- 1;
322 else if ((RSSI_max
- RSSI_min
) < 10)
323 RSSI_Ave
= RSSI_max
- 2;
325 RSSI_Ave
= RSSI_max
- 3;
328 /* 1 Process OFDM RSSI */
329 if (UndecoratedSmoothedOFDM
<= 0) {
331 UndecoratedSmoothedOFDM
= pPhyInfo
->RxPWDBAll
;
333 if (pPhyInfo
->RxPWDBAll
> (u32
)UndecoratedSmoothedOFDM
) {
334 UndecoratedSmoothedOFDM
=
335 (((UndecoratedSmoothedOFDM
)*(Rx_Smooth_Factor
-1)) +
336 (RSSI_Ave
)) / (Rx_Smooth_Factor
);
337 UndecoratedSmoothedOFDM
= UndecoratedSmoothedOFDM
+ 1;
339 UndecoratedSmoothedOFDM
=
340 (((UndecoratedSmoothedOFDM
)*(Rx_Smooth_Factor
-1)) +
341 (RSSI_Ave
)) / (Rx_Smooth_Factor
);
344 pEntry
->rssi_stat
.PacketMap
=
345 (pEntry
->rssi_stat
.PacketMap
<<1) | BIT(0);
347 RSSI_Ave
= pPhyInfo
->RxPWDBAll
;
349 /* 1 Process CCK RSSI */
350 if (UndecoratedSmoothedCCK
<= 0) {
352 UndecoratedSmoothedCCK
= pPhyInfo
->RxPWDBAll
;
354 if (pPhyInfo
->RxPWDBAll
> (u32
)UndecoratedSmoothedCCK
) {
355 UndecoratedSmoothedCCK
=
356 (((UndecoratedSmoothedCCK
)*(Rx_Smooth_Factor
-1)) +
357 (pPhyInfo
->RxPWDBAll
)) / (Rx_Smooth_Factor
);
358 UndecoratedSmoothedCCK
= UndecoratedSmoothedCCK
+ 1;
360 UndecoratedSmoothedCCK
=
361 (((UndecoratedSmoothedCCK
)*(Rx_Smooth_Factor
-1)) +
362 (pPhyInfo
->RxPWDBAll
)) / (Rx_Smooth_Factor
);
365 pEntry
->rssi_stat
.PacketMap
= pEntry
->rssi_stat
.PacketMap
<<1;
368 /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
369 if (pEntry
->rssi_stat
.ValidBit
>= 64)
370 pEntry
->rssi_stat
.ValidBit
= 64;
372 pEntry
->rssi_stat
.ValidBit
++;
374 for (i
= 0; i
< pEntry
->rssi_stat
.ValidBit
; i
++)
376 (u8
)(pEntry
->rssi_stat
.PacketMap
>>i
) & BIT(0);
378 if (pEntry
->rssi_stat
.ValidBit
== 64) {
379 Weighting
= ((OFDM_pkt
<<4) > 64)?64:(OFDM_pkt
<<4);
380 UndecoratedSmoothedPWDB
= (Weighting
*UndecoratedSmoothedOFDM
+(64-Weighting
)*UndecoratedSmoothedCCK
)>>6;
382 if (pEntry
->rssi_stat
.ValidBit
!= 0)
383 UndecoratedSmoothedPWDB
= (OFDM_pkt
*UndecoratedSmoothedOFDM
+(pEntry
->rssi_stat
.ValidBit
-OFDM_pkt
)*UndecoratedSmoothedCCK
)/pEntry
->rssi_stat
.ValidBit
;
385 UndecoratedSmoothedPWDB
= 0;
387 pEntry
->rssi_stat
.UndecoratedSmoothedCCK
= UndecoratedSmoothedCCK
;
388 pEntry
->rssi_stat
.UndecoratedSmoothedOFDM
= UndecoratedSmoothedOFDM
;
389 pEntry
->rssi_stat
.UndecoratedSmoothedPWDB
= UndecoratedSmoothedPWDB
;
393 void ODM_PhyStatusQuery23a(struct dm_odm_t
*pDM_Odm
, struct phy_info
*pPhyInfo
,
394 u8
*pPhyStatus
, struct odm_packet_info
*pPktinfo
)
396 odm_RxPhyStatus92CSeries_Parsing(pDM_Odm
, pPhyInfo
,
397 pPhyStatus
, pPktinfo
);
399 odm_Process_RSSIForDM(pDM_Odm
, pPhyInfo
, pPktinfo
);