mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
wifi: mt76: mt7915: improve accuracy of time_busy calculation
The MIB INFO command is fetching MIB_BUSY_TIME, MIB_TX_TIME, MIB_RX_TIME and MIB_OBSS_AIRTIME from the radio and filling out cc_busy, cc_tx, cc_bss_rx and cc_rx respectively. busy should be >= tx + rx >= tx + bss_rx but we don’t always quite see this. Sometimes tx + rx is a bit higher than busy due to inaccurate accounting, so this patch recalculates numbers to make them more reasonable. Reported-By: Kevin Schneider <kevin.schneider@adtran.com> Tested-by: Kevin Schneider <kevin.schneider@adtran.com> Tested-by: Chad Monroe <chad.monroe@smartrg.com> Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
@@ -444,6 +444,23 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
|
|||||||
|
|
||||||
/* mt7915: disable rx rate report by default due to hw issues */
|
/* mt7915: disable rx rate report by default due to hw issues */
|
||||||
mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN);
|
mt76_clear(dev, MT_DMA_DCR0(band), MT_DMA_DCR0_RXD_G5_EN);
|
||||||
|
|
||||||
|
/* clear estimated value of EIFS for Rx duration & OBSS time */
|
||||||
|
mt76_wr(dev, MT_WF_RMAC_RSVD0(band), MT_WF_RMAC_RSVD0_EIFS_CLR);
|
||||||
|
|
||||||
|
/* clear backoff time for Rx duration */
|
||||||
|
mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME1(band),
|
||||||
|
MT_WF_RMAC_MIB_NONQOSD_BACKOFF);
|
||||||
|
mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME3(band),
|
||||||
|
MT_WF_RMAC_MIB_QOS01_BACKOFF);
|
||||||
|
mt76_clear(dev, MT_WF_RMAC_MIB_AIRTIME4(band),
|
||||||
|
MT_WF_RMAC_MIB_QOS23_BACKOFF);
|
||||||
|
|
||||||
|
/* clear backoff time and set software compensation for OBSS time */
|
||||||
|
mask = MT_WF_RMAC_MIB_OBSS_BACKOFF | MT_WF_RMAC_MIB_ED_OFFSET;
|
||||||
|
set = FIELD_PREP(MT_WF_RMAC_MIB_OBSS_BACKOFF, 0) |
|
||||||
|
FIELD_PREP(MT_WF_RMAC_MIB_ED_OFFSET, 4);
|
||||||
|
mt76_rmw(dev, MT_WF_RMAC_MIB_AIRTIME0(band), mask, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mt7915_mac_init(struct mt7915_dev *dev)
|
static void mt7915_mac_init(struct mt7915_dev *dev)
|
||||||
|
|||||||
@@ -2940,25 +2940,36 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
|
|||||||
{
|
{
|
||||||
/* strict order */
|
/* strict order */
|
||||||
static const u32 offs[] = {
|
static const u32 offs[] = {
|
||||||
MIB_BUSY_TIME, MIB_TX_TIME, MIB_RX_TIME, MIB_OBSS_AIRTIME,
|
MIB_NON_WIFI_TIME,
|
||||||
MIB_BUSY_TIME_V2, MIB_TX_TIME_V2, MIB_RX_TIME_V2,
|
MIB_TX_TIME,
|
||||||
|
MIB_RX_TIME,
|
||||||
|
MIB_OBSS_AIRTIME,
|
||||||
|
MIB_TXOP_INIT_COUNT,
|
||||||
|
/* v2 */
|
||||||
|
MIB_NON_WIFI_TIME_V2,
|
||||||
|
MIB_TX_TIME_V2,
|
||||||
|
MIB_RX_TIME_V2,
|
||||||
MIB_OBSS_AIRTIME_V2
|
MIB_OBSS_AIRTIME_V2
|
||||||
};
|
};
|
||||||
struct mt76_channel_state *state = phy->mt76->chan_state;
|
struct mt76_channel_state *state = phy->mt76->chan_state;
|
||||||
struct mt76_channel_state *state_ts = &phy->state_ts;
|
struct mt76_channel_state *state_ts = &phy->state_ts;
|
||||||
struct mt7915_dev *dev = phy->dev;
|
struct mt7915_dev *dev = phy->dev;
|
||||||
struct mt7915_mcu_mib *res, req[4];
|
struct mt7915_mcu_mib *res, req[5];
|
||||||
struct sk_buff *skb;
|
struct sk_buff *skb;
|
||||||
int i, ret, start = 0, ofs = 20;
|
int i, ret, start = 0, ofs = 20;
|
||||||
|
u64 cc_tx;
|
||||||
|
|
||||||
if (!is_mt7915(&dev->mt76)) {
|
if (!is_mt7915(&dev->mt76)) {
|
||||||
start = 4;
|
start = 5;
|
||||||
ofs = 0;
|
ofs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 5; i++) {
|
||||||
req[i].band = cpu_to_le32(phy != &dev->phy);
|
req[i].band = cpu_to_le32(phy != &dev->phy);
|
||||||
req[i].offs = cpu_to_le32(offs[i + start]);
|
req[i].offs = cpu_to_le32(offs[i + start]);
|
||||||
|
|
||||||
|
if (!is_mt7915(&dev->mt76) && i == 3)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO),
|
ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO),
|
||||||
@@ -2968,20 +2979,24 @@ int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
|
|||||||
|
|
||||||
res = (struct mt7915_mcu_mib *)(skb->data + ofs);
|
res = (struct mt7915_mcu_mib *)(skb->data + ofs);
|
||||||
|
|
||||||
|
#define __res_u64(s) le64_to_cpu(res[s].data)
|
||||||
|
/* subtract Tx backoff time from Tx duration */
|
||||||
|
cc_tx = is_mt7915(&dev->mt76) ? __res_u64(1) - __res_u64(4) : __res_u64(1);
|
||||||
|
|
||||||
if (chan_switch)
|
if (chan_switch)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
#define __res_u64(s) le64_to_cpu(res[s].data)
|
state->cc_tx += cc_tx - state_ts->cc_tx;
|
||||||
state->cc_busy += __res_u64(0) - state_ts->cc_busy;
|
|
||||||
state->cc_tx += __res_u64(1) - state_ts->cc_tx;
|
|
||||||
state->cc_bss_rx += __res_u64(2) - state_ts->cc_bss_rx;
|
state->cc_bss_rx += __res_u64(2) - state_ts->cc_bss_rx;
|
||||||
state->cc_rx += __res_u64(2) + __res_u64(3) - state_ts->cc_rx;
|
state->cc_rx += __res_u64(2) + __res_u64(3) - state_ts->cc_rx;
|
||||||
|
state->cc_busy += __res_u64(0) + cc_tx + __res_u64(2) + __res_u64(3) -
|
||||||
|
state_ts->cc_busy;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
state_ts->cc_busy = __res_u64(0);
|
state_ts->cc_tx = cc_tx;
|
||||||
state_ts->cc_tx = __res_u64(1);
|
|
||||||
state_ts->cc_bss_rx = __res_u64(2);
|
state_ts->cc_bss_rx = __res_u64(2);
|
||||||
state_ts->cc_rx = __res_u64(2) + __res_u64(3);
|
state_ts->cc_rx = __res_u64(2) + __res_u64(3);
|
||||||
|
state_ts->cc_busy = __res_u64(0) + cc_tx + __res_u64(2) + __res_u64(3);
|
||||||
#undef __res_u64
|
#undef __res_u64
|
||||||
|
|
||||||
dev_kfree_skb(skb);
|
dev_kfree_skb(skb);
|
||||||
|
|||||||
@@ -160,15 +160,17 @@ struct mt7915_mcu_mib {
|
|||||||
|
|
||||||
enum mt7915_chan_mib_offs {
|
enum mt7915_chan_mib_offs {
|
||||||
/* mt7915 */
|
/* mt7915 */
|
||||||
MIB_BUSY_TIME = 14,
|
|
||||||
MIB_TX_TIME = 81,
|
MIB_TX_TIME = 81,
|
||||||
MIB_RX_TIME,
|
MIB_RX_TIME,
|
||||||
MIB_OBSS_AIRTIME = 86,
|
MIB_OBSS_AIRTIME = 86,
|
||||||
|
MIB_NON_WIFI_TIME,
|
||||||
|
MIB_TXOP_INIT_COUNT,
|
||||||
|
|
||||||
/* mt7916 */
|
/* mt7916 */
|
||||||
MIB_BUSY_TIME_V2 = 0,
|
|
||||||
MIB_TX_TIME_V2 = 6,
|
MIB_TX_TIME_V2 = 6,
|
||||||
MIB_RX_TIME_V2 = 8,
|
MIB_RX_TIME_V2 = 8,
|
||||||
MIB_OBSS_AIRTIME_V2 = 490
|
MIB_OBSS_AIRTIME_V2 = 490,
|
||||||
|
MIB_NON_WIFI_TIME_V2
|
||||||
};
|
};
|
||||||
|
|
||||||
struct edca {
|
struct edca {
|
||||||
|
|||||||
@@ -525,8 +525,22 @@ enum offs_rev {
|
|||||||
#define MT_WF_RFCR1_DROP_CFEND BIT(7)
|
#define MT_WF_RFCR1_DROP_CFEND BIT(7)
|
||||||
#define MT_WF_RFCR1_DROP_CFACK BIT(8)
|
#define MT_WF_RFCR1_DROP_CFACK BIT(8)
|
||||||
|
|
||||||
|
#define MT_WF_RMAC_RSVD0(_band) MT_WF_RMAC(_band, 0x02e0)
|
||||||
|
#define MT_WF_RMAC_RSVD0_EIFS_CLR BIT(21)
|
||||||
|
|
||||||
#define MT_WF_RMAC_MIB_AIRTIME0(_band) MT_WF_RMAC(_band, 0x0380)
|
#define MT_WF_RMAC_MIB_AIRTIME0(_band) MT_WF_RMAC(_band, 0x0380)
|
||||||
#define MT_WF_RMAC_MIB_RXTIME_CLR BIT(31)
|
#define MT_WF_RMAC_MIB_RXTIME_CLR BIT(31)
|
||||||
|
#define MT_WF_RMAC_MIB_OBSS_BACKOFF GENMASK(15, 0)
|
||||||
|
#define MT_WF_RMAC_MIB_ED_OFFSET GENMASK(20, 16)
|
||||||
|
|
||||||
|
#define MT_WF_RMAC_MIB_AIRTIME1(_band) MT_WF_RMAC(_band, 0x0384)
|
||||||
|
#define MT_WF_RMAC_MIB_NONQOSD_BACKOFF GENMASK(31, 16)
|
||||||
|
|
||||||
|
#define MT_WF_RMAC_MIB_AIRTIME3(_band) MT_WF_RMAC(_band, 0x038c)
|
||||||
|
#define MT_WF_RMAC_MIB_QOS01_BACKOFF GENMASK(31, 0)
|
||||||
|
|
||||||
|
#define MT_WF_RMAC_MIB_AIRTIME4(_band) MT_WF_RMAC(_band, 0x0390)
|
||||||
|
#define MT_WF_RMAC_MIB_QOS23_BACKOFF GENMASK(31, 0)
|
||||||
|
|
||||||
/* WFDMA0 */
|
/* WFDMA0 */
|
||||||
#define MT_WFDMA0_BASE __REG(WFDMA0_ADDR)
|
#define MT_WFDMA0_BASE __REG(WFDMA0_ADDR)
|
||||||
|
|||||||
Reference in New Issue
Block a user