]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/net/wireless/realtek/rtl8192cu/hal/rtl8192c/rtl8192c_rxdesc.c
net: Add non-mainline source for rtl8192cu wlan
[mirror_ubuntu-zesty-kernel.git] / drivers / net / wireless / realtek / rtl8192cu / hal / rtl8192c / rtl8192c_rxdesc.c
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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17 *
18 *
19 ******************************************************************************/
20 #define _RTL8192C_REDESC_C_
21 #include <drv_conf.h>
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <rtl8192c_hal.h>
25
26 static u8 evm_db2percentage(s8 value)
27 {
28 //
29 // -33dB~0dB to 0%~99%
30 //
31 s8 ret_val;
32
33 ret_val = value;
34 //ret_val /= 2;
35
36 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("EVMdbToPercentage92S Value=%d / %x \n", ret_val, ret_val));
37
38 if(ret_val >= 0)
39 ret_val = 0;
40 if(ret_val <= -33)
41 ret_val = -33;
42
43 ret_val = 0 - ret_val;
44 ret_val*=3;
45
46 if(ret_val == 99)
47 ret_val = 100;
48
49 return(ret_val);
50 }
51
52
53 static s32 signal_scale_mapping(_adapter *padapter, s32 cur_sig )
54 {
55 s32 ret_sig;
56
57 #ifdef CONFIG_USB_HCI
58 if(cur_sig >= 51 && cur_sig <= 100)
59 {
60 ret_sig = 100;
61 }
62 else if(cur_sig >= 41 && cur_sig <= 50)
63 {
64 ret_sig = 80 + ((cur_sig - 40)*2);
65 }
66 else if(cur_sig >= 31 && cur_sig <= 40)
67 {
68 ret_sig = 66 + (cur_sig - 30);
69 }
70 else if(cur_sig >= 21 && cur_sig <= 30)
71 {
72 ret_sig = 54 + (cur_sig - 20);
73 }
74 else if(cur_sig >= 10 && cur_sig <= 20)
75 {
76 ret_sig = 42 + (((cur_sig - 10) * 2) / 3);
77 }
78 else if(cur_sig >= 5 && cur_sig <= 9)
79 {
80 ret_sig = 22 + (((cur_sig - 5) * 3) / 2);
81 }
82 else if(cur_sig >= 1 && cur_sig <= 4)
83 {
84 ret_sig = 6 + (((cur_sig - 1) * 3) / 2);
85 }
86 else
87 {
88 ret_sig = cur_sig;
89 }
90 #else
91 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
92
93 if(pHalData->CustomerID == RT_CID_819x_Lenovo)
94 {
95 // Step 1. Scale mapping.
96 // 20100611 Joseph: Re-tunning RSSI presentation for Lenovo.
97 // 20100426 Joseph: Modify Signal strength mapping.
98 // This modification makes the RSSI indication similar to Intel solution.
99 // 20100414 Joseph: Tunning RSSI for Lenovo according to RTL8191SE.
100 if(cur_sig >= 54 && cur_sig <= 100)
101 {
102 ret_sig = 100;
103 }
104 else if(cur_sig>=42 && cur_sig <= 53 )
105 {
106 ret_sig = 95;
107 }
108 else if(cur_sig>=36 && cur_sig <= 41 )
109 {
110 ret_sig = 74 + ((cur_sig - 36) *20)/6;
111 }
112 else if(cur_sig>=33 && cur_sig <= 35 )
113 {
114 ret_sig = 65 + ((cur_sig - 33) *8)/2;
115 }
116 else if(cur_sig>=18 && cur_sig <= 32 )
117 {
118 ret_sig = 62 + ((cur_sig - 18) *2)/15;
119 }
120 else if(cur_sig>=15 && cur_sig <= 17 )
121 {
122 ret_sig = 33 + ((cur_sig - 15) *28)/2;
123 }
124 else if(cur_sig>=10 && cur_sig <= 14 )
125 {
126 ret_sig = 39;
127 }
128 else if(cur_sig>=8 && cur_sig <= 9 )
129 {
130 ret_sig = 33;
131 }
132 else if(cur_sig <= 8 )
133 {
134 ret_sig = 19;
135 }
136 }
137 else
138 {
139 // Step 1. Scale mapping.
140 if(cur_sig >= 61 && cur_sig <= 100)
141 {
142 ret_sig = 90 + ((cur_sig - 60) / 4);
143 }
144 else if(cur_sig >= 41 && cur_sig <= 60)
145 {
146 ret_sig = 78 + ((cur_sig - 40) / 2);
147 }
148 else if(cur_sig >= 31 && cur_sig <= 40)
149 {
150 ret_sig = 66 + (cur_sig - 30);
151 }
152 else if(cur_sig >= 21 && cur_sig <= 30)
153 {
154 ret_sig = 54 + (cur_sig - 20);
155 }
156 else if(cur_sig >= 5 && cur_sig <= 20)
157 {
158 ret_sig = 42 + (((cur_sig - 5) * 2) / 3);
159 }
160 else if(cur_sig == 4)
161 {
162 ret_sig = 36;
163 }
164 else if(cur_sig == 3)
165 {
166 ret_sig = 27;
167 }
168 else if(cur_sig == 2)
169 {
170 ret_sig = 18;
171 }
172 else if(cur_sig == 1)
173 {
174 ret_sig = 9;
175 }
176 else
177 {
178 ret_sig = cur_sig;
179 }
180 }
181 #endif
182
183 return ret_sig;
184 }
185
186
187 static s32 translate2dbm(u8 signal_strength_idx)
188 {
189 s32 signal_power; // in dBm.
190
191
192 // Translate to dBm (x=0.5y-95).
193 signal_power = (s32)((signal_strength_idx + 1) >> 1);
194 signal_power -= 95;
195
196 return signal_power;
197 }
198
199 static void query_rx_phy_status(union recv_frame *prframe, struct phy_stat *pphy_stat)
200 {
201 PHY_STS_OFDM_8192CD_T *pOfdm_buf;
202 PHY_STS_CCK_8192CD_T *pCck_buf;
203 u8 i, max_spatial_stream, evm;
204 s8 rx_pwr[4], rx_pwr_all = 0;
205 u8 pwdb_all;
206 u32 rssi,total_rssi=0;
207 u8 bcck_rate=0, rf_rx_num = 0, cck_highpwr = 0;
208 _adapter *padapter = prframe->u.hdr.adapter;
209 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
210 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
211 struct dm_priv *pdmpriv = &pHalData->dmpriv;
212 u8 tmp_rxsnr;
213 s8 rx_snrX;
214
215 #ifdef CONFIG_HW_ANTENNA_DIVERSITY
216 PHY_RX_DRIVER_INFO_8192CD *pDrvInfo = ((PHY_RX_DRIVER_INFO_8192CD *)pphy_stat);
217 u8 bant1_sel = (pDrvInfo->ANTSEL == 1)?_TRUE:_FALSE;
218 #endif
219
220 // Record it for next packet processing
221 bcck_rate=(pattrib->mcs_rate<=3? 1:0);
222
223 if(bcck_rate) //CCK
224 {
225 u8 report;
226 #ifdef CONFIG_HW_ANTENNA_DIVERSITY
227 if(bant1_sel == _TRUE)
228 pHalData->CCK_Ant1_Cnt++;
229 else
230 pHalData->CCK_Ant2_Cnt++;
231 #endif
232
233 // CCK Driver info Structure is not the same as OFDM packet.
234 pCck_buf = (PHY_STS_CCK_8192CD_T *)pphy_stat;
235 //Adapter->RxStats.NumQryPhyStatusCCK++;
236
237 //
238 // (1)Hardware does not provide RSSI for CCK
239 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive)
240 //
241
242 if(padapter->pwrctrlpriv.rf_pwrstate == rf_on)
243 cck_highpwr = (u8)pHalData->bCckHighPower;
244 else
245 cck_highpwr = _FALSE;
246
247 if(!cck_highpwr)
248 {
249 report = pCck_buf->cck_agc_rpt&0xc0;
250 report = report>>6;
251 switch(report)
252 {
253 // 03312009 modified by cosa
254 // Modify the RF RNA gain value to -40, -20, -2, 14 by Jenyu's suggestion
255 // Note: different RF with the different RNA gain.
256 case 0x3:
257 rx_pwr_all = (-46) - (pCck_buf->cck_agc_rpt & 0x3e);
258 break;
259 case 0x2:
260 rx_pwr_all = (-26) - (pCck_buf->cck_agc_rpt & 0x3e);
261 break;
262 case 0x1:
263 rx_pwr_all = (-12) - (pCck_buf->cck_agc_rpt & 0x3e);
264 break;
265 case 0x0:
266 rx_pwr_all = (16) - (pCck_buf->cck_agc_rpt & 0x3e);
267 break;
268 }
269 }
270 else
271 {
272 report = pCck_buf->cck_agc_rpt & 0x60;
273 report = report>>5;
274 switch(report)
275 {
276 case 0x3:
277 rx_pwr_all = (-46) - ((pCck_buf->cck_agc_rpt & 0x1f)<<1) ;
278 break;
279 case 0x2:
280 rx_pwr_all = (-26)- ((pCck_buf->cck_agc_rpt & 0x1f)<<1);
281 break;
282 case 0x1:
283 rx_pwr_all = (-12) - ((pCck_buf->cck_agc_rpt & 0x1f)<<1) ;
284 break;
285 case 0x0:
286 rx_pwr_all = (16) - ((pCck_buf->cck_agc_rpt & 0x1f)<<1) ;
287 break;
288 }
289 }
290
291 pwdb_all= query_rx_pwr_percentage(rx_pwr_all);
292 if(pHalData->CustomerID == RT_CID_819x_Lenovo)
293 {
294 // CCK gain is smaller than OFDM/MCS gain,
295 // so we add gain diff by experiences, the val is 6
296 pwdb_all+=6;
297 if(pwdb_all > 100)
298 pwdb_all = 100;
299 // modify the offset to make the same gain index with OFDM.
300 if(pwdb_all > 34 && pwdb_all <= 42)
301 pwdb_all -= 2;
302 else if(pwdb_all > 26 && pwdb_all <= 34)
303 pwdb_all -= 6;
304 else if(pwdb_all > 14 && pwdb_all <= 26)
305 pwdb_all -= 8;
306 else if(pwdb_all > 4 && pwdb_all <= 14)
307 pwdb_all -= 4;
308 }
309
310 pattrib->RxPWDBAll = pwdb_all; //for DIG/rate adaptive
311 pattrib->RecvSignalPower = rx_pwr_all; //dBM
312 padapter->recvpriv.rxpwdb = rx_pwr_all;
313 //
314 // (3) Get Signal Quality (EVM)
315 //
316 //if(bPacketMatchBSSID)
317 {
318 u8 sq;
319
320 if(pHalData->CustomerID == RT_CID_819x_Lenovo)
321 {
322 // mapping to 5 bars for vista signal strength
323 // signal quality in driver will be displayed to signal strength
324 // in vista.
325 if(pwdb_all >= 50)
326 sq = 100;
327 else if(pwdb_all >= 35 && pwdb_all < 50)
328 sq = 80;
329 else if(pwdb_all >= 22 && pwdb_all < 35)
330 sq = 60;
331 else if(pwdb_all >= 18 && pwdb_all < 22)
332 sq = 40;
333 else
334 sq = 20;
335 }
336 else
337 {
338 if(pwdb_all> 40)
339 {
340 sq = 100;
341 }
342 else
343 {
344 sq = pCck_buf->SQ_rpt;
345
346 if(pCck_buf->SQ_rpt > 64)
347 sq = 0;
348 else if (pCck_buf->SQ_rpt < 20)
349 sq= 100;
350 else
351 sq = ((64-sq) * 100) / 44;
352
353 }
354 }
355
356 pattrib->signal_qual=sq;
357 pattrib->rx_mimo_signal_qual[0]=sq;
358 pattrib->rx_mimo_signal_qual[1]=(-1);
359 }
360
361 }
362 else //OFDM/HT
363 {
364 #ifdef CONFIG_HW_ANTENNA_DIVERSITY
365 if(bant1_sel == _TRUE)
366 pHalData->OFDM_Ant1_Cnt++;
367 else
368 pHalData->OFDM_Ant2_Cnt++;
369 #endif
370 pdmpriv->OFDM_Pkt_Cnt++;
371
372 pOfdm_buf = (PHY_STS_OFDM_8192CD_T *)pphy_stat;
373
374 //
375 // (1)Get RSSI per-path
376 //
377 for(i=0; i<pHalData->NumTotalRFPath; i++)
378 {
379 // 2008/01/30 MH we will judge RF RX path now.
380 if (pHalData->bRFPathRxEnable[i])
381 rf_rx_num++;
382 //else
383 //continue;
384
385 rx_pwr[i] = ((pOfdm_buf->trsw_gain_X[i]&0x3F)*2) - 110;
386 padapter->recvpriv.RxRssi[i] = rx_pwr[i];
387 /* Translate DBM to percentage. */
388 pattrib->rx_rssi[i] = rssi = query_rx_pwr_percentage(rx_pwr[i]);
389 total_rssi += rssi;
390
391 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("RF-%d RXPWR=%x RSSI=%d\n", i, rx_pwr[i], rssi));
392
393 //Get Rx snr value in DB
394 tmp_rxsnr = pOfdm_buf->rxsnr_X[i];
395 rx_snrX = (s8)(tmp_rxsnr);
396 rx_snrX >>= 1;
397 padapter->recvpriv.RxSNRdB[i] = (int)rx_snrX;
398 pattrib->rx_snr[i]=pOfdm_buf->rxsnr_X[i];
399 /* Record Signal Strength for next packet */
400 //if(bPacketMatchBSSID)
401 {
402 //pRfd->Status.RxMIMOSignalStrength[i] =(u1Byte) RSSI;
403
404 //The following is for lenovo signal strength in vista
405 if(pHalData->CustomerID == RT_CID_819x_Lenovo)
406 {
407 u8 sq;
408
409 if(i == 0)
410 {
411 // mapping to 5 bars for vista signal strength
412 // signal quality in driver will be displayed to signal strength
413 // in vista.
414 if(rssi >= 50)
415 sq = 100;
416 else if(rssi >= 35 && rssi < 50)
417 sq = 80;
418 else if(rssi >= 22 && rssi < 35)
419 sq = 60;
420 else if(rssi >= 18 && rssi < 22)
421 sq = 40;
422 else
423 sq = 20;
424 //DbgPrint("ofdm/mcs RSSI=%d\n", RSSI);
425 //pRfd->Status.SignalQuality = SQ;
426 //DbgPrint("ofdm/mcs SQ = %d\n", pRfd->Status.SignalQuality);
427 }
428 }
429 }
430 }
431
432
433 //
434 // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive),average
435 //
436 rx_pwr_all = (((pOfdm_buf->pwdb_all ) >> 1 )& 0x7f) -110;//for OFDM Average RSSI
437 pwdb_all = query_rx_pwr_percentage(rx_pwr_all);
438
439 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("PWDB_ALL=%d\n", pwdb_all));
440
441 pattrib->RxPWDBAll = pwdb_all; //for DIG/rate adaptive
442 pattrib->RecvSignalPower = rx_pwr_all;//dBM
443 padapter->recvpriv.rxpwdb = rx_pwr_all;
444 //
445 // (3)EVM of HT rate
446 //
447 if(pHalData->CustomerID != RT_CID_819x_Lenovo)
448 {
449 if(pattrib->rxht && pattrib->mcs_rate >=20 && pattrib->mcs_rate<=27)
450 max_spatial_stream = 2; //both spatial stream make sense
451 else
452 max_spatial_stream = 1; //only spatial stream 1 makes sense
453
454 for(i=0; i<max_spatial_stream; i++)
455 {
456 // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment
457 // fill most significant bit to "zero" when doing shifting operation which may change a negative
458 // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore.
459 evm = evm_db2percentage( (pOfdm_buf->rxevm_X[i]/*/ 2*/));//dbm
460
461 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("RXRATE=%x RXEVM=%x EVM=%s%d\n",
462 pattrib->mcs_rate, pOfdm_buf->rxevm_X[i], "%",evm));
463
464 //if(bPacketMatchBSSID)
465 {
466 if(i==0) // Fill value in RFD, Get the first spatial stream only
467 {
468 pattrib->signal_qual = (u8)(evm & 0xff);
469 }
470 pattrib->rx_mimo_signal_qual[i] = (u8)(evm & 0xff);
471 }
472 }
473
474 }
475
476 //
477 // 4. Record rx statistics for debug
478 //
479
480 }
481
482
483 //UI BSS List signal strength(in percentage), make it good looking, from 0~100.
484 //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp().
485 if(bcck_rate)
486 {
487 pattrib->signal_strength=(u8)signal_scale_mapping(padapter, pwdb_all);
488 }
489 else
490 {
491 if (rf_rx_num != 0)
492 {
493 pattrib->signal_strength= (u8)(signal_scale_mapping(padapter, total_rssi/=rf_rx_num));
494 }
495 }
496 //DBG_8192C("%s,rx_pwr_all(%d),RxPWDBAll(%d)\n",__FUNCTION__,rx_pwr_all,pattrib->RxPWDBAll);
497
498 }
499
500
501 static void process_rssi(_adapter *padapter,union recv_frame *prframe)
502 {
503 u32 last_rssi, tmp_val;
504 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
505 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
506 struct signal_stat * signal_stat = &padapter->recvpriv.signal_strength_data;
507 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
508
509 //DBG_8192C("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->RecvSignalPower,pattrib->signal_strength);
510 //if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon)
511 {
512
513 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
514 if(signal_stat->update_req) {
515 signal_stat->total_num = 0;
516 signal_stat->total_val = 0;
517 signal_stat->update_req = 0;
518 }
519
520 signal_stat->total_num++;
521 signal_stat->total_val += pattrib->signal_strength;
522 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
523 #else //CONFIG_NEW_SIGNAL_STAT_PROCESS
524
525 //Adapter->RxStats.RssiCalculateCnt++; //For antenna Test
526 if(padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX)
527 {
528 padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX;
529 last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index];
530 padapter->recvpriv.signal_strength_data.total_val -= last_rssi;
531 }
532 padapter->recvpriv.signal_strength_data.total_val +=pattrib->signal_strength;
533
534 padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->signal_strength;
535 if(padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX)
536 padapter->recvpriv.signal_strength_data.index = 0;
537
538
539 tmp_val = padapter->recvpriv.signal_strength_data.total_val/padapter->recvpriv.signal_strength_data.total_num;
540
541 if(padapter->recvpriv.is_signal_dbg) {
542 padapter->recvpriv.signal_strength= padapter->recvpriv.signal_strength_dbg;
543 padapter->recvpriv.rssi=(s8)translate2dbm((u8)padapter->recvpriv.signal_strength_dbg);
544 } else {
545 padapter->recvpriv.signal_strength= tmp_val;
546 padapter->recvpriv.rssi=(s8)translate2dbm((u8)tmp_val);
547 }
548
549 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("UI RSSI = %d, ui_rssi.TotalVal = %d, ui_rssi.TotalNum = %d\n", tmp_val, padapter->recvpriv.signal_strength_data.total_val,padapter->recvpriv.signal_strength_data.total_num));
550 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
551 }
552
553 }// Process_UI_RSSI_8192C
554
555
556 static void process_PWDB(_adapter *padapter, union recv_frame *prframe)
557 {
558 int UndecoratedSmoothedPWDB;
559 int UndecoratedSmoothedCCK;
560 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
561 struct dm_priv *pdmpriv = &pHalData->dmpriv;
562 struct rx_pkt_attrib *pattrib= &prframe->u.hdr.attrib;
563 struct sta_info *psta = prframe->u.hdr.psta;
564 u8 isCCKrate=(pattrib->mcs_rate<=3? 1:0);
565
566
567 if(psta)
568 {
569 UndecoratedSmoothedPWDB = psta->rssi_stat.UndecoratedSmoothedPWDB;
570 UndecoratedSmoothedCCK = psta->rssi_stat.UndecoratedSmoothedCCK;
571 }
572 else
573 {
574 UndecoratedSmoothedPWDB = pdmpriv->UndecoratedSmoothedPWDB;
575 UndecoratedSmoothedCCK = pdmpriv->UndecoratedSmoothedCCK;
576 }
577
578 //if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon)
579
580 if(!isCCKrate)
581 {
582 // Process OFDM RSSI
583 if(UndecoratedSmoothedPWDB < 0) // initialize
584 {
585 UndecoratedSmoothedPWDB = pattrib->RxPWDBAll;
586 }
587
588 if(pattrib->RxPWDBAll > (u32)UndecoratedSmoothedPWDB)
589 {
590 UndecoratedSmoothedPWDB =
591 ( ((UndecoratedSmoothedPWDB)*(Rx_Smooth_Factor-1)) +
592 (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor);
593
594 UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB + 1;
595 }
596 else
597 {
598 UndecoratedSmoothedPWDB =
599 ( ((UndecoratedSmoothedPWDB)*(Rx_Smooth_Factor-1)) +
600 (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor);
601 }
602 }
603 else
604 {
605 // Process CCK RSSI
606 if(UndecoratedSmoothedCCK < 0) // initialize
607 {
608 UndecoratedSmoothedCCK = pattrib->RxPWDBAll;
609 }
610
611 if(pattrib->RxPWDBAll > (u32)UndecoratedSmoothedCCK)
612 {
613 UndecoratedSmoothedCCK =
614 ( ((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) +
615 (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor);
616
617 UndecoratedSmoothedCCK = UndecoratedSmoothedCCK + 1;
618 }
619 else
620 {
621 UndecoratedSmoothedCCK =
622 ( ((UndecoratedSmoothedCCK)*(Rx_Smooth_Factor-1)) +
623 (pattrib->RxPWDBAll)) /(Rx_Smooth_Factor);
624 }
625 }
626
627
628 if(psta)
629 {
630 //psta->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;//todo:
631 pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
632
633 if(pdmpriv->RSSI_Select == RSSI_OFDM){
634 psta->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
635 }
636 else if(pdmpriv->RSSI_Select == RSSI_CCK){
637 psta->rssi_stat.UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK;
638 }
639 else{
640 if(UndecoratedSmoothedPWDB <0 )
641 pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK;
642 else
643 pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
644 }
645 psta->rssi_stat.UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
646 }
647 else
648 {
649 //pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
650
651 if(pdmpriv->RSSI_Select == RSSI_OFDM){
652 pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
653 }
654 else if(pdmpriv->RSSI_Select == RSSI_CCK){
655 pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK;
656 }
657 else {
658 if(UndecoratedSmoothedPWDB <0 )
659 pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedCCK;
660 else
661 pdmpriv->UndecoratedSmoothedPWDB = UndecoratedSmoothedPWDB;
662
663 }
664 pdmpriv->UndecoratedSmoothedCCK = UndecoratedSmoothedCCK;
665 }
666
667 //UpdateRxSignalStatistics8192C(padapter, prframe);
668
669 }
670
671
672 static void process_link_qual(_adapter *padapter,union recv_frame *prframe)
673 {
674 u32 last_evm=0, tmpVal;
675 struct rx_pkt_attrib *pattrib;
676 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
677 struct signal_stat * signal_stat;
678 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
679
680 if(prframe == NULL || padapter==NULL){
681 return;
682 }
683
684 pattrib = &prframe->u.hdr.attrib;
685 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
686 signal_stat = &padapter->recvpriv.signal_qual_data;
687 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
688
689 //DBG_8192C("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual);
690
691 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
692 if(signal_stat->update_req) {
693 signal_stat->total_num = 0;
694 signal_stat->total_val = 0;
695 signal_stat->update_req = 0;
696 }
697
698 signal_stat->total_num++;
699 signal_stat->total_val += pattrib->signal_qual;
700 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
701
702 #else //CONFIG_NEW_SIGNAL_STAT_PROCESS
703 if(pattrib->signal_qual != 0)
704 {
705 //
706 // 1. Record the general EVM to the sliding window.
707 //
708 if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX)
709 {
710 padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
711 last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
712 padapter->recvpriv.signal_qual_data.total_val -= last_evm;
713 }
714 padapter->recvpriv.signal_qual_data.total_val += pattrib->signal_qual;
715
716 padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->signal_qual;
717 if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
718 padapter->recvpriv.signal_qual_data.index = 0;
719
720 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, pattrib->signal_qual));
721
722 // <1> Showed on UI for user, in percentage.
723 tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num;
724 padapter->recvpriv.signal_qual=(u8)tmpVal;
725
726 }
727 else
728 {
729 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" pattrib->signal_qual =%d\n", pattrib->signal_qual));
730 }
731 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
732
733 }// Process_UiLinkQuality8192S
734
735
736 static void process_phy_info(_adapter *padapter, union recv_frame *prframe)
737 {
738 union recv_frame *precvframe = (union recv_frame *)prframe;
739
740 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
741 // If we switch to the antenna for testing, the signal strength
742 // of the packets in this time shall not be counted into total receiving power.
743 // This prevents error counting Rx signal strength and affecting other dynamic mechanism.
744
745 // Select the packets to do RSSI checking for antenna switching.
746 SwAntDivRSSICheck8192C(padapter, precvframe->u.hdr.attrib.RxPWDBAll);
747
748 if(GET_HAL_DATA(padapter)->RSSI_test == _TRUE)
749 return;
750 #endif
751 //
752 // Check RSSI
753 //
754 process_rssi(padapter, precvframe);
755 //
756 // Check PWDB.
757 //
758 process_PWDB(padapter, precvframe);
759 //
760 // Check EVM
761 //
762 process_link_qual(padapter, precvframe);
763
764 }
765
766
767 void rtl8192c_translate_rx_signal_stuff(union recv_frame *precvframe, struct phy_stat *pphy_info)
768 {
769 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
770 _adapter *padapter = precvframe->u.hdr.adapter;
771 u8 bPacketMatchBSSID =_FALSE;
772 u8 bPacketToSelf = _FALSE;
773 u8 bPacketBeacon = _FALSE;
774
775 if((pattrib->physt) && (pphy_info != NULL))
776 {
777 bPacketMatchBSSID = ((!IsFrameTypeCtrl(precvframe->u.hdr.rx_data)) && !(pattrib->icv_err) && !(pattrib->crc_err) &&
778 _rtw_memcmp(get_hdr_bssid(precvframe->u.hdr.rx_data), get_my_bssid(&padapter->mlmeextpriv.mlmext_info.network), ETH_ALEN));
779
780
781 bPacketToSelf = bPacketMatchBSSID && (_rtw_memcmp(get_da(precvframe->u.hdr.rx_data), myid(&padapter->eeprompriv), ETH_ALEN));
782
783 bPacketBeacon =bPacketMatchBSSID && (GetFrameSubType(precvframe->u.hdr.rx_data) == WIFI_BEACON);
784
785 query_rx_phy_status(precvframe, pphy_info);
786
787 precvframe->u.hdr.psta = NULL;
788 if(bPacketMatchBSSID && check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
789 {
790 u8 *sa;
791 struct sta_info *psta=NULL;
792 struct sta_priv *pstapriv = &padapter->stapriv;
793
794 sa = get_sa(precvframe->u.hdr.rx_data);
795
796 psta = rtw_get_stainfo(pstapriv, sa);
797 if(psta)
798 {
799 precvframe->u.hdr.psta = psta;
800 process_phy_info(padapter, precvframe);
801 }
802 }
803 else if(bPacketToSelf || bPacketBeacon)
804 {
805 if(check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)
806 {
807 u8 *sa;
808 struct sta_info *psta=NULL;
809 struct sta_priv *pstapriv = &padapter->stapriv;
810
811 sa = get_sa(precvframe->u.hdr.rx_data);
812
813 psta = rtw_get_stainfo(pstapriv, sa);
814 if(psta)
815 {
816 precvframe->u.hdr.psta = psta;
817 }
818 }
819
820 process_phy_info(padapter, precvframe);
821 }
822 }
823 }
824
825 void rtl8192c_query_rx_desc_status(union recv_frame *precvframe, struct recv_stat *pdesc)
826 {
827 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
828
829 //Offset 0
830 pattrib->physt = (u8)((le32_to_cpu(pdesc->rxdw0) >> 26) & 0x1);
831 pattrib->pkt_len = (u16)(le32_to_cpu(pdesc->rxdw0)&0x00003fff);
832 pattrib->drvinfo_sz = (u8)((le32_to_cpu(pdesc->rxdw0) >> 16) & 0xf) * 8;//uint 2^3 = 8 bytes
833
834 pattrib->shift_sz = (u8)((le32_to_cpu(pdesc->rxdw0) >> 24) & 0x3);
835
836 pattrib->crc_err = (u8)((le32_to_cpu(pdesc->rxdw0) >> 14) & 0x1);
837 pattrib->icv_err = (u8)((le32_to_cpu(pdesc->rxdw0) >> 15) & 0x1);
838 pattrib->qos = (u8)(( le32_to_cpu( pdesc->rxdw0 ) >> 23) & 0x1);// Qos data, wireless lan header length is 26
839 pattrib->bdecrypted = (le32_to_cpu(pdesc->rxdw0) & BIT(27))? 0:1;
840
841 //Offset 4
842 pattrib->mfrag = (u8)((le32_to_cpu(pdesc->rxdw1) >> 27) & 0x1);//more fragment bit
843
844 //Offset 8
845 pattrib->frag_num = (u8)((le32_to_cpu(pdesc->rxdw2) >> 12) & 0xf);//fragmentation number
846
847 //Offset 12
848 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
849 if ( le32_to_cpu(pdesc->rxdw3) & BIT(13)){
850 pattrib->tcpchk_valid = 1; // valid
851 if ( le32_to_cpu(pdesc->rxdw3) & BIT(11) ) {
852 pattrib->tcp_chkrpt = 1; // correct
853 //DBG_8192C("tcp csum ok\n");
854 }
855 else
856 pattrib->tcp_chkrpt = 0; // incorrect
857
858 if ( le32_to_cpu(pdesc->rxdw3) & BIT(12) )
859 pattrib->ip_chkrpt = 1; // correct
860 else
861 pattrib->ip_chkrpt = 0; // incorrect
862 }
863 else {
864 pattrib->tcpchk_valid = 0; // invalid
865 }
866 #endif
867
868 pattrib->mcs_rate=(u8)((le32_to_cpu(pdesc->rxdw3))&0x3f);
869 pattrib->rxht=(u8)((le32_to_cpu(pdesc->rxdw3) >>6)&0x1);
870 pattrib->sgi=(u8)((le32_to_cpu(pdesc->rxdw3) >>8)&0x1);
871 //Offset 16
872 //Offset 20
873
874 }