/******************************************************************************
*
* Copyright(c) 2009-2010 Realtek Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* The full GNU General Public License is included in this distribution in the
* file called LICENSE.
*
* Contact Information:
* wlanfae <wlanfae@realtek.com>
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
* Hsinchu 300, Taiwan.
*
* Larry Finger <Larry.Finger@lwfinger.net>
*
*****************************************************************************/
#include "../wifi.h"
#include "../pci.h"
#include "../base.h"
#include "../stats.h"
#include "reg.h"
#include "def.h"
#include "phy.h"
#include "trx.h"
#include "led.h"
#include "dm.h"
#include "phy.h"
#include "fw.h"
static u8 _rtl8821ae_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
{
__le16 fc = rtl_get_fc(skb);
if (unlikely(ieee80211_is_beacon(fc)))
return QSLT_BEACON;
if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
return QSLT_MGNT;
return skb->priority;
}
static u16 odm_cfo(char value)
{
int ret_val;
if (value < 0) {
ret_val = 0 - value;
ret_val = (ret_val << 1) + (ret_val >> 1);
/* set bit12 as 1 for negative cfo */
ret_val = ret_val | BIT(12);
} else {
ret_val = value;
ret_val = (ret_val << 1) + (ret_val >> 1);
}
return ret_val;
}
static void query_rxphystatus(struct ieee80211_hw *hw,
struct rtl_stats *pstatus, u8 *pdesc,
struct rx_fwinfo_8821ae *p_drvinfo,
bool bpacket_match_bssid,
bool bpacket_toself, bool packet_beacon)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct phy_status_rpt *p_phystrpt = (struct phy_status_rpt *)p_drvinfo;
struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
struct rtl_phy *rtlphy = &rtlpriv->phy;
char rx_pwr_all = 0, rx_pwr[4];
u8 rf_rx_num = 0, evm, evmdbm, pwdb_all;
u8 i, max_spatial_stream;
u32 rssi, total_rssi = 0;
bool is_cck = pstatus->is_cck;
u8 lan_idx, vga_idx;
/* Record it for next packet processing */
pstatus->packet_matchbssid = bpacket_match_bssid;
pstatus->packet_toself = bpacket_toself;
pstatus->packet_beacon = packet_beacon;
pstatus->rx_mimo_signalquality[0] = -1;
pstatus->rx_mimo_signalquality[1] = -1;
if (is_cck) {
u8 cck_highpwr;
u8 cck_agc_rpt;
cck_agc_rpt = p_phystrpt->cfosho[0];
/* (1)Hardware does not provide RSSI for CCK
* (2)PWDB, Average PWDB cacluated by
* hardware (for rate adaptive)
*/
cck_highpwr = (u8)rtlphy->cck_high_power;
lan_idx = ((cck_agc_rpt & 0xE0) >> 5);
vga_idx = (cck_agc_rpt & 0x1f);
if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) {
switch (lan_idx) {
case 7:
if (vga_idx <= 27)
/*VGA_idx = 27~2*/
rx_pwr_all = -100 + 2*(27-vga_idx);
else
rx_pwr_all = -100;
break;
case 6:
/*VGA_idx = 2~0*/
rx_pwr_all = -48 + 2*(2-vga_idx);
break;
case 5:
/*VGA_idx = 7~5*/
rx_pwr_all = -42 + 2*(7-vga_idx);
break;
case 4:
/*VGA_idx = 7~4*/
rx_pwr_all = -36 + 2*(7-vga_idx);
break;
case 3:
/*VGA_idx = 7~0*/
rx_pwr_all = -24 + 2*(7-vga_idx);
break;
case 2:
if (cck_highpwr)
/*VGA_idx = 5~0*/
rx_pwr_all = -12 + 2*(5-vga_idx);
else
rx_pwr_all = -6 + 2*(5-vga_idx);