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 ((pDM_Odm
->SupportInterface
== ODM_ITRF_USB
) || (pDM_Odm
->SupportInterface
== ODM_ITRF_SDIO
)) {
37 if (CurrSig
>= 51 && CurrSig
<= 100)
39 else if (CurrSig
>= 41 && CurrSig
<= 50)
40 RetSig
= 80 + ((CurrSig
- 40)*2);
41 else if (CurrSig
>= 31 && CurrSig
<= 40)
42 RetSig
= 66 + (CurrSig
- 30);
43 else if (CurrSig
>= 21 && CurrSig
<= 30)
44 RetSig
= 54 + (CurrSig
- 20);
45 else if (CurrSig
>= 10 && CurrSig
<= 20)
46 RetSig
= 42 + (((CurrSig
- 10) * 2) / 3);
47 else if (CurrSig
>= 5 && CurrSig
<= 9)
48 RetSig
= 22 + (((CurrSig
- 5) * 3) / 2);
49 else if (CurrSig
>= 1 && CurrSig
<= 4)
50 RetSig
= 6 + (((CurrSig
- 1) * 3) / 2);
57 static s32
odm_SignalScaleMapping(struct dm_odm_t
*pDM_Odm
, s32 CurrSig
)
59 return odm_SignalScaleMapping_92CSeries(pDM_Odm
, CurrSig
);
63 odm_EVMdbToPercentage(
68 /* -33dB~0dB to 0%~99% */
79 ret_val
= 0 - ret_val
;
88 static void odm_RxPhyStatus92CSeries_Parsing(struct dm_odm_t
*pDM_Odm
,
89 struct phy_info
*pPhyInfo
,
91 struct odm_packet_info
*pPktinfo
)
93 struct phy_status_rpt
*pPhyStaRpt
= (struct phy_status_rpt
*)pPhyStatus
;
94 u8 i
, Max_spatial_stream
;
95 s8 rx_pwr
[4], rx_pwr_all
= 0;
96 u8 EVM
, PWDB_ALL
= 0, PWDB_ALL_BT
;
97 u8 RSSI
, total_rssi
= 0;
102 isCCKrate
= (pPktinfo
->Rate
<= DESC92C_RATE11M
) ? true : false;
103 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_A
] = -1;
104 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_B
] = -1;
110 pDM_Odm
->PhyDbgInfo
.NumQryPhyStatusCCK
++;
111 /* (1)Hardware does not provide RSSI for CCK */
112 /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
114 cck_highpwr
= pDM_Odm
->bCckHighPower
;
116 cck_agc_rpt
= pPhyStaRpt
->cck_agc_rpt_ofdm_cfosho_a
;
118 /* The RSSI formula should be modified according to the gain table */
120 report
= (cck_agc_rpt
& 0xc0)>>6;
122 /* Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion */
123 /* Note: different RF with the different RNA gain. */
125 rx_pwr_all
= -46 - (cck_agc_rpt
& 0x3e);
128 rx_pwr_all
= -26 - (cck_agc_rpt
& 0x3e);
131 rx_pwr_all
= -12 - (cck_agc_rpt
& 0x3e);
134 rx_pwr_all
= 16 - (cck_agc_rpt
& 0x3e);
138 report
= (cck_agc_rpt
& 0x60)>>5;
141 rx_pwr_all
= -46 - ((cck_agc_rpt
& 0x1f)<<1) ;
144 rx_pwr_all
= -26 - ((cck_agc_rpt
& 0x1f)<<1);
147 rx_pwr_all
= -12 - ((cck_agc_rpt
& 0x1f)<<1) ;
150 rx_pwr_all
= 16 - ((cck_agc_rpt
& 0x1f)<<1) ;
155 PWDB_ALL
= odm_QueryRxPwrPercentage(rx_pwr_all
);
157 /* Modification for ext-LNA board */
158 if (pDM_Odm
->BoardType
== ODM_BOARD_HIGHPWR
) {
159 if ((cck_agc_rpt
>>7) == 0) {
160 PWDB_ALL
= (PWDB_ALL
> 94) ? 100 : (PWDB_ALL
+6);
165 PWDB_ALL
= (PWDB_ALL
<= 16) ? (PWDB_ALL
>>2) : (PWDB_ALL
-12);
168 /* CCK modification */
169 if (PWDB_ALL
> 25 && PWDB_ALL
<= 60)
171 } else { /* Modification for int-LNA board */
174 else if (PWDB_ALL
> 50 && PWDB_ALL
<= 68)
177 pPhyInfo
->RxPWDBAll
= PWDB_ALL
;
178 pPhyInfo
->BTRxRSSIPercentage
= PWDB_ALL
;
179 pPhyInfo
->RecvSignalPower
= rx_pwr_all
;
180 /* (3) Get Signal Quality (EVM) */
181 if (pPktinfo
->bPacketMatchBSSID
) {
184 SQ_rpt
= pPhyStaRpt
->cck_sig_qual_ofdm_pwdb_all
;
188 else if (SQ_rpt
< 20)
191 SQ
= ((64-SQ_rpt
) * 100) / 44;
193 pPhyInfo
->SignalQuality
= SQ
;
194 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_A
] = SQ
;
195 pPhyInfo
->RxMIMOSignalQuality
[RF_PATH_B
] = -1;
197 } else { /* is OFDM rate */
198 pDM_Odm
->PhyDbgInfo
.NumQryPhyStatusOFDM
++;
200 /* (1)Get RSSI for HT rate */
202 for (i
= RF_PATH_A
; i
< RF_PATH_MAX
; i
++) {
203 /* 2008/01/30 MH we will judge RF RX path now. */
204 if (pDM_Odm
->RFPathRxEnable
& BIT(i
))
207 rx_pwr
[i
] = ((pPhyStaRpt
->path_agc
[i
].gain
& 0x3F)*2) - 110;
209 pPhyInfo
->RxPwr
[i
] = rx_pwr
[i
];
211 /* Translate DBM to percentage. */
212 RSSI
= odm_QueryRxPwrPercentage(rx_pwr
[i
]);
215 /* Modification for ext-LNA board */
216 if (pDM_Odm
->BoardType
== ODM_BOARD_HIGHPWR
) {
217 if ((pPhyStaRpt
->path_agc
[i
].trsw
) == 1)
218 RSSI
= (RSSI
> 94) ? 100 : (RSSI
+6);
220 RSSI
= (RSSI
<= 16) ? (RSSI
>>3) : (RSSI
-16);
222 if ((RSSI
<= 34) && (RSSI
>= 4))
226 pPhyInfo
->RxMIMOSignalStrength
[i
] = (u8
) RSSI
;
228 /* Get Rx snr value in DB */
229 pPhyInfo
->RxSNR
[i
] = pDM_Odm
->PhyDbgInfo
.RxSNRdB
[i
] = (s32
)(pPhyStaRpt
->path_rxsnr
[i
]/2);
232 /* (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) */
233 rx_pwr_all
= (((pPhyStaRpt
->cck_sig_qual_ofdm_pwdb_all
) >> 1) & 0x7f)-110;
235 PWDB_ALL
= odm_QueryRxPwrPercentage(rx_pwr_all
);
236 PWDB_ALL_BT
= PWDB_ALL
;
238 pPhyInfo
->RxPWDBAll
= PWDB_ALL
;
239 pPhyInfo
->BTRxRSSIPercentage
= PWDB_ALL_BT
;
240 pPhyInfo
->RxPower
= rx_pwr_all
;
241 pPhyInfo
->RecvSignalPower
= rx_pwr_all
;
243 /* (3)EVM of HT rate */
244 if (pPktinfo
->Rate
>= DESC92C_RATEMCS8
&& pPktinfo
->Rate
<= DESC92C_RATEMCS15
)
245 Max_spatial_stream
= 2; /* both spatial stream make sense */
247 Max_spatial_stream
= 1; /* only spatial stream 1 makes sense */
249 for (i
= 0; i
< Max_spatial_stream
; i
++) {
250 /* Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment */
251 /* fill most significant bit to "zero" when doing shifting operation which may change a negative */
252 /* value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. */
253 EVM
= odm_EVMdbToPercentage((pPhyStaRpt
->stream_rxevm
[i
])); /* dbm */
255 if (pPktinfo
->bPacketMatchBSSID
) {
256 if (i
== RF_PATH_A
) {
257 /* Fill value in RFD, Get the first spatial stream only */
258 pPhyInfo
->SignalQuality
= (u8
)(EVM
& 0xff);
260 pPhyInfo
->RxMIMOSignalQuality
[i
] = (u8
)(EVM
& 0xff);
264 /* UI BSS List signal strength(in percentage), make it good looking, from 0~100. */
265 /* It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). */
267 pPhyInfo
->SignalStrength
= (u8
)(odm_SignalScaleMapping(pDM_Odm
, PWDB_ALL
));/* PWDB_ALL; */
270 pPhyInfo
->SignalStrength
= (u8
)(odm_SignalScaleMapping(pDM_Odm
, total_rssi
/= rf_rx_num
));
274 void odm_Init_RSSIForDM23a(struct dm_odm_t
*pDM_Odm
)
278 static void odm_Process_RSSIForDM(struct dm_odm_t
*pDM_Odm
,
279 struct phy_info
*pPhyInfo
,
280 struct odm_packet_info
*pPktinfo
)
282 s32 UndecoratedSmoothedPWDB
, UndecoratedSmoothedCCK
;
283 s32 UndecoratedSmoothedOFDM
, RSSI_Ave
;
285 u8 RSSI_max
, RSSI_min
, i
;
288 struct sta_info
*pEntry
;
290 if (pPktinfo
->StationID
== 0xFF)
293 pEntry
= pDM_Odm
->pODM_StaInfo
[pPktinfo
->StationID
];
296 if ((!pPktinfo
->bPacketMatchBSSID
))
299 isCCKrate
= (pPktinfo
->Rate
<= DESC92C_RATE11M
) ? true : false;
301 /* Smart Antenna Debug Message------------------*/
303 UndecoratedSmoothedCCK
= pEntry
->rssi_stat
.UndecoratedSmoothedCCK
;
304 UndecoratedSmoothedOFDM
= pEntry
->rssi_stat
.UndecoratedSmoothedOFDM
;
305 UndecoratedSmoothedPWDB
= pEntry
->rssi_stat
.UndecoratedSmoothedPWDB
;
307 if (pPktinfo
->bPacketToSelf
|| pPktinfo
->bPacketBeacon
) {
308 if (!isCCKrate
) { /* ofdm rate */
309 if (pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
] == 0) {
310 RSSI_Ave
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
];
312 if (pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
] > pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
]) {
313 RSSI_max
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
];
314 RSSI_min
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
];
316 RSSI_max
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_B
];
317 RSSI_min
= pPhyInfo
->RxMIMOSignalStrength
[RF_PATH_A
];
319 if ((RSSI_max
- RSSI_min
) < 3)
321 else if ((RSSI_max
- RSSI_min
) < 6)
322 RSSI_Ave
= RSSI_max
- 1;
323 else if ((RSSI_max
- RSSI_min
) < 10)
324 RSSI_Ave
= RSSI_max
- 2;
326 RSSI_Ave
= RSSI_max
- 3;
329 /* 1 Process OFDM RSSI */
330 if (UndecoratedSmoothedOFDM
<= 0) {
332 UndecoratedSmoothedOFDM
= pPhyInfo
->RxPWDBAll
;
334 if (pPhyInfo
->RxPWDBAll
> (u32
)UndecoratedSmoothedOFDM
) {
335 UndecoratedSmoothedOFDM
=
336 (((UndecoratedSmoothedOFDM
)*(Rx_Smooth_Factor
-1)) +
337 (RSSI_Ave
)) / (Rx_Smooth_Factor
);
338 UndecoratedSmoothedOFDM
= UndecoratedSmoothedOFDM
+ 1;
340 UndecoratedSmoothedOFDM
=
341 (((UndecoratedSmoothedOFDM
)*(Rx_Smooth_Factor
-1)) +
342 (RSSI_Ave
)) / (Rx_Smooth_Factor
);
345 pEntry
->rssi_stat
.PacketMap
=
346 (pEntry
->rssi_stat
.PacketMap
<<1) | BIT(0);
348 RSSI_Ave
= pPhyInfo
->RxPWDBAll
;
350 /* 1 Process CCK RSSI */
351 if (UndecoratedSmoothedCCK
<= 0) {
353 UndecoratedSmoothedCCK
= pPhyInfo
->RxPWDBAll
;
355 if (pPhyInfo
->RxPWDBAll
> (u32
)UndecoratedSmoothedCCK
) {
356 UndecoratedSmoothedCCK
=
357 (((UndecoratedSmoothedCCK
)*(Rx_Smooth_Factor
-1)) +
358 (pPhyInfo
->RxPWDBAll
)) / (Rx_Smooth_Factor
);
359 UndecoratedSmoothedCCK
= UndecoratedSmoothedCCK
+ 1;
361 UndecoratedSmoothedCCK
=
362 (((UndecoratedSmoothedCCK
)*(Rx_Smooth_Factor
-1)) +
363 (pPhyInfo
->RxPWDBAll
)) / (Rx_Smooth_Factor
);
366 pEntry
->rssi_stat
.PacketMap
= pEntry
->rssi_stat
.PacketMap
<<1;
369 /* 2011.07.28 LukeLee: modified to prevent unstable CCK RSSI */
370 if (pEntry
->rssi_stat
.ValidBit
>= 64)
371 pEntry
->rssi_stat
.ValidBit
= 64;
373 pEntry
->rssi_stat
.ValidBit
++;
375 for (i
= 0; i
< pEntry
->rssi_stat
.ValidBit
; i
++)
377 (u8
)(pEntry
->rssi_stat
.PacketMap
>>i
) & BIT(0);
379 if (pEntry
->rssi_stat
.ValidBit
== 64) {
380 Weighting
= ((OFDM_pkt
<<4) > 64)?64:(OFDM_pkt
<<4);
381 UndecoratedSmoothedPWDB
= (Weighting
*UndecoratedSmoothedOFDM
+(64-Weighting
)*UndecoratedSmoothedCCK
)>>6;
383 if (pEntry
->rssi_stat
.ValidBit
!= 0)
384 UndecoratedSmoothedPWDB
= (OFDM_pkt
*UndecoratedSmoothedOFDM
+(pEntry
->rssi_stat
.ValidBit
-OFDM_pkt
)*UndecoratedSmoothedCCK
)/pEntry
->rssi_stat
.ValidBit
;
386 UndecoratedSmoothedPWDB
= 0;
388 pEntry
->rssi_stat
.UndecoratedSmoothedCCK
= UndecoratedSmoothedCCK
;
389 pEntry
->rssi_stat
.UndecoratedSmoothedOFDM
= UndecoratedSmoothedOFDM
;
390 pEntry
->rssi_stat
.UndecoratedSmoothedPWDB
= UndecoratedSmoothedPWDB
;
394 /* Endianness before calling this API */
395 static void ODM_PhyStatusQuery23a_92CSeries(struct dm_odm_t
*pDM_Odm
,
396 struct phy_info
*pPhyInfo
,
398 struct odm_packet_info
*pPktinfo
)
400 odm_RxPhyStatus92CSeries_Parsing(pDM_Odm
, pPhyInfo
,
401 pPhyStatus
, pPktinfo
);
402 if (pDM_Odm
->RSSI_test
) {
403 /* Select the packets to do RSSI checking for antenna switching. */
404 if (pPktinfo
->bPacketToSelf
|| pPktinfo
->bPacketBeacon
)
405 ODM_SwAntDivChkPerPktRssi(pDM_Odm
, pPktinfo
->StationID
, pPhyInfo
);
407 odm_Process_RSSIForDM(pDM_Odm
, pPhyInfo
, pPktinfo
);
411 void ODM_PhyStatusQuery23a(struct dm_odm_t
*pDM_Odm
, struct phy_info
*pPhyInfo
,
412 u8
*pPhyStatus
, struct odm_packet_info
*pPktinfo
)
414 ODM_PhyStatusQuery23a_92CSeries(pDM_Odm
, pPhyInfo
, pPhyStatus
, pPktinfo
);