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 <osdep_service.h> 23#include <drv_types.h> 24#include <rtl8188e_hal.h> 25 26static void process_rssi(struct adapter *padapter, struct recv_frame *prframe) 27{ 28 struct rx_pkt_attrib *pattrib = &prframe->attrib; 29 struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data; 30 31 if (signal_stat->update_req) { 32 signal_stat->total_num = 0; 33 signal_stat->total_val = 0; 34 signal_stat->update_req = 0; 35 } 36 37 signal_stat->total_num++; 38 signal_stat->total_val += pattrib->phy_info.SignalStrength; 39 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; 40} /* Process_UI_RSSI_8192C */ 41 42static void process_link_qual(struct adapter *padapter, 43 struct recv_frame *prframe) 44{ 45 struct rx_pkt_attrib *pattrib; 46 struct signal_stat *signal_stat; 47 48 if (prframe == NULL || padapter == NULL) 49 return; 50 51 pattrib = &prframe->attrib; 52 signal_stat = &padapter->recvpriv.signal_qual_data; 53 54 if (signal_stat->update_req) { 55 signal_stat->total_num = 0; 56 signal_stat->total_val = 0; 57 signal_stat->update_req = 0; 58 } 59 60 signal_stat->total_num++; 61 signal_stat->total_val += pattrib->phy_info.SignalQuality; 62 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num; 63} 64 65void rtl8188e_process_phy_info(struct adapter *padapter, void *prframe) 66{ 67 struct recv_frame *precvframe = (struct recv_frame *)prframe; 68 69 /* Check RSSI */ 70 process_rssi(padapter, precvframe); 71 /* Check EVM */ 72 process_link_qual(padapter, precvframe); 73} 74 75void update_recvframe_attrib_88e(struct recv_frame *precvframe, 76 struct recv_stat *prxstat) 77{ 78 struct rx_pkt_attrib *pattrib; 79 struct recv_stat report; 80 81 report.rxdw0 = prxstat->rxdw0; 82 report.rxdw1 = prxstat->rxdw1; 83 report.rxdw2 = prxstat->rxdw2; 84 report.rxdw3 = prxstat->rxdw3; 85 report.rxdw4 = prxstat->rxdw4; 86 report.rxdw5 = prxstat->rxdw5; 87 88 pattrib = &precvframe->attrib; 89 memset(pattrib, 0, sizeof(struct rx_pkt_attrib)); 90 91 pattrib->crc_err = (u8)((le32_to_cpu(report.rxdw0) >> 14) & 0x1);/* u8)prxreport->crc32; */ 92 93 /* update rx report to recv_frame attribute */ 94 pattrib->pkt_rpt_type = (u8)((le32_to_cpu(report.rxdw3) >> 14) & 0x3);/* prxreport->rpt_sel; */ 95 96 if (pattrib->pkt_rpt_type == NORMAL_RX) { /* Normal rx packet */ 97 pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x00003fff);/* u16)prxreport->pktlen; */ 98 pattrib->drvinfo_sz = (u8)((le32_to_cpu(report.rxdw0) >> 16) & 0xf) * 8;/* u8)(prxreport->drvinfosize << 3); */ 99 100 pattrib->physt = (u8)((le32_to_cpu(report.rxdw0) >> 26) & 0x1);/* u8)prxreport->physt; */ 101 102 pattrib->bdecrypted = (le32_to_cpu(report.rxdw0) & BIT(27)) ? 0 : 1;/* u8)(prxreport->swdec ? 0 : 1); */ 103 pattrib->encrypt = (u8)((le32_to_cpu(report.rxdw0) >> 20) & 0x7);/* u8)prxreport->security; */ 104 105 pattrib->qos = (u8)((le32_to_cpu(report.rxdw0) >> 23) & 0x1);/* u8)prxreport->qos; */ 106 pattrib->priority = (u8)((le32_to_cpu(report.rxdw1) >> 8) & 0xf);/* u8)prxreport->tid; */ 107 108 pattrib->amsdu = (u8)((le32_to_cpu(report.rxdw1) >> 13) & 0x1);/* u8)prxreport->amsdu; */ 109 110 pattrib->seq_num = (u16)(le32_to_cpu(report.rxdw2) & 0x00000fff);/* u16)prxreport->seq; */ 111 pattrib->frag_num = (u8)((le32_to_cpu(report.rxdw2) >> 12) & 0xf);/* u8)prxreport->frag; */ 112 pattrib->mfrag = (u8)((le32_to_cpu(report.rxdw1) >> 27) & 0x1);/* u8)prxreport->mf; */ 113 pattrib->mdata = (u8)((le32_to_cpu(report.rxdw1) >> 26) & 0x1);/* u8)prxreport->md; */ 114 115 pattrib->mcs_rate = (u8)(le32_to_cpu(report.rxdw3) & 0x3f);/* u8)prxreport->rxmcs; */ 116 pattrib->rxht = (u8)((le32_to_cpu(report.rxdw3) >> 6) & 0x1);/* u8)prxreport->rxht; */ 117 118 pattrib->icv_err = (u8)((le32_to_cpu(report.rxdw0) >> 15) & 0x1);/* u8)prxreport->icverr; */ 119 pattrib->shift_sz = (u8)((le32_to_cpu(report.rxdw0) >> 24) & 0x3); 120 } else if (pattrib->pkt_rpt_type == TX_REPORT1) { /* CCX */ 121 pattrib->pkt_len = TX_RPT1_PKT_LEN; 122 pattrib->drvinfo_sz = 0; 123 } else if (pattrib->pkt_rpt_type == TX_REPORT2) { /* TX RPT */ 124 pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x3FF);/* Rx length[9:0] */ 125 pattrib->drvinfo_sz = 0; 126 127 /* */ 128 /* Get TX report MAC ID valid. */ 129 /* */ 130 pattrib->MacIDValidEntry[0] = le32_to_cpu(report.rxdw4); 131 pattrib->MacIDValidEntry[1] = le32_to_cpu(report.rxdw5); 132 133 } else if (pattrib->pkt_rpt_type == HIS_REPORT) { /* USB HISR RPT */ 134 pattrib->pkt_len = (u16)(le32_to_cpu(report.rxdw0) & 0x00003fff);/* u16)prxreport->pktlen; */ 135 } 136} 137 138/* 139 * Notice: 140 * Before calling this function, 141 * precvframe->rx_data should be ready! 142 */ 143void update_recvframe_phyinfo_88e(struct recv_frame *precvframe, 144 struct phy_stat *pphy_status) 145{ 146 struct adapter *padapter = precvframe->adapter; 147 struct rx_pkt_attrib *pattrib = &precvframe->attrib; 148 struct hal_data_8188e *pHalData = GET_HAL_DATA(padapter); 149 struct odm_phy_status_info *pPHYInfo = (struct odm_phy_status_info *)(&pattrib->phy_info); 150 u8 *wlanhdr; 151 struct odm_per_pkt_info pkt_info; 152 u8 *sa = NULL; 153 struct sta_priv *pstapriv; 154 struct sta_info *psta; 155 156 pkt_info.bPacketMatchBSSID = false; 157 pkt_info.bPacketToSelf = false; 158 pkt_info.bPacketBeacon = false; 159 160 wlanhdr = precvframe->rx_data; 161 162 pkt_info.bPacketMatchBSSID = ((!IsFrameTypeCtrl(wlanhdr)) && 163 !pattrib->icv_err && !pattrib->crc_err && 164 !memcmp(get_hdr_bssid(wlanhdr), 165 get_bssid(&padapter->mlmepriv), ETH_ALEN)); 166 167 pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID && 168 (!memcmp(get_da(wlanhdr), 169 myid(&padapter->eeprompriv), ETH_ALEN)); 170 171 pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID && 172 (GetFrameSubType(wlanhdr) == WIFI_BEACON); 173 174 if (pkt_info.bPacketBeacon) { 175 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) 176 sa = padapter->mlmepriv.cur_network.network.MacAddress; 177 /* to do Ad-hoc */ 178 } else { 179 sa = get_sa(wlanhdr); 180 } 181 182 pstapriv = &padapter->stapriv; 183 pkt_info.StationID = 0xFF; 184 psta = rtw_get_stainfo(pstapriv, sa); 185 if (psta) 186 pkt_info.StationID = psta->mac_id; 187 pkt_info.Rate = pattrib->mcs_rate; 188 189 ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, (u8 *)pphy_status, &(pkt_info)); 190 191 precvframe->psta = NULL; 192 if (pkt_info.bPacketMatchBSSID && 193 (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE))) { 194 if (psta) { 195 precvframe->psta = psta; 196 rtl8188e_process_phy_info(padapter, precvframe); 197 } 198 } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) { 199 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) { 200 if (psta) 201 precvframe->psta = psta; 202 } 203 rtl8188e_process_phy_info(padapter, precvframe); 204 } 205} 206