WiFi: add rtl8189es/etv support, Optimization wifi configuration.
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8189es / hal / rtl8188e / rtl8188e_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 _RTL8188E_REDESC_C_
21
22 #include <drv_types.h>
23 #include <rtl8188e_hal.h>
24
25 static s32  translate2dbm(u8 signal_strength_idx)
26 {
27         s32     signal_power; // in dBm.
28
29
30         // Translate to dBm (x=0.5y-95).
31         signal_power = (s32)((signal_strength_idx + 1) >> 1);
32         signal_power -= 95;
33
34         return signal_power;
35 }
36
37
38 static void process_rssi(_adapter *padapter,union recv_frame *prframe)
39 {
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
45
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)
48         {
49         
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;
55                 }
56
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
61         
62                 //Adapter->RxStats.RssiCalculateCnt++;  //For antenna Test
63                 if(padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX)
64                 {
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;
68                 }
69                 padapter->recvpriv.signal_strength_data.total_val  +=pattrib->phy_info.SignalStrength;
70
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;
74
75
76                 tmp_val = padapter->recvpriv.signal_strength_data.total_val/padapter->recvpriv.signal_strength_data.total_num;
77                 
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);
81                 } else {
82                         padapter->recvpriv.signal_strength= tmp_val;
83                         padapter->recvpriv.rssi=(s8)translate2dbm((u8)tmp_val);
84                 }
85
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
88         }
89
90 }// Process_UI_RSSI_8192C
91
92
93
94 static void process_link_qual(_adapter *padapter,union recv_frame *prframe)
95 {
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
101
102         if(prframe == NULL || padapter==NULL){
103                 return;
104         }
105
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
110
111         //DBG_8192C("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual);
112
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;
118         }
119
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;
123         
124 #else //CONFIG_NEW_SIGNAL_STAT_PROCESS
125         if(pattrib->phy_info.SignalQuality != 0)
126         {
127                         //
128                         // 1. Record the general EVM to the sliding window.
129                         //
130                         if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX)
131                         {
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;
135                         }
136                         padapter->recvpriv.signal_qual_data.total_val += pattrib->phy_info.SignalQuality;
137
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;
141
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));
143
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;
147
148         }
149         else
150         {
151                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" pattrib->signal_qual =%d\n", pattrib->phy_info.SignalQuality));
152         }
153 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
154
155 }
156
157 //void rtl8188e_process_phy_info(_adapter *padapter, union recv_frame *prframe)
158 void rtl8188e_process_phy_info(_adapter *padapter, void *prframe)
159 {
160         union recv_frame *precvframe = (union recv_frame *)prframe;
161
162         //
163         // Check RSSI
164         //
165         process_rssi(padapter, precvframe);
166         //
167         // Check PWDB.
168         //
169         //process_PWDB(padapter, precvframe); 
170
171         //UpdateRxSignalStatistics8192C(Adapter, pRfd);
172         //
173         // Check EVM
174         //
175         process_link_qual(padapter,  precvframe);
176         #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
177         rtw_store_phy_info( padapter,prframe);
178         #endif
179         
180
181 }
182
183
184 void update_recvframe_attrib_88e(
185         union recv_frame *precvframe,
186         struct recv_stat *prxstat)
187 {
188         struct rx_pkt_attrib    *pattrib;
189         struct recv_stat        report;
190         PRXREPORT               prxreport;
191         //struct recv_frame_hdr *phdr;
192
193         //phdr = &precvframe->u.hdr;
194
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);
201
202         prxreport = (PRXREPORT)&report;
203
204         pattrib = &precvframe->u.hdr.attrib;
205         _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
206
207         pattrib->crc_err = (u8)((report.rxdw0 >> 14) & 0x1);;//(u8)prxreport->crc32;    
208         
209         // update rx report to recv_frame attribute
210         pattrib->pkt_rpt_type = (u8)((report.rxdw3 >> 14) & 0x3);//prxreport->rpt_sel;
211         
212         if(pattrib->pkt_rpt_type == NORMAL_RX)//Normal rx packet        
213         {
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);
216                         
217                 pattrib->physt =  (u8)((report.rxdw0 >> 26) & 0x1);//(u8)prxreport->physt;      
218
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;
221
222                 pattrib->qos = (u8)((report.rxdw0 >> 23) & 0x1);//(u8)prxreport->qos;
223                 pattrib->priority = (u8)((report.rxdw1 >> 8) & 0xf);//(u8)prxreport->tid;
224
225                 pattrib->amsdu = (u8)((report.rxdw1 >> 13) & 0x1);//(u8)prxreport->amsdu;
226
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;
231
232                 pattrib->data_rate = (u8)(report.rxdw3 & 0x3f);//(u8)prxreport->rxmcs;
233                 
234                 pattrib->icv_err = (u8)((report.rxdw0 >> 15) & 0x1);//(u8)prxreport->icverr;
235                 pattrib->shift_sz = (u8)((report.rxdw0 >> 24) & 0x3);
236         
237         }
238         else if(pattrib->pkt_rpt_type == TX_REPORT1)//CCX
239         {
240                 pattrib->pkt_len = TX_RPT1_PKT_LEN;
241                 pattrib->drvinfo_sz = 0;
242         }
243         else if(pattrib->pkt_rpt_type == TX_REPORT2)// TX RPT
244         {
245                 pattrib->pkt_len =(u16)(report.rxdw0 & 0x3FF);//Rx length[9:0]
246                 pattrib->drvinfo_sz = 0;
247
248                 //
249                 // Get TX report MAC ID valid.
250                 //
251                 pattrib->MacIDValidEntry[0] = report.rxdw4;
252                 pattrib->MacIDValidEntry[1] = report.rxdw5;
253                 
254         }
255         else if(pattrib->pkt_rpt_type == HIS_REPORT)// USB HISR RPT
256         {
257                 pattrib->pkt_len = (u16)(report.rxdw0 &0x00003fff);//(u16)prxreport->pktlen;
258         }       
259         
260 }
261
262 /*
263  * Notice:
264  *      Before calling this function,
265  *      precvframe->u.hdr.rx_data should be ready!
266  */
267 void update_recvframe_phyinfo_88e(
268         union recv_frame        *precvframe,
269         struct phy_stat *pphy_status)
270 {
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);
275         u8                                      *wlanhdr;
276         ODM_PACKET_INFO_T       pkt_info;
277         u8 *sa = NULL;
278         struct sta_priv *pstapriv;
279         struct sta_info *psta;
280         //_irqL         irqL;
281         
282         pkt_info.bPacketMatchBSSID =_FALSE;
283         pkt_info.bPacketToSelf = _FALSE;
284         pkt_info.bPacketBeacon = _FALSE;
285         
286         wlanhdr = get_recvframe_data(precvframe);
287
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));
291
292         pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN));
293
294         pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON);
295
296 /*
297         if(pkt_info.bPacketBeacon){
298                 if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){                            
299                         sa = padapter->mlmepriv.cur_network.network.MacAddress;
300                         #if 0
301                         {                                       
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]);                                   
304                         }
305                         #endif
306                 }
307                 else
308                 {
309                         //to do Ad-hoc
310                         sa = NULL;
311                 }
312         }
313         else{   
314                 sa = get_sa(wlanhdr);           
315         }       
316 */      
317         sa = get_ta(wlanhdr);   
318         
319         pstapriv = &padapter->stapriv;
320         pkt_info.StationID = 0xFF;
321         psta = rtw_get_stainfo(pstapriv, sa);
322         if (psta)
323         {
324                 pkt_info.StationID = psta->mac_id;              
325                 //DBG_8192C("%s ==> StationID(%d)\n",__FUNCTION__,pkt_info.StationID);
326         }                       
327         pkt_info.DataRate = pattrib->data_rate; 
328         //rtl8188e_query_rx_phy_status(precvframe, pphy_status);
329
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);
333
334         precvframe->u.hdr.psta = NULL;
335         if (pkt_info.bPacketMatchBSSID &&
336                 (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE))
337         {               
338                 if (psta)
339                 {                       
340                         precvframe->u.hdr.psta = psta;
341                         rtl8188e_process_phy_info(padapter, precvframe);
342                         
343                 }               
344         }
345         else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon)
346         {
347                 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)
348                 {               
349                         if (psta)
350                         {                               
351                                 precvframe->u.hdr.psta = psta;
352                         }
353                 }
354                 rtl8188e_process_phy_info(padapter, precvframe);                
355         }
356 }
357