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 * 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
19 ******************************************************************************/
20 #define _RTL8188E_REDESC_C_
22 #include <drv_types.h>
23 #include <rtl8188e_hal.h>
25 static s32 translate2dbm(u8 signal_strength_idx)
27 s32 signal_power; // in dBm.
30 // Translate to dBm (x=0.5y-95).
31 signal_power = (s32)((signal_strength_idx + 1) >> 1);
38 static void process_rssi(_adapter *padapter,union recv_frame *prframe)
40 u32 last_rssi, tmp_val;
41 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
42 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
43 struct signal_stat * signal_stat = &padapter->recvpriv.signal_strength_data;
44 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
46 //DBG_8192C("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->RecvSignalPower,pattrib->signal_strength);
47 //if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon)
50 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
51 if(signal_stat->update_req) {
52 signal_stat->total_num = 0;
53 signal_stat->total_val = 0;
54 signal_stat->update_req = 0;
57 signal_stat->total_num++;
58 signal_stat->total_val += pattrib->phy_info.SignalStrength;
59 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
60 #else //CONFIG_NEW_SIGNAL_STAT_PROCESS
62 //Adapter->RxStats.RssiCalculateCnt++; //For antenna Test
63 if(padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX)
65 padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX;
66 last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index];
67 padapter->recvpriv.signal_strength_data.total_val -= last_rssi;
69 padapter->recvpriv.signal_strength_data.total_val +=pattrib->phy_info.SignalStrength;
71 padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->phy_info.SignalStrength;
72 if(padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX)
73 padapter->recvpriv.signal_strength_data.index = 0;
76 tmp_val = padapter->recvpriv.signal_strength_data.total_val/padapter->recvpriv.signal_strength_data.total_num;
78 if(padapter->recvpriv.is_signal_dbg) {
79 padapter->recvpriv.signal_strength= padapter->recvpriv.signal_strength_dbg;
80 padapter->recvpriv.rssi=(s8)translate2dbm((u8)padapter->recvpriv.signal_strength_dbg);
82 padapter->recvpriv.signal_strength= tmp_val;
83 padapter->recvpriv.rssi=(s8)translate2dbm((u8)tmp_val);
86 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));
87 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
90 }// Process_UI_RSSI_8192C
94 static void process_link_qual(_adapter *padapter,union recv_frame *prframe)
96 u32 last_evm=0, tmpVal;
97 struct rx_pkt_attrib *pattrib;
98 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
99 struct signal_stat * signal_stat;
100 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
102 if(prframe == NULL || padapter==NULL){
106 pattrib = &prframe->u.hdr.attrib;
107 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
108 signal_stat = &padapter->recvpriv.signal_qual_data;
109 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
111 //DBG_8192C("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual);
113 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
114 if(signal_stat->update_req) {
115 signal_stat->total_num = 0;
116 signal_stat->total_val = 0;
117 signal_stat->update_req = 0;
120 signal_stat->total_num++;
121 signal_stat->total_val += pattrib->phy_info.SignalQuality;
122 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
124 #else //CONFIG_NEW_SIGNAL_STAT_PROCESS
125 if(pattrib->phy_info.SignalQuality != 0)
128 // 1. Record the general EVM to the sliding window.
130 if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX)
132 padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
133 last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
134 padapter->recvpriv.signal_qual_data.total_val -= last_evm;
136 padapter->recvpriv.signal_qual_data.total_val += pattrib->phy_info.SignalQuality;
138 padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->phy_info.SignalQuality;
139 if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
140 padapter->recvpriv.signal_qual_data.index = 0;
142 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Total SQ=%d pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, pattrib->phy_info.SignalQuality));
144 // <1> Showed on UI for user, in percentage.
145 tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num;
146 padapter->recvpriv.signal_qual=(u8)tmpVal;
151 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" pattrib->signal_qual =%d\n", pattrib->phy_info.SignalQuality));
153 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
157 //void rtl8188e_process_phy_info(_adapter *padapter, union recv_frame *prframe)
158 void rtl8188e_process_phy_info(_adapter *padapter, void *prframe)
160 union recv_frame *precvframe = (union recv_frame *)prframe;
165 process_rssi(padapter, precvframe);
169 //process_PWDB(padapter, precvframe);
171 //UpdateRxSignalStatistics8192C(Adapter, pRfd);
175 process_link_qual(padapter, precvframe);
176 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
177 rtw_store_phy_info( padapter,prframe);
184 void update_recvframe_attrib_88e(
185 union recv_frame *precvframe,
186 struct recv_stat *prxstat)
188 struct rx_pkt_attrib *pattrib;
189 struct recv_stat report;
191 //struct recv_frame_hdr *phdr;
193 //phdr = &precvframe->u.hdr;
195 report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
196 report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
197 report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
198 report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
199 report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
200 report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
202 prxreport = (PRXREPORT)&report;
204 pattrib = &precvframe->u.hdr.attrib;
205 _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
207 pattrib->crc_err = (u8)((report.rxdw0 >> 14) & 0x1);;//(u8)prxreport->crc32;
209 // update rx report to recv_frame attribute
210 pattrib->pkt_rpt_type = (u8)((report.rxdw3 >> 14) & 0x3);//prxreport->rpt_sel;
212 if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet
214 pattrib->pkt_len = (u16)(report.rxdw0 &0x00003fff);//(u16)prxreport->pktlen;
215 pattrib->drvinfo_sz = (u8)((report.rxdw0 >> 16) & 0xf) * 8;//(u8)(prxreport->drvinfosize << 3);
217 pattrib->physt = (u8)((report.rxdw0 >> 26) & 0x1);//(u8)prxreport->physt;
219 pattrib->bdecrypted = (report.rxdw0 & BIT(27))? 0:1;//(u8)(prxreport->swdec ? 0 : 1);
220 pattrib->encrypt = (u8)((report.rxdw0 >> 20) & 0x7);//(u8)prxreport->security;
222 pattrib->qos = (u8)((report.rxdw0 >> 23) & 0x1);//(u8)prxreport->qos;
223 pattrib->priority = (u8)((report.rxdw1 >> 8) & 0xf);//(u8)prxreport->tid;
225 pattrib->amsdu = (u8)((report.rxdw1 >> 13) & 0x1);//(u8)prxreport->amsdu;
227 pattrib->seq_num = (u16)(report.rxdw2 & 0x00000fff);//(u16)prxreport->seq;
228 pattrib->frag_num = (u8)((report.rxdw2 >> 12) & 0xf);//(u8)prxreport->frag;
229 pattrib->mfrag = (u8)((report.rxdw1 >> 27) & 0x1);//(u8)prxreport->mf;
230 pattrib->mdata = (u8)((report.rxdw1 >> 26) & 0x1);//(u8)prxreport->md;
232 pattrib->data_rate = (u8)(report.rxdw3 & 0x3f);//(u8)prxreport->rxmcs;
234 pattrib->icv_err = (u8)((report.rxdw0 >> 15) & 0x1);//(u8)prxreport->icverr;
235 pattrib->shift_sz = (u8)((report.rxdw0 >> 24) & 0x3);
238 else if(pattrib->pkt_rpt_type == TX_REPORT1)//CCX
240 pattrib->pkt_len = TX_RPT1_PKT_LEN;
241 pattrib->drvinfo_sz = 0;
243 else if(pattrib->pkt_rpt_type == TX_REPORT2)// TX RPT
245 pattrib->pkt_len =(u16)(report.rxdw0 & 0x3FF);//Rx length[9:0]
246 pattrib->drvinfo_sz = 0;
249 // Get TX report MAC ID valid.
251 pattrib->MacIDValidEntry[0] = report.rxdw4;
252 pattrib->MacIDValidEntry[1] = report.rxdw5;
255 else if(pattrib->pkt_rpt_type == HIS_REPORT)// USB HISR RPT
257 pattrib->pkt_len = (u16)(report.rxdw0 &0x00003fff);//(u16)prxreport->pktlen;
264 * Before calling this function,
265 * precvframe->u.hdr.rx_data should be ready!
267 void update_recvframe_phyinfo_88e(
268 union recv_frame *precvframe,
269 struct phy_stat *pphy_status)
271 PADAPTER padapter = precvframe->u.hdr.adapter;
272 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
273 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
274 PODM_PHY_INFO_T pPHYInfo = (PODM_PHY_INFO_T)(&pattrib->phy_info);
276 ODM_PACKET_INFO_T pkt_info;
278 struct sta_priv *pstapriv;
279 struct sta_info *psta;
282 pkt_info.bPacketMatchBSSID =_FALSE;
283 pkt_info.bPacketToSelf = _FALSE;
284 pkt_info.bPacketBeacon = _FALSE;
286 wlanhdr = get_recvframe_data(precvframe);
288 pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) &&
289 !pattrib->icv_err && !pattrib->crc_err &&
290 _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN));
292 pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN));
294 pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON);
297 if(pkt_info.bPacketBeacon){
298 if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){
299 sa = padapter->mlmepriv.cur_network.network.MacAddress;
302 DBG_8192C("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n",
303 sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]);
314 sa = get_sa(wlanhdr);
317 sa = get_ta(wlanhdr);
319 pstapriv = &padapter->stapriv;
320 pkt_info.StationID = 0xFF;
321 psta = rtw_get_stainfo(pstapriv, sa);
324 pkt_info.StationID = psta->mac_id;
325 //DBG_8192C("%s ==> StationID(%d)\n",__FUNCTION__,pkt_info.StationID);
327 pkt_info.DataRate = pattrib->data_rate;
328 //rtl8188e_query_rx_phy_status(precvframe, pphy_status);
330 //_enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
331 ODM_PhyStatusQuery(&pHalData->odmpriv,pPHYInfo,(u8 *)pphy_status,&(pkt_info));
332 //_exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL);
334 precvframe->u.hdr.psta = NULL;
335 if (pkt_info.bPacketMatchBSSID &&
336 (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE))
340 precvframe->u.hdr.psta = psta;
341 rtl8188e_process_phy_info(padapter, precvframe);
345 else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon)
347 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)
351 precvframe->u.hdr.psta = psta;
354 rtl8188e_process_phy_info(padapter, precvframe);