aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192ce/trx.c')
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/trx.c763
1 files changed, 243 insertions, 520 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
index bf5852f2d63..8f04817cb7e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright(c) 2009-2010 Realtek Corporation.
+ * Copyright(c) 2009-2012 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
@@ -30,146 +30,23 @@
#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"
-static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(u16 fc,
- unsigned int
- skb_queue)
+static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
{
- enum rtl_desc_qsel qsel;
+ __le16 fc = rtl_get_fc(skb);
- if (unlikely(ieee80211_is_beacon(fc))) {
- qsel = QSLT_BEACON;
- return qsel;
- }
-
- if (ieee80211_is_mgmt(fc)) {
- qsel = QSLT_MGNT;
- return qsel;
- }
+ if (unlikely(ieee80211_is_beacon(fc)))
+ return QSLT_BEACON;
+ if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc))
+ return QSLT_MGNT;
- switch (skb_queue) {
- case VO_QUEUE:
- qsel = QSLT_VO;
- break;
- case VI_QUEUE:
- qsel = QSLT_VI;
- break;
- case BE_QUEUE:
- qsel = QSLT_BE;
- break;
- case BK_QUEUE:
- qsel = QSLT_BK;
- break;
- default:
- qsel = QSLT_BE;
- RT_ASSERT(false, ("BE queue, skb_queue:%d,"
- " set qsel = 0x%X\n", skb_queue, QSLT_BE));
- break;
- }
- return qsel;
-}
-
-static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
-{
- int rate_idx;
-
- if (first_ampdu) {
- if (false == isht) {
- switch (desc_rate) {
- case DESC92C_RATE1M:
- rate_idx = 0;
- break;
- case DESC92C_RATE2M:
- rate_idx = 1;
- break;
- case DESC92C_RATE5_5M:
- rate_idx = 2;
- break;
- case DESC92C_RATE11M:
- rate_idx = 3;
- break;
- case DESC92C_RATE6M:
- rate_idx = 4;
- break;
- case DESC92C_RATE9M:
- rate_idx = 5;
- break;
- case DESC92C_RATE12M:
- rate_idx = 6;
- break;
- case DESC92C_RATE18M:
- rate_idx = 7;
- break;
- case DESC92C_RATE24M:
- rate_idx = 8;
- break;
- case DESC92C_RATE36M:
- rate_idx = 9;
- break;
- case DESC92C_RATE48M:
- rate_idx = 10;
- break;
- case DESC92C_RATE54M:
- rate_idx = 11;
- break;
- default:
- rate_idx = 0;
- break;
- }
- } else {
- rate_idx = 11;
- }
-
- return rate_idx;
- }
-
- switch (desc_rate) {
- case DESC92C_RATE1M:
- rate_idx = 0;
- break;
- case DESC92C_RATE2M:
- rate_idx = 1;
- break;
- case DESC92C_RATE5_5M:
- rate_idx = 2;
- break;
- case DESC92C_RATE11M:
- rate_idx = 3;
- break;
- case DESC92C_RATE6M:
- rate_idx = 4;
- break;
- case DESC92C_RATE9M:
- rate_idx = 5;
- break;
- case DESC92C_RATE12M:
- rate_idx = 6;
- break;
- case DESC92C_RATE18M:
- rate_idx = 7;
- break;
- case DESC92C_RATE24M:
- rate_idx = 8;
- break;
- case DESC92C_RATE36M:
- rate_idx = 9;
- break;
- case DESC92C_RATE48M:
- rate_idx = 10;
- break;
- case DESC92C_RATE54M:
- rate_idx = 11;
- break;
- default:
- rate_idx = 11;
- break;
- }
- return rate_idx;
+ return skb->priority;
}
static u8 _rtl92c_query_rxpwrpercentage(char antpower)
@@ -202,16 +79,6 @@ static u8 _rtl92c_evm_db_to_percentage(char value)
return ret_val;
}
-static long _rtl92ce_translate_todbm(struct ieee80211_hw *hw,
- u8 signal_strength_index)
-{
- long signal_power;
-
- signal_power = (long)((signal_strength_index + 1) >> 1);
- signal_power -= 95;
- return signal_power;
-}
-
static long _rtl92ce_signal_scale_mapping(struct ieee80211_hw *hw,
long currsig)
{
@@ -245,34 +112,38 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
struct rtl_stats *pstats,
struct rx_desc_92c *pdesc,
struct rx_fwinfo_92c *p_drvinfo,
- bool bpacket_match_bssid,
- bool bpacket_toself,
- bool b_packet_beacon)
+ bool packet_match_bssid,
+ bool packet_toself,
+ bool packet_beacon)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct phy_sts_cck_8192s_t *cck_buf;
- s8 rx_pwr_all, rx_pwr[4];
- u8 rf_rx_num, evm, pwdb_all;
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
+ s8 rx_pwr_all = 0, rx_pwr[4];
+ u8 evm, pwdb_all, rf_rx_num = 0;
u8 i, max_spatial_stream;
- u32 rssi, total_rssi;
+ u32 rssi, total_rssi = 0;
bool is_cck_rate;
is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
- pstats->b_packet_matchbssid = bpacket_match_bssid;
- pstats->b_packet_toself = bpacket_toself;
- pstats->b_is_cck = is_cck_rate;
- pstats->b_packet_beacon = b_packet_beacon;
- pstats->b_is_cck = is_cck_rate;
- pstats->rx_mimo_signalquality[0] = -1;
- pstats->rx_mimo_signalquality[1] = -1;
+ pstats->packet_matchbssid = packet_match_bssid;
+ pstats->packet_toself = packet_toself;
+ pstats->is_cck = is_cck_rate;
+ pstats->packet_beacon = packet_beacon;
+ pstats->rx_mimo_sig_qual[0] = -1;
+ pstats->rx_mimo_sig_qual[1] = -1;
if (is_cck_rate) {
u8 report, cck_highpwr;
cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
- cck_highpwr = (u8) rtl_get_bbreg(hw,
- RFPGA0_XA_HSSIPARAMETER2,
- BIT(9));
+ if (ppsc->rfpwr_state == ERFON)
+ cck_highpwr = (u8) rtl_get_bbreg(hw,
+ RFPGA0_XA_HSSIPARAMETER2,
+ BIT(9));
+ else
+ cck_highpwr = false;
+
if (!cck_highpwr) {
u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
report = cck_buf->cck_agc_rpt & 0xc0;
@@ -311,11 +182,31 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
}
}
- pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
+ pwdb_all = rtl_query_rxpwrpercentage(rx_pwr_all);
+ /* CCK gain is smaller than OFDM/MCS gain,
+ * so we add gain diff by experiences,
+ * the val is 6
+ */
+ pwdb_all += 6;
+ if (pwdb_all > 100)
+ pwdb_all = 100;
+ /* modify the offset to make the same
+ * gain index with OFDM.
+ */
+ if (pwdb_all > 34 && pwdb_all <= 42)
+ pwdb_all -= 2;
+ else if (pwdb_all > 26 && pwdb_all <= 34)
+ pwdb_all -= 6;
+ else if (pwdb_all > 14 && pwdb_all <= 26)
+ pwdb_all -= 8;
+ else if (pwdb_all > 4 && pwdb_all <= 14)
+ pwdb_all -= 4;
+
pstats->rx_pwdb_all = pwdb_all;
pstats->recvsignalpower = rx_pwr_all;
- if (bpacket_match_bssid) {
+ /* (3) Get Signal Quality (EVM) */
+ if (packet_match_bssid) {
u8 sq;
if (pstats->rx_pwdb_all > 40)
sq = 100;
@@ -330,35 +221,44 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
}
pstats->signalquality = sq;
- pstats->rx_mimo_signalquality[0] = sq;
- pstats->rx_mimo_signalquality[1] = -1;
+ pstats->rx_mimo_sig_qual[0] = sq;
+ pstats->rx_mimo_sig_qual[1] = -1;
}
} else {
- rtlpriv->dm.brfpath_rxenable[0] =
- rtlpriv->dm.brfpath_rxenable[1] = true;
+ rtlpriv->dm.rfpath_rxenable[0] =
+ rtlpriv->dm.rfpath_rxenable[1] = true;
+ /* (1)Get RSSI for HT rate */
for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
- if (rtlpriv->dm.brfpath_rxenable[i])
+ /* we will judge RF RX path now. */
+ if (rtlpriv->dm.rfpath_rxenable[i])
rf_rx_num++;
rx_pwr[i] =
((p_drvinfo->gain_trsw[i] & 0x3f) * 2) - 110;
+ /* Translate DBM to percentage. */
rssi = _rtl92c_query_rxpwrpercentage(rx_pwr[i]);
total_rssi += rssi;
+ /* Get Rx snr value in DB */
rtlpriv->stats.rx_snr_db[i] =
(long)(p_drvinfo->rxsnr[i] / 2);
- if (bpacket_match_bssid)
+ /* Record Signal Strength for next packet */
+ if (packet_match_bssid)
pstats->rx_mimo_signalstrength[i] = (u8) rssi;
}
+ /* (2)PWDB, Average PWDB cacluated by
+ * hardware (for rate adaptive)
+ */
rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
pwdb_all = _rtl92c_query_rxpwrpercentage(rx_pwr_all);
pstats->rx_pwdb_all = pwdb_all;
pstats->rxpower = rx_pwr_all;
pstats->recvsignalpower = rx_pwr_all;
- if (pdesc->rxht && pdesc->rxmcs >= DESC92C_RATEMCS8 &&
- pdesc->rxmcs <= DESC92C_RATEMCS15)
+ /* (3)EVM of HT rate */
+ if (pstats->is_ht && pstats->rate >= DESC92_RATEMCS8 &&
+ pstats->rate <= DESC92_RATEMCS15)
max_spatial_stream = 2;
else
max_spatial_stream = 1;
@@ -366,16 +266,21 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
for (i = 0; i < max_spatial_stream; i++) {
evm = _rtl92c_evm_db_to_percentage(p_drvinfo->rxevm[i]);
- if (bpacket_match_bssid) {
+ if (packet_match_bssid) {
+ /* Fill value in RFD, Get the first
+ * spatial stream only
+ */
if (i == 0)
pstats->signalquality =
(u8) (evm & 0xff);
- pstats->rx_mimo_signalquality[i] =
- (u8) (evm & 0xff);
+ pstats->rx_mimo_sig_qual[i] = (u8) (evm & 0xff);
}
}
}
+ /* UI BSS List signal strength(in percentage),
+ * make it good looking, from 0~100.
+ */
if (is_cck_rate)
pstats->signalstrength =
(u8) (_rtl92ce_signal_scale_mapping(hw, pwdb_all));
@@ -385,225 +290,6 @@ static void _rtl92ce_query_rxphystatus(struct ieee80211_hw *hw,
(hw, total_rssi /= rf_rx_num));
}
-static void _rtl92ce_process_ui_rssi(struct ieee80211_hw *hw,
- struct rtl_stats *pstats)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_phy *rtlphy = &(rtlpriv->phy);
- u8 rfpath;
- u32 last_rssi, tmpval;
-
- if (pstats->b_packet_toself || pstats->b_packet_beacon) {
- rtlpriv->stats.rssi_calculate_cnt++;
-
- if (rtlpriv->stats.ui_rssi.total_num++ >=
- PHY_RSSI_SLID_WIN_MAX) {
- rtlpriv->stats.ui_rssi.total_num =
- PHY_RSSI_SLID_WIN_MAX;
- last_rssi =
- rtlpriv->stats.ui_rssi.elements[rtlpriv->
- stats.ui_rssi.index];
- rtlpriv->stats.ui_rssi.total_val -= last_rssi;
- }
-
- rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
- rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.
- index++] =
- pstats->signalstrength;
-
- if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
- rtlpriv->stats.ui_rssi.index = 0;
-
- tmpval = rtlpriv->stats.ui_rssi.total_val /
- rtlpriv->stats.ui_rssi.total_num;
- rtlpriv->stats.signal_strength =
- _rtl92ce_translate_todbm(hw, (u8) tmpval);
- pstats->rssi = rtlpriv->stats.signal_strength;
- }
-
- if (!pstats->b_is_cck && pstats->b_packet_toself) {
- for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
- rfpath++) {
-
- if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
- continue;
-
- if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
- rtlpriv->stats.rx_rssi_percentage[rfpath] =
- pstats->rx_mimo_signalstrength[rfpath];
-
- }
-
- if (pstats->rx_mimo_signalstrength[rfpath] >
- rtlpriv->stats.rx_rssi_percentage[rfpath]) {
- rtlpriv->stats.rx_rssi_percentage[rfpath] =
- ((rtlpriv->stats.
- rx_rssi_percentage[rfpath] *
- (RX_SMOOTH_FACTOR - 1)) +
- (pstats->rx_mimo_signalstrength[rfpath])) /
- (RX_SMOOTH_FACTOR);
-
- rtlpriv->stats.rx_rssi_percentage[rfpath] =
- rtlpriv->stats.rx_rssi_percentage[rfpath] +
- 1;
- } else {
- rtlpriv->stats.rx_rssi_percentage[rfpath] =
- ((rtlpriv->stats.
- rx_rssi_percentage[rfpath] *
- (RX_SMOOTH_FACTOR - 1)) +
- (pstats->rx_mimo_signalstrength[rfpath])) /
- (RX_SMOOTH_FACTOR);
- }
-
- }
- }
-}
-
-static void _rtl92ce_update_rxsignalstatistics(struct ieee80211_hw *hw,
- struct rtl_stats *pstats)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- int weighting;
-
- if (rtlpriv->stats.recv_signal_power == 0)
- rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
-
- if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
- weighting = 5;
-
- else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
- weighting = (-5);
-
- rtlpriv->stats.recv_signal_power =
- (rtlpriv->stats.recv_signal_power * 5 +
- pstats->recvsignalpower + weighting) / 6;
-}
-
-static void _rtl92ce_process_pwdb(struct ieee80211_hw *hw,
- struct rtl_stats *pstats)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
- long undecorated_smoothed_pwdb;
-
- if (mac->opmode == NL80211_IFTYPE_ADHOC) {
- return;
- } else {
- undecorated_smoothed_pwdb =
- rtlpriv->dm.undecorated_smoothed_pwdb;
- }
-
- if (pstats->b_packet_toself || pstats->b_packet_beacon) {
- if (undecorated_smoothed_pwdb < 0)
- undecorated_smoothed_pwdb = pstats->rx_pwdb_all;
-
- if (pstats->rx_pwdb_all > (u32) undecorated_smoothed_pwdb) {
- undecorated_smoothed_pwdb =
- (((undecorated_smoothed_pwdb) *
- (RX_SMOOTH_FACTOR - 1)) +
- (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
-
- undecorated_smoothed_pwdb = undecorated_smoothed_pwdb
- + 1;
- } else {
- undecorated_smoothed_pwdb =
- (((undecorated_smoothed_pwdb) *
- (RX_SMOOTH_FACTOR - 1)) +
- (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
- }
-
- rtlpriv->dm.undecorated_smoothed_pwdb =
- undecorated_smoothed_pwdb;
- _rtl92ce_update_rxsignalstatistics(hw, pstats);
- }
-}
-
-static void _rtl92ce_process_ui_link_quality(struct ieee80211_hw *hw,
- struct rtl_stats *pstats)
-{
- struct rtl_priv *rtlpriv = rtl_priv(hw);
- u32 last_evm, n_spatialstream, tmpval;
-
- if (pstats->signalquality != 0) {
- if (pstats->b_packet_toself || pstats->b_packet_beacon) {
-
- if (rtlpriv->stats.ui_link_quality.total_num++ >=
- PHY_LINKQUALITY_SLID_WIN_MAX) {
- rtlpriv->stats.ui_link_quality.total_num =
- PHY_LINKQUALITY_SLID_WIN_MAX;
- last_evm =
- rtlpriv->stats.
- ui_link_quality.elements[rtlpriv->
- stats.ui_link_quality.
- index];
- rtlpriv->stats.ui_link_quality.total_val -=
- last_evm;
- }
-
- rtlpriv->stats.ui_link_quality.total_val +=
- pstats->signalquality;
- rtlpriv->stats.ui_link_quality.elements[rtlpriv->stats.
- ui_link_quality.
- index++] =
- pstats->signalquality;
-
- if (rtlpriv->stats.ui_link_quality.index >=
- PHY_LINKQUALITY_SLID_WIN_MAX)
- rtlpriv->stats.ui_link_quality.index = 0;
-
- tmpval = rtlpriv->stats.ui_link_quality.total_val /
- rtlpriv->stats.ui_link_quality.total_num;
- rtlpriv->stats.signal_quality = tmpval;
-
- rtlpriv->stats.last_sigstrength_inpercent = tmpval;
-
- for (n_spatialstream = 0; n_spatialstream < 2;
- n_spatialstream++) {
- if (pstats->
- rx_mimo_signalquality[n_spatialstream] !=
- -1) {
- if (rtlpriv->stats.
- rx_evm_percentage[n_spatialstream]
- == 0) {
- rtlpriv->stats.
- rx_evm_percentage
- [n_spatialstream] =
- pstats->rx_mimo_signalquality
- [n_spatialstream];
- }
-
- rtlpriv->stats.
- rx_evm_percentage[n_spatialstream] =
- ((rtlpriv->
- stats.rx_evm_percentage
- [n_spatialstream] *
- (RX_SMOOTH_FACTOR - 1)) +
- (pstats->
- rx_mimo_signalquality
- [n_spatialstream] * 1)) /
- (RX_SMOOTH_FACTOR);
- }
- }
- }
- } else {
- ;
- }
-}
-
-static void _rtl92ce_process_phyinfo(struct ieee80211_hw *hw,
- u8 *buffer,
- struct rtl_stats *pcurrent_stats)
-{
-
- if (!pcurrent_stats->b_packet_matchbssid &&
- !pcurrent_stats->b_packet_beacon)
- return;
-
- _rtl92ce_process_ui_rssi(hw, pcurrent_stats);
- _rtl92ce_process_pwdb(hw, pcurrent_stats);
- _rtl92ce_process_ui_link_quality(hw, pcurrent_stats);
-}
-
static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct rtl_stats *pstats,
@@ -616,37 +302,37 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr;
u8 *tmp_buf;
u8 *praddr;
- u8 *psaddr;
- u16 fc, type;
- bool b_packet_matchbssid, b_packet_toself, b_packet_beacon;
+ __le16 fc;
+ u16 type, c_fc;
+ bool packet_matchbssid, packet_toself, packet_beacon = false;
tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
hdr = (struct ieee80211_hdr *)tmp_buf;
- fc = le16_to_cpu(hdr->frame_control);
+ fc = hdr->frame_control;
+ c_fc = le16_to_cpu(fc);
type = WLAN_FC_GET_TYPE(fc);
praddr = hdr->addr1;
- psaddr = hdr->addr2;
- b_packet_matchbssid =
+ packet_matchbssid =
((IEEE80211_FTYPE_CTL != type) &&
- (!compare_ether_addr(mac->bssid,
- (fc & IEEE80211_FCTL_TODS) ?
- hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS) ?
- hdr->addr2 : hdr->addr3)) &&
- (!pstats->b_hwerror) && (!pstats->b_crc) && (!pstats->b_icv));
+ ether_addr_equal(mac->bssid,
+ (c_fc & IEEE80211_FCTL_TODS) ? hdr->addr1 :
+ (c_fc & IEEE80211_FCTL_FROMDS) ? hdr->addr2 :
+ hdr->addr3) &&
+ (!pstats->hwerror) && (!pstats->crc) && (!pstats->icv));
- b_packet_toself = b_packet_matchbssid &&
- (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+ packet_toself = packet_matchbssid &&
+ ether_addr_equal(praddr, rtlefuse->dev_addr);
if (ieee80211_is_beacon(fc))
- b_packet_beacon = true;
+ packet_beacon = true;
_rtl92ce_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
- b_packet_matchbssid, b_packet_toself,
- b_packet_beacon);
+ packet_matchbssid, packet_toself,
+ packet_beacon);
- _rtl92ce_process_phyinfo(hw, tmp_buf, pstats);
+ rtl_process_phyinfo(hw, tmp_buf, pstats);
}
bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
@@ -656,53 +342,74 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
{
struct rx_fwinfo_92c *p_drvinfo;
struct rx_desc_92c *pdesc = (struct rx_desc_92c *)p_desc;
-
+ struct ieee80211_hdr *hdr;
u32 phystatus = GET_RX_DESC_PHYST(pdesc);
stats->length = (u16) GET_RX_DESC_PKT_LEN(pdesc);
stats->rx_drvinfo_size = (u8) GET_RX_DESC_DRV_INFO_SIZE(pdesc) *
RX_DRV_INFO_SIZE_UNIT;
stats->rx_bufshift = (u8) (GET_RX_DESC_SHIFT(pdesc) & 0x03);
- stats->b_icv = (u16) GET_RX_DESC_ICV(pdesc);
- stats->b_crc = (u16) GET_RX_DESC_CRC32(pdesc);
- stats->b_hwerror = (stats->b_crc | stats->b_icv);
+ stats->icv = (u16) GET_RX_DESC_ICV(pdesc);
+ stats->crc = (u16) GET_RX_DESC_CRC32(pdesc);
+ stats->hwerror = (stats->crc | stats->icv);
stats->decrypted = !GET_RX_DESC_SWDEC(pdesc);
stats->rate = (u8) GET_RX_DESC_RXMCS(pdesc);
- stats->b_shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
- stats->b_isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
- stats->b_isampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
+ stats->shortpreamble = (u16) GET_RX_DESC_SPLCP(pdesc);
+ stats->isampdu = (bool) (GET_RX_DESC_PAGGR(pdesc) == 1);
+ stats->isfirst_ampdu = (bool) ((GET_RX_DESC_PAGGR(pdesc) == 1)
&& (GET_RX_DESC_FAGGR(pdesc) == 1));
stats->timestamp_low = GET_RX_DESC_TSFL(pdesc);
stats->rx_is40Mhzpacket = (bool) GET_RX_DESC_BW(pdesc);
+ stats->is_ht = (bool)GET_RX_DESC_RXHT(pdesc);
- rx_status->freq = hw->conf.channel->center_freq;
- rx_status->band = hw->conf.channel->band;
+ stats->is_cck = RX_HAL_IS_CCK_RATE(pdesc);
- if (GET_RX_DESC_CRC32(pdesc))
- rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+ rx_status->freq = hw->conf.chandef.chan->center_freq;
+ rx_status->band = hw->conf.chandef.chan->band;
- if (!GET_RX_DESC_SWDEC(pdesc))
- rx_status->flag |= RX_FLAG_DECRYPTED;
+ hdr = (struct ieee80211_hdr *)(skb->data + stats->rx_drvinfo_size
+ + stats->rx_bufshift);
- if (GET_RX_DESC_BW(pdesc))
+ if (stats->crc)
+ rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+ if (stats->rx_is40Mhzpacket)
rx_status->flag |= RX_FLAG_40MHZ;
- if (GET_RX_DESC_RXHT(pdesc))
+ if (stats->is_ht)
rx_status->flag |= RX_FLAG_HT;
- rx_status->flag |= RX_FLAG_TSFT;
-
- if (stats->decrypted)
- rx_status->flag |= RX_FLAG_DECRYPTED;
-
- rx_status->rate_idx = _rtl92ce_rate_mapping((bool)
- GET_RX_DESC_RXHT(pdesc),
- (u8)
- GET_RX_DESC_RXMCS(pdesc),
- (bool)
- GET_RX_DESC_PAGGR(pdesc));
-
- rx_status->mactime = GET_RX_DESC_TSFL(pdesc);
- if (phystatus == true) {
+ rx_status->flag |= RX_FLAG_MACTIME_START;
+
+ /* hw will set stats->decrypted true, if it finds the
+ * frame is open data frame or mgmt frame.
+ * So hw will not decryption robust managment frame
+ * for IEEE80211w but still set status->decrypted
+ * true, so here we should set it back to undecrypted
+ * for IEEE80211w frame, and mac80211 sw will help
+ * to decrypt it
+ */
+ if (stats->decrypted) {
+ if (!hdr) {
+ /* In testing, hdr was NULL here */
+ return false;
+ }
+ if ((_ieee80211_is_robust_mgmt_frame(hdr)) &&
+ (ieee80211_has_protected(hdr->frame_control)))
+ rx_status->flag &= ~RX_FLAG_DECRYPTED;
+ else
+ rx_status->flag |= RX_FLAG_DECRYPTED;
+ }
+ /* rate_idx: index of data rate into band's
+ * supported rates or MCS index if HT rates
+ * are use (RX_FLAG_HT)
+ * Notice: this is diff with windows define
+ */
+ rx_status->rate_idx = rtlwifi_rate_mapping(hw,
+ stats->is_ht, stats->rate,
+ stats->isfirst_ampdu);
+
+ rx_status->mactime = stats->timestamp_low;
+ if (phystatus) {
p_drvinfo = (struct rx_fwinfo_92c *)(skb->data +
stats->rx_bufshift);
@@ -712,96 +419,104 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
}
/*rx_status->qual = stats->signal; */
- rx_status->signal = stats->rssi + 10;
- /*rx_status->noise = -stats->noise; */
+ rx_status->signal = stats->recvsignalpower + 10;
return true;
}
void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
struct ieee80211_hdr *hdr, u8 *pdesc_tx,
- struct ieee80211_tx_info *info, struct sk_buff *skb,
- unsigned int queue_index)
+ u8 *pbd_desc_tx, struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb,
+ u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
- bool b_defaultadapter = true;
-
- struct ieee80211_sta *sta = ieee80211_find_sta(mac->vif, mac->bssid);
-
- u8 *pdesc = (u8 *) pdesc_tx;
- struct rtl_tcb_desc tcb_desc;
- u8 *qc = ieee80211_get_qos_ctl(hdr);
- u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+ bool defaultadapter = true;
+ u8 *pdesc = pdesc_tx;
u16 seq_number;
- u16 fc = le16_to_cpu(hdr->frame_control);
- u8 rate_flag = info->control.rates[0].flags;
-
- enum rtl_desc_qsel fw_qsel =
- _rtl92ce_map_hwqueue_to_fwqueue(le16_to_cpu(hdr->frame_control),
- queue_index);
+ __le16 fc = hdr->frame_control;
+ u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
+ bool firstseg = ((hdr->seq_ctrl &
+ cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
- bool b_firstseg = ((hdr->seq_ctrl &
- cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
-
- bool b_lastseg = ((hdr->frame_control &
- cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
+ bool lastseg = ((hdr->frame_control &
+ cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) == 0);
dma_addr_t mapping = pci_map_single(rtlpci->pdev,
skb->data, skb->len,
PCI_DMA_TODEVICE);
+ u8 bw_40 = 0;
+
+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+ "DMA mapping error");
+ return;
+ }
+ rcu_read_lock();
+ sta = get_sta(hw, mac->vif, mac->bssid);
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ bw_40 = mac->bw_40;
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ if (sta)
+ bw_40 = sta->bandwidth >= IEEE80211_STA_RX_BW_40;
+ }
+
seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
- rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
+ rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
- if (b_firstseg) {
+ if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
+ firstseg = true;
+ lastseg = true;
+ }
+ if (firstseg) {
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
- SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
+ SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
- if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
+ if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
- if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
- info->flags & IEEE80211_TX_CTL_AMPDU) {
+ if (info->flags & IEEE80211_TX_CTL_AMPDU) {
SET_TX_DESC_AGG_BREAK(pdesc, 1);
SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
}
SET_TX_DESC_SEQ(pdesc, seq_number);
- SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.b_rts_enable &&
- !tcb_desc.
- b_cts_enable) ? 1 : 0));
+ SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
+ !tcb_desc->
+ cts_enable) ? 1 : 0));
SET_TX_DESC_HW_RTS_ENABLE(pdesc,
- ((tcb_desc.b_rts_enable
- || tcb_desc.b_cts_enable) ? 1 : 0));
- SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.b_cts_enable) ? 1 : 0));
- SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.b_rts_stbc) ? 1 : 0));
+ ((tcb_desc->rts_enable
+ || tcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
+ SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
- SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
+ SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
SET_TX_DESC_RTS_BW(pdesc, 0);
- SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
+ SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
SET_TX_DESC_RTS_SHORT(pdesc,
- ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
- (tcb_desc.b_rts_use_shortpreamble ? 1 : 0)
- : (tcb_desc.b_rts_use_shortgi ? 1 : 0)));
+ ((tcb_desc->rts_rate <= DESC92_RATE54M) ?
+ (tcb_desc->rts_use_shortpreamble ? 1 : 0)
+ : (tcb_desc->rts_use_shortgi ? 1 : 0)));
- if (mac->bw_40) {
- if (tcb_desc.b_packet_bw) {
+ if (bw_40) {
+ if (tcb_desc->packet_bw) {
SET_TX_DESC_DATA_BW(pdesc, 1);
SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
-
- if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
- SET_TX_DESC_TX_SUB_CARRIER(pdesc,
- mac->cur_40_prime_sc);
- }
+ SET_TX_DESC_TX_SUB_CARRIER(pdesc,
+ mac->cur_40_prime_sc);
}
} else {
SET_TX_DESC_DATA_BW(pdesc, 0);
@@ -842,55 +557,55 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
SET_TX_DESC_DISABLE_FB(pdesc, 0);
- SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
+ SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
if (ieee80211_is_data_qos(fc)) {
if (mac->rdg_en) {
RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
- ("Enable RDG function.\n"));
+ "Enable RDG function\n");
SET_TX_DESC_RDG_ENABLE(pdesc, 1);
SET_TX_DESC_HTC(pdesc, 1);
}
}
}
+ rcu_read_unlock();
- SET_TX_DESC_FIRST_SEG(pdesc, (b_firstseg ? 1 : 0));
- SET_TX_DESC_LAST_SEG(pdesc, (b_lastseg ? 1 : 0));
+ SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
+ SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
- SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
- if (rtlpriv->dm.b_useramask) {
- SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
- SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
+ if (rtlpriv->dm.useramask) {
+ SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
+ SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
} else {
- SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
- SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
+ SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
+ SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
}
- if ((!ieee80211_is_data_qos(fc)) && ppsc->b_leisure_ps &&
- ppsc->b_fwctrl_lps) {
+ if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
SET_TX_DESC_HWSEQ_EN(pdesc, 1);
SET_TX_DESC_PKT_ID(pdesc, 8);
- if (!b_defaultadapter)
+ if (!defaultadapter)
SET_TX_DESC_QOS(pdesc, 1);
}
- SET_TX_DESC_MORE_FRAG(pdesc, (b_lastseg ? 0 : 1));
+ SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1));
if (is_multicast_ether_addr(ieee80211_get_DA(hdr)) ||
is_broadcast_ether_addr(ieee80211_get_DA(hdr))) {
SET_TX_DESC_BMC(pdesc, 1);
}
- RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n");
}
void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
- u8 *pdesc, bool b_firstseg,
- bool b_lastseg, struct sk_buff *skb)
+ u8 *pdesc, bool firstseg,
+ bool lastseg, struct sk_buff *skb)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
@@ -901,14 +616,19 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
PCI_DMA_TODEVICE);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
- u16 fc = le16_to_cpu(hdr->frame_control);
+ __le16 fc = hdr->frame_control;
+ if (pci_dma_mapping_error(rtlpci->pdev, mapping)) {
+ RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
+ "DMA mapping error");
+ return;
+ }
CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE);
- if (b_firstseg)
+ if (firstseg)
SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
- SET_TX_DESC_TX_RATE(pdesc, DESC92C_RATE1M);
+ SET_TX_DESC_TX_RATE(pdesc, DESC92_RATE1M);
SET_TX_DESC_SEQ(pdesc, 0);
@@ -921,14 +641,14 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
- SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
SET_TX_DESC_RATE_ID(pdesc, 7);
SET_TX_DESC_MACID(pdesc, 0);
SET_TX_DESC_OWN(pdesc, 1);
- SET_TX_DESC_PKT_SIZE((u8 *) pdesc, (u16) (skb->len));
+ SET_TX_DESC_PKT_SIZE(pdesc, (u16) (skb->len));
SET_TX_DESC_FIRST_SEG(pdesc, 1);
SET_TX_DESC_LAST_SEG(pdesc, 1);
@@ -943,28 +663,30 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw,
}
RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD,
- "H2C Tx Cmd Content\n",
- pdesc, TX_DESC_SIZE);
+ "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE);
}
-void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
+void rtl92ce_set_desc(struct ieee80211_hw *hw, u8 *pdesc, bool istx,
+ u8 desc_name, u8 *val)
{
- if (istx == true) {
+ if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
+ wmb();
SET_TX_DESC_OWN(pdesc, 1);
break;
case HW_DESC_TX_NEXTDESC_ADDR:
SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
break;
default:
- RT_ASSERT(false, ("ERR txdesc :%d"
- " not process\n", desc_name));
+ RT_ASSERT(false, "ERR txdesc :%d not process\n",
+ desc_name);
break;
}
} else {
switch (desc_name) {
case HW_DESC_RXOWN:
+ wmb();
SET_RX_DESC_OWN(pdesc, 1);
break;
case HW_DESC_RXBUFF_ADDR:
@@ -977,8 +699,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
SET_RX_DESC_EOR(pdesc, 1);
break;
default:
- RT_ASSERT(false, ("ERR rxdesc :%d "
- "not process\n", desc_name));
+ RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+ desc_name);
break;
}
}
@@ -988,7 +710,7 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
{
u32 ret = 0;
- if (istx == true) {
+ if (istx) {
switch (desc_name) {
case HW_DESC_OWN:
ret = GET_TX_DESC_OWN(p_desc);
@@ -997,8 +719,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc);
break;
default:
- RT_ASSERT(false, ("ERR txdesc :%d "
- "not process\n", desc_name));
+ RT_ASSERT(false, "ERR txdesc :%d not process\n",
+ desc_name);
break;
}
} else {
@@ -1011,15 +733,15 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name)
ret = GET_RX_DESC_PKT_LEN(pdesc);
break;
default:
- RT_ASSERT(false, ("ERR rxdesc :%d "
- "not process\n", desc_name));
+ RT_ASSERT(false, "ERR rxdesc :%d not process\n",
+ desc_name);
break;
}
}
return ret;
}
-void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
+void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
if (hw_queue == BEACON_QUEUE) {
@@ -1029,3 +751,4 @@ void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
BIT(0) << (hw_queue));
}
}
+