Commit 0985d3a4 authored by Chris Chiu's avatar Chris Chiu Committed by Kalle Valo

rtl8xxxu: Feed current txrate information for mac80211

The nl80211 commands such as 'iw link' can't get current txrate
information from the driver. This commit fills in the tx rate
information from the C2H RA report in the sta_statistics function.
Signed-off-by: default avatarChris Chiu <chiu@endlessm.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20200320063833.1058-3-chiu@endlessm.com
parent a66b8b41
......@@ -1183,13 +1183,16 @@ struct rtl8723bu_c2h {
} __packed bt_info;
struct {
u8 rate:7;
u8 dummy0_0:1;
u8 sgi:1;
u8 macid;
u8 ldpc:1;
u8 txbf:1;
u8 noisy_state:1;
u8 dummy2_0:5;
u8 dummy3_0;
u8 dummy4_0;
u8 dummy5_0;
u8 bw;
} __packed ra_report;
};
};
......@@ -1269,6 +1272,12 @@ struct rtl8xxxu_btcoex {
#define RTL8XXXU_SNR_THRESH_HIGH 50
#define RTL8XXXU_SNR_THRESH_LOW 20
struct rtl8xxxu_ra_report {
struct rate_info txrate;
u32 bit_rate;
u8 desc_rate;
};
struct rtl8xxxu_priv {
struct ieee80211_hw *hw;
struct usb_device *udev;
......@@ -1384,6 +1393,7 @@ struct rtl8xxxu_priv {
struct sk_buff_head c2hcmd_queue;
spinlock_t c2hcmd_lock;
struct rtl8xxxu_btcoex bt_coex;
struct rtl8xxxu_ra_report ra_report;
};
struct rtl8xxxu_rx_urb {
......
......@@ -5389,6 +5389,35 @@ void rtl8723bu_handle_bt_info(struct rtl8xxxu_priv *priv)
}
}
static struct ieee80211_rate rtl8xxxu_legacy_ratetable[] = {
{.bitrate = 10, .hw_value = 0x00,},
{.bitrate = 20, .hw_value = 0x01,},
{.bitrate = 55, .hw_value = 0x02,},
{.bitrate = 110, .hw_value = 0x03,},
{.bitrate = 60, .hw_value = 0x04,},
{.bitrate = 90, .hw_value = 0x05,},
{.bitrate = 120, .hw_value = 0x06,},
{.bitrate = 180, .hw_value = 0x07,},
{.bitrate = 240, .hw_value = 0x08,},
{.bitrate = 360, .hw_value = 0x09,},
{.bitrate = 480, .hw_value = 0x0a,},
{.bitrate = 540, .hw_value = 0x0b,},
};
static void rtl8xxxu_desc_to_mcsrate(u16 rate, u8 *mcs, u8 *nss)
{
if (rate <= DESC_RATE_54M)
return;
if (rate >= DESC_RATE_MCS0 && rate <= DESC_RATE_MCS15) {
if (rate < DESC_RATE_MCS8)
*nss = 1;
else
*nss = 2;
*mcs = rate - DESC_RATE_MCS0;
}
}
static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
{
struct rtl8xxxu_priv *priv;
......@@ -5397,9 +5426,14 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
unsigned long flags;
u8 bt_info = 0;
struct rtl8xxxu_btcoex *btcoex;
struct rtl8xxxu_ra_report *rarpt;
u8 rate, sgi, bw;
u32 bit_rate;
u8 mcs = 0, nss = 0;
priv = container_of(work, struct rtl8xxxu_priv, c2hcmd_work);
btcoex = &priv->bt_coex;
rarpt = &priv->ra_report;
if (priv->rf_paths > 1)
goto out;
......@@ -5422,6 +5456,34 @@ static void rtl8xxxu_c2hcmd_callback(struct work_struct *work)
}
rtl8723bu_handle_bt_info(priv);
break;
case C2H_8723B_RA_REPORT:
rarpt->txrate.flags = 0;
rate = c2h->ra_report.rate;
sgi = c2h->ra_report.sgi;
bw = c2h->ra_report.bw;
if (rate < DESC_RATE_MCS0) {
rarpt->txrate.legacy =
rtl8xxxu_legacy_ratetable[rate].bitrate;
} else {
rtl8xxxu_desc_to_mcsrate(rate, &mcs, &nss);
rarpt->txrate.flags |= RATE_INFO_FLAGS_MCS;
rarpt->txrate.mcs = mcs;
rarpt->txrate.nss = nss;
if (sgi) {
rarpt->txrate.flags |=
RATE_INFO_FLAGS_SHORT_GI;
}
if (bw == RATE_INFO_BW_20)
rarpt->txrate.bw |= RATE_INFO_BW_20;
}
bit_rate = cfg80211_calculate_bitrate(&rarpt->txrate);
rarpt->bit_rate = bit_rate;
rarpt->desc_rate = rate;
break;
default:
break;
}
......@@ -5465,7 +5527,7 @@ static void rtl8723bu_handle_c2h(struct rtl8xxxu_priv *priv,
case C2H_8723B_RA_REPORT:
dev_dbg(dev,
"C2H RA RPT: rate %02x, unk %i, macid %02x, noise %i\n",
c2h->ra_report.rate, c2h->ra_report.dummy0_0,
c2h->ra_report.rate, c2h->ra_report.sgi,
c2h->ra_report.macid, c2h->ra_report.noisy_state);
break;
default:
......@@ -6069,6 +6131,16 @@ rtl8xxxu_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
return 0;
}
static void
rtl8xxxu_sta_statistics(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta, struct station_info *sinfo)
{
struct rtl8xxxu_priv *priv = hw->priv;
sinfo->txrate = priv->ra_report.txrate;
sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
}
static u8 rtl8xxxu_signal_to_snr(int signal)
{
if (signal < RTL8XXXU_NOISE_FLOOR_MIN)
......@@ -6371,6 +6443,7 @@ static const struct ieee80211_ops rtl8xxxu_ops = {
.sw_scan_complete = rtl8xxxu_sw_scan_complete,
.set_key = rtl8xxxu_set_key,
.ampdu_action = rtl8xxxu_ampdu_action,
.sta_statistics = rtl8xxxu_sta_statistics,
};
static int rtl8xxxu_parse_usb(struct rtl8xxxu_priv *priv,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment