Commit 5c2a25a1 authored by Benjamin Lin's avatar Benjamin Lin Committed by Felix Fietkau
Browse files

wifi: mt76: mt7996: fix incorrect indexing of MIB FW event



Fix wrong calculation of the channel times due to incorrect
interpretation from the FW event.

Fixes: 98686cd2 ("wifi: mt76: mt7996: add driver for MediaTek Wi-Fi 7 (802.11be) devices")
Signed-off-by: default avatarBenjamin Lin <benjamin-jw.lin@mediatek.com>
Signed-off-by: default avatarShayne Chen <shayne.chen@mediatek.com>
Link: https://patch.msgid.link/20250114101026.3587702-4-shayne.chen@mediatek.com


Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 7e3aef59
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -3678,6 +3678,13 @@ int mt7996_mcu_get_chip_config(struct mt7996_dev *dev, u32 *cap)

int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch)
{
	enum {
		IDX_TX_TIME,
		IDX_RX_TIME,
		IDX_OBSS_AIRTIME,
		IDX_NON_WIFI_TIME,
		IDX_NUM
	};
	struct {
		struct {
			u8 band;
@@ -3687,16 +3694,15 @@ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch)
			__le16 tag;
			__le16 len;
			__le32 offs;
		} data[4];
		} data[IDX_NUM];
	} __packed req = {
		.hdr.band = phy->mt76->band_idx,
	};
	/* strict order */
	static const u32 offs[] = {
		UNI_MIB_TX_TIME,
		UNI_MIB_RX_TIME,
		UNI_MIB_OBSS_AIRTIME,
		UNI_MIB_NON_WIFI_TIME,
		[IDX_TX_TIME] = UNI_MIB_TX_TIME,
		[IDX_RX_TIME] = UNI_MIB_RX_TIME,
		[IDX_OBSS_AIRTIME] = UNI_MIB_OBSS_AIRTIME,
		[IDX_NON_WIFI_TIME] = UNI_MIB_NON_WIFI_TIME,
	};
	struct mt76_channel_state *state = phy->mt76->chan_state;
	struct mt76_channel_state *state_ts = &phy->state_ts;
@@ -3705,7 +3711,7 @@ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch)
	struct sk_buff *skb;
	int i, ret;

	for (i = 0; i < 4; i++) {
	for (i = 0; i < IDX_NUM; i++) {
		req.data[i].tag = cpu_to_le16(UNI_CMD_MIB_DATA);
		req.data[i].len = cpu_to_le16(sizeof(req.data[i]));
		req.data[i].offs = cpu_to_le32(offs[i]);
@@ -3724,17 +3730,24 @@ int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch)
		goto out;

#define __res_u64(s) le64_to_cpu(res[s].data)
	state->cc_tx += __res_u64(1) - state_ts->cc_tx;
	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_busy += __res_u64(0) + __res_u64(1) + __res_u64(2) + __res_u64(3) -
	state->cc_tx += __res_u64(IDX_TX_TIME) - state_ts->cc_tx;
	state->cc_bss_rx += __res_u64(IDX_RX_TIME) - state_ts->cc_bss_rx;
	state->cc_rx += __res_u64(IDX_RX_TIME) +
			__res_u64(IDX_OBSS_AIRTIME) -
			state_ts->cc_rx;
	state->cc_busy += __res_u64(IDX_TX_TIME) +
			  __res_u64(IDX_RX_TIME) +
			  __res_u64(IDX_OBSS_AIRTIME) +
			  __res_u64(IDX_NON_WIFI_TIME) -
			  state_ts->cc_busy;

out:
	state_ts->cc_tx = __res_u64(1);
	state_ts->cc_bss_rx = __res_u64(2);
	state_ts->cc_rx = __res_u64(2) + __res_u64(3);
	state_ts->cc_busy = __res_u64(0) + __res_u64(1) + __res_u64(2) + __res_u64(3);
	state_ts->cc_tx = __res_u64(IDX_TX_TIME);
	state_ts->cc_bss_rx = __res_u64(IDX_RX_TIME);
	state_ts->cc_rx = __res_u64(IDX_RX_TIME) + __res_u64(IDX_OBSS_AIRTIME);
	state_ts->cc_busy = __res_u64(IDX_TX_TIME) +
			    __res_u64(IDX_RX_TIME) +
			    __res_u64(IDX_OBSS_AIRTIME) +
			    __res_u64(IDX_NON_WIFI_TIME);
#undef __res_u64

	dev_kfree_skb(skb);