eedc8c20b4f940d038dfc25988442d087ed346f8
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bs / hal / rtl8723b / rtl8723b_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 _RTL8723B_REDESC_C_
21
22 #include <rtl8723b_hal.h>
23
24 static void process_rssi(_adapter *padapter,union recv_frame *prframe)
25 {
26         u32     last_rssi, tmp_val;
27         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
28 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
29         struct signal_stat * signal_stat = &padapter->recvpriv.signal_strength_data;
30 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
31
32         //DBG_8192C("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->RecvSignalPower,pattrib->signal_strength);
33         //if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon)
34         {
35
36         #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
37                 if(signal_stat->update_req) {
38                         signal_stat->total_num = 0;
39                         signal_stat->total_val = 0;
40                         signal_stat->update_req = 0;
41                 }
42
43                 signal_stat->total_num++;
44                 signal_stat->total_val  += pattrib->phy_info.SignalStrength;
45                 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
46         #else //CONFIG_NEW_SIGNAL_STAT_PROCESS
47
48                 //Adapter->RxStats.RssiCalculateCnt++;  //For antenna Test
49                 if(padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX)
50                 {
51                         padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX;
52                         last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index];
53                         padapter->recvpriv.signal_strength_data.total_val -= last_rssi;
54                 }
55                 padapter->recvpriv.signal_strength_data.total_val  +=pattrib->phy_info.SignalStrength;
56
57                 padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->phy_info.SignalStrength;
58                 if(padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX)
59                         padapter->recvpriv.signal_strength_data.index = 0;
60
61
62                 tmp_val = padapter->recvpriv.signal_strength_data.total_val/padapter->recvpriv.signal_strength_data.total_num;
63
64                 if(padapter->recvpriv.is_signal_dbg) {
65                         padapter->recvpriv.signal_strength= padapter->recvpriv.signal_strength_dbg;
66                         padapter->recvpriv.rssi=(s8)translate_percentage_to_dbm(padapter->recvpriv.signal_strength_dbg);
67                 } else {
68                         padapter->recvpriv.signal_strength= tmp_val;
69                         padapter->recvpriv.rssi=(s8)translate_percentage_to_dbm(tmp_val);
70                 }
71
72                 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));
73         #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
74         }
75
76 }// Process_UI_RSSI_8192C
77
78 static void process_link_qual(_adapter *padapter,union recv_frame *prframe)
79 {
80         u32     last_evm=0, tmpVal;
81         struct rx_pkt_attrib *pattrib;
82 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
83         struct signal_stat * signal_stat;
84 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
85
86         if(prframe == NULL || padapter==NULL){
87                 return;
88         }
89
90         pattrib = &prframe->u.hdr.attrib;
91 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
92         signal_stat = &padapter->recvpriv.signal_qual_data;
93 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
94
95         //DBG_8192C("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual);
96
97 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
98         if(signal_stat->update_req) {
99                 signal_stat->total_num = 0;
100                 signal_stat->total_val = 0;
101                 signal_stat->update_req = 0;
102         }
103
104         signal_stat->total_num++;
105         signal_stat->total_val  += pattrib->phy_info.SignalQuality;
106         signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
107
108 #else //CONFIG_NEW_SIGNAL_STAT_PROCESS
109         if(pattrib->phy_info.SignalQuality != 0)
110         {
111                         //
112                         // 1. Record the general EVM to the sliding window.
113                         //
114                         if(padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX)
115                         {
116                                 padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
117                                 last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
118                                 padapter->recvpriv.signal_qual_data.total_val -= last_evm;
119                         }
120                         padapter->recvpriv.signal_qual_data.total_val += pattrib->phy_info.SignalQuality;
121
122                         padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->phy_info.SignalQuality;
123                         if(padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
124                                 padapter->recvpriv.signal_qual_data.index = 0;
125
126                         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));
127
128                         // <1> Showed on UI for user, in percentage.
129                         tmpVal = padapter->recvpriv.signal_qual_data.total_val/padapter->recvpriv.signal_qual_data.total_num;
130                         padapter->recvpriv.signal_qual=(u8)tmpVal;
131
132         }
133         else
134         {
135                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" pattrib->signal_qual =%d\n", pattrib->phy_info.SignalQuality));
136         }
137 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
138
139 }// Process_UiLinkQuality8192S
140
141 static void process_phy_info(_adapter *padapter, void *prframe)
142 {
143         union recv_frame *precvframe = (union recv_frame *)prframe;
144         //
145         // Check RSSI
146         //
147         process_rssi(padapter, precvframe);
148         //
149         // Check PWDB.
150         //
151         //process_PWDB(padapter, precvframe);
152
153         //UpdateRxSignalStatistics8192C(Adapter, pRfd);
154         //
155         // Check EVM
156         //
157         process_link_qual(padapter,  precvframe);
158         #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
159         rtw_store_phy_info( padapter,prframe);
160         #endif
161
162 }
163
164 /*
165  * Notice:
166  *      Before calling this function,
167  *      precvframe->u.hdr.rx_data should be ready!
168  */
169 void rtl8723b_query_rx_phy_status(union recv_frame *precvframe, struct phy_stat *pphy_status)
170 {
171         PADAPTER padapter = precvframe->u.hdr.adapter;
172         struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
173         PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
174         PODM_PHY_INFO_T pPHYInfo  = (PODM_PHY_INFO_T)(&pattrib->phy_info);
175
176         u8 *wlanhdr;
177         ODM_PACKET_INFO_T pkt_info;
178         u8 *sa = NULL;
179         //_irqL         irqL;
180         struct sta_priv *pstapriv;
181         struct sta_info *psta;
182
183
184         pkt_info.bPacketMatchBSSID =_FALSE;
185         pkt_info.bPacketToSelf = _FALSE;
186         pkt_info.bPacketBeacon = _FALSE;
187
188         wlanhdr = get_recvframe_data(precvframe);
189
190         pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) &&
191                 !pattrib->icv_err && !pattrib->crc_err &&
192                 _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN));
193
194         pkt_info.bToSelf = ((!pattrib->icv_err) && (!pattrib->crc_err)) && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN));
195
196         pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && (_rtw_memcmp(get_ra(wlanhdr), myid(&padapter->eeprompriv), ETH_ALEN));
197
198         pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && (GetFrameSubType(wlanhdr) == WIFI_BEACON);
199 /*
200         if(pkt_info.bPacketBeacon){
201                 if(check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE){
202                         sa = padapter->mlmepriv.cur_network.network.MacAddress;
203                 #if 0
204                         {
205                                 DBG_871X("==> rx beacon from AP[%02x:%02x:%02x:%02x:%02x:%02x]\n",
206                                         sa[0],sa[1],sa[2],sa[3],sa[4],sa[5]);
207                         }
208                 #endif
209                 }
210                 //to do Ad-hoc
211         }
212         else{
213                 sa = get_sa(wlanhdr);
214         }
215 */
216         sa = get_ta(wlanhdr);
217
218         pkt_info.StationID = 0xFF;
219
220         pstapriv = &padapter->stapriv;
221         psta = rtw_get_stainfo(pstapriv, sa);
222         if (psta)
223                 pkt_info.StationID = psta->mac_id;
224         pkt_info.DataRate = pattrib->data_rate;
225
226         ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8*)pphy_status, &pkt_info);
227         if(psta)
228                 psta->rssi = pattrib->phy_info.RecvSignalPower;
229
230         precvframe->u.hdr.psta = NULL;
231         if (pkt_info.bPacketMatchBSSID &&
232                 (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)) {
233                 if (psta) {
234                         precvframe->u.hdr.psta = psta;
235                         process_phy_info(padapter, precvframe);
236                 }
237         } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) {
238                 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)
239                         if (psta)
240                                 precvframe->u.hdr.psta = psta;
241                 process_phy_info(padapter, precvframe);
242         }
243 }
244
245 void rtl8723b_query_rx_desc_status(union recv_frame *precvframe, u8 *pdesc)
246 {
247         struct rx_pkt_attrib *pattrib;
248
249
250         pattrib = &precvframe->u.hdr.attrib;
251         _rtw_memset(pattrib, 0, sizeof(struct rx_pkt_attrib));
252
253         pattrib->pkt_len = (u16)GET_RX_STATUS_DESC_PKT_LEN_8723B(pdesc);
254         pattrib->pkt_rpt_type = GET_RX_STATUS_DESC_RPT_SEL_8723B(pdesc) ? C2H_PACKET : NORMAL_RX;
255
256         if (pattrib->pkt_rpt_type == NORMAL_RX) {
257                 // Offset 0
258                 pattrib->crc_err = (u8)GET_RX_STATUS_DESC_CRC32_8723B(pdesc);
259                 pattrib->icv_err = (u8)GET_RX_STATUS_DESC_ICV_8723B(pdesc);
260                 pattrib->drvinfo_sz = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE_8723B(pdesc) << 3;
261                 pattrib->encrypt = (u8)GET_RX_STATUS_DESC_SECURITY_8723B(pdesc);
262                 pattrib->qos = (u8)GET_RX_STATUS_DESC_QOS_8723B(pdesc);
263                 pattrib->shift_sz = (u8)GET_RX_STATUS_DESC_SHIFT_8723B(pdesc);
264                 pattrib->physt = (u8)GET_RX_STATUS_DESC_PHY_STATUS_8723B(pdesc);
265                 pattrib->bdecrypted = (u8)GET_RX_STATUS_DESC_SWDEC_8723B(pdesc) ? 0 : 1;
266
267                 // Offset 4
268                 pattrib->priority = (u8)GET_RX_STATUS_DESC_TID_8723B(pdesc);
269                 pattrib->amsdu = (u8)GET_RX_STATUS_DESC_AMSDU_8723B(pdesc);
270                 pattrib->mdata = (u8)GET_RX_STATUS_DESC_MORE_DATA_8723B(pdesc);
271                 pattrib->mfrag = (u8)GET_RX_STATUS_DESC_MORE_FRAG_8723B(pdesc);
272
273                 // Offset 8
274                 pattrib->seq_num = (u16)GET_RX_STATUS_DESC_SEQ_8723B(pdesc);
275                 pattrib->frag_num = (u8)GET_RX_STATUS_DESC_FRAG_8723B(pdesc);
276
277                 // Offset 12
278                 pattrib->data_rate = (u8)GET_RX_STATUS_DESC_RX_RATE_8723B(pdesc);
279         }
280 }
281