Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Fail-Safe/ac74c2ee5f1b9f5ebdf190617110b0fa to your computer and use it in GitHub Desktop.
Save Fail-Safe/ac74c2ee5f1b9f5ebdf190617110b0fa to your computer and use it in GitHub Desktop.
Updated for mt76 @ c40e648b
From 9b6482b0e42da5b69e5abe4473c99d1d0f518e28 Mon Sep 17 00:00:00 2001
From: rany <ranygh@riseup.net>
Date: Fri, 26 May 2023 19:41:12 +0300
Subject: [PATCH] wifi: mt76: mt7915: do not use event format to get survey
data
Using the event format to get survey data results in the chip
eventually crashing with no chance of recovery. The only possible
course of action is to restart the system and hope it never happens
again.
Signed-off-by: rany <ranygh@riseup.net>
diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
index 915eb3a1..3e92f3f3 100644
--- a/mt76_connac_mcu.h
+++ b/mt76_connac_mcu.h
@@ -1218,7 +1218,6 @@ enum {
MCU_EXT_CMD_EFUSE_FREE_BLOCK = 0x4f,
MCU_EXT_CMD_TX_POWER_FEATURE_CTRL = 0x58,
MCU_EXT_CMD_RXDCOC_CAL = 0x59,
- MCU_EXT_CMD_GET_MIB_INFO = 0x5a,
MCU_EXT_CMD_TXDPD_CAL = 0x60,
MCU_EXT_CMD_CAL_CACHE = 0x67,
MCU_EXT_CMD_RED_ENABLE = 0x68,
diff --git a/mt7915/init.c b/mt7915/init.c
index eee18798..bffc94e3 100644
--- a/mt7915/init.c
+++ b/mt7915/init.c
@@ -515,6 +515,7 @@ mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
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_TIME0(band), mask, set);
mt76_rmw(dev, MT_WF_RMAC_MIB_AIRTIME0(band), mask, set);
/* filter out non-resp frames and get instanstaeous signal reporting */
diff --git a/mt7915/mac.c b/mt7915/mac.c
index 8008ce3f..4cda0938 100644
--- a/mt7915/mac.c
+++ b/mt7915/mac.c
@@ -1146,10 +1146,14 @@ void mt7915_mac_reset_counters(struct mt7915_phy *phy)
memset(phy->mt76->aggr_stats, 0, sizeof(phy->mt76->aggr_stats));
/* reset airtime counters */
+ mt76_rr(dev, MT_MIB_SDR9(phy->mt76->band_idx));
+ mt76_rr(dev, MT_MIB_SDR36(phy->mt76->band_idx));
+ mt76_rr(dev, MT_MIB_SDR37(phy->mt76->band_idx));
+
+ mt76_set(dev, MT_WF_RMAC_MIB_TIME0(phy->mt76->band_idx),
+ MT_WF_RMAC_MIB_RXTIME_CLR);
mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(phy->mt76->band_idx),
MT_WF_RMAC_MIB_RXTIME_CLR);
-
- mt7915_mcu_get_chan_mib_info(phy, true);
}
void mt7915_mac_set_timing(struct mt7915_phy *phy)
@@ -1252,23 +1256,49 @@ mt7915_phy_get_nf(struct mt7915_phy *phy, int idx)
return sum / n;
}
-void mt7915_update_channel(struct mt76_phy *mphy)
+static void
+mt7915_phy_update_channel(struct mt76_phy *mphy, u8 idx)
{
+ struct mt7915_dev *dev = container_of(mphy->dev, struct mt7915_dev, mt76);
struct mt7915_phy *phy = mphy->priv;
struct mt76_channel_state *state = mphy->chan_state;
+ u64 busy_time, tx_time, rx_time, obss_time;
int nf;
- mt7915_mcu_get_chan_mib_info(phy, false);
+ busy_time = mt76_get_field(dev, MT_MIB_SDR9(idx),
+ MT_MIB_SDR9_BUSY_MASK);
+ tx_time = mt76_get_field(dev, MT_MIB_SDR36(idx),
+ MT_MIB_SDR36_TXTIME_MASK);
+ rx_time = mt76_get_field(dev, MT_MIB_SDR37(idx),
+ MT_MIB_SDR37_RXTIME_MASK);
+ obss_time = mt76_get_field(dev, MT_WF_RMAC_MIB_AIRTIME14(idx),
+ MT_MIB_OBSSTIME_MASK);
- nf = mt7915_phy_get_nf(phy, phy->mt76->band_idx);
+ nf = mt7915_phy_get_nf(phy, idx);
if (!phy->noise)
phy->noise = nf << 4;
else if (nf)
phy->noise += nf - (phy->noise >> 4);
+ state->cc_busy += busy_time;
+ state->cc_tx += tx_time;
+ state->cc_rx += rx_time + obss_time;
+ state->cc_bss_rx += rx_time;
state->noise = -(phy->noise >> 4);
}
+void mt7915_update_channel(struct mt76_phy *mphy)
+{
+ struct mt7915_phy *phy = (struct mt7915_phy *)mphy->priv;
+ struct mt7915_dev *dev = phy->dev;
+
+ mt7915_phy_update_channel(mphy, phy->mt76->band_idx);
+
+ /* reset obss airtime */
+ mt76_set(dev, MT_WF_RMAC_MIB_TIME0(phy->mt76->band_idx),
+ MT_WF_RMAC_MIB_RXTIME_CLR);
+}
+
static bool
mt7915_wait_reset_state(struct mt7915_dev *dev, u32 state)
{
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
index 29e9d660..8f0c3f36 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -3086,78 +3086,6 @@ int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy)
return 0;
}
-int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch)
-{
- struct mt76_channel_state *state = phy->mt76->chan_state;
- struct mt76_channel_state *state_ts = &phy->state_ts;
- struct mt7915_dev *dev = phy->dev;
- struct mt7915_mcu_mib *res, req[5];
- struct sk_buff *skb;
- static const u32 *offs;
- int i, ret, len, offs_cc;
- u64 cc_tx;
-
- /* strict order */
- if (is_mt7915(&dev->mt76)) {
- static const u32 chip_offs[] = {
- MIB_NON_WIFI_TIME,
- MIB_TX_TIME,
- MIB_RX_TIME,
- MIB_OBSS_AIRTIME,
- MIB_TXOP_INIT_COUNT,
- };
- len = ARRAY_SIZE(chip_offs);
- offs = chip_offs;
- offs_cc = 20;
- } else {
- static const u32 chip_offs[] = {
- MIB_NON_WIFI_TIME_V2,
- MIB_TX_TIME_V2,
- MIB_RX_TIME_V2,
- MIB_OBSS_AIRTIME_V2
- };
- len = ARRAY_SIZE(chip_offs);
- offs = chip_offs;
- offs_cc = 0;
- }
-
- for (i = 0; i < len; i++) {
- req[i].band = cpu_to_le32(phy->mt76->band_idx);
- req[i].offs = cpu_to_le32(offs[i]);
- }
-
- ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(GET_MIB_INFO),
- req, len * sizeof(req[0]), true, &skb);
- if (ret)
- return ret;
-
- res = (struct mt7915_mcu_mib *)(skb->data + offs_cc);
-
-#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)
- goto out;
-
- state->cc_tx += cc_tx - 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) + cc_tx + __res_u64(2) + __res_u64(3) -
- state_ts->cc_busy;
-
-out:
- state_ts->cc_tx = cc_tx;
- 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) + cc_tx + __res_u64(2) + __res_u64(3);
-#undef __res_u64
-
- dev_kfree_skb(skb);
-
- return 0;
-}
-
int mt7915_mcu_get_temperature(struct mt7915_phy *phy)
{
struct mt7915_dev *dev = phy->dev;
diff --git a/mt7915/mcu.h b/mt7915/mcu.h
index b41ac4aa..c8e5fd9d 100644
--- a/mt7915/mcu.h
+++ b/mt7915/mcu.h
@@ -163,27 +163,6 @@ struct mt7915_mcu_phy_rx_info {
u8 bw;
};
-struct mt7915_mcu_mib {
- __le32 band;
- __le32 offs;
- __le64 data;
-} __packed;
-
-enum mt7915_chan_mib_offs {
- /* mt7915 */
- MIB_TX_TIME = 81,
- MIB_RX_TIME,
- MIB_OBSS_AIRTIME = 86,
- MIB_NON_WIFI_TIME,
- MIB_TXOP_INIT_COUNT,
-
- /* mt7916 */
- MIB_TX_TIME_V2 = 6,
- MIB_RX_TIME_V2 = 8,
- MIB_OBSS_AIRTIME_V2 = 490,
- MIB_NON_WIFI_TIME_V2
-};
-
struct mt7915_mcu_txpower_sku {
u8 format_id;
u8 limit_type;
diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
index a30d08eb..2e02a528 100644
--- a/mt7915/mt7915.h
+++ b/mt7915/mt7915.h
@@ -495,7 +495,6 @@ int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
int mt7915_mcu_set_muru_ctrl(struct mt7915_dev *dev, u32 cmd, u32 val);
int mt7915_mcu_apply_group_cal(struct mt7915_dev *dev);
int mt7915_mcu_apply_tx_dpd(struct mt7915_phy *phy);
-int mt7915_mcu_get_chan_mib_info(struct mt7915_phy *phy, bool chan_switch);
int mt7915_mcu_get_temperature(struct mt7915_phy *phy);
int mt7915_mcu_set_thermal_throttling(struct mt7915_phy *phy, u8 state);
int mt7915_mcu_set_thermal_protect(struct mt7915_phy *phy);
diff --git a/mt7915/regs.h b/mt7915/regs.h
index 89ac8e67..8a0a7ff4 100644
--- a/mt7915/regs.h
+++ b/mt7915/regs.h
@@ -311,6 +311,9 @@ enum offs_rev {
#define MT_MIB_SDR3_FCS_ERR_MASK GENMASK(15, 0)
#define MT_MIB_SDR3_FCS_ERR_MASK_MT7916 GENMASK(31, 16)
+#define MT_MIB_SDR9(_band) MT_WF_MIB(_band, 0x02c)
+#define MT_MIB_SDR9_BUSY_MASK GENMASK(23, 0)
+
#define MT_MIB_SDR4(_band) MT_WF_MIB(_band, __OFFS(MIB_SDR4))
#define MT_MIB_SDR4_RX_FIFO_FULL_MASK GENMASK(15, 0)
@@ -412,6 +415,11 @@ enum offs_rev {
#define MT_MIB_SDR33(_band) MT_WF_MIB(_band, 0x088)
#define MT_MIB_SDR33_TX_PKT_IBF_CNT GENMASK(15, 0)
+#define MT_MIB_SDR36(_band) MT_WF_MIB(_band, 0x098)
+#define MT_MIB_SDR36_TXTIME_MASK GENMASK(23, 0)
+#define MT_MIB_SDR37(_band) MT_WF_MIB(_band, 0x09c)
+#define MT_MIB_SDR37_RXTIME_MASK GENMASK(23, 0)
+
#define MT_MIB_SDRMUBF(_band) MT_WF_MIB(_band, __OFFS(MIB_SDRMUBF))
#define MT_MIB_MU_BF_TX_CNT GENMASK(15, 0)
@@ -556,6 +564,7 @@ enum offs_rev {
#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_TIME0(_band) MT_WF_RMAC(_band, 0x03c4)
#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_OBSS_BACKOFF GENMASK(15, 0)
@@ -570,6 +579,10 @@ enum offs_rev {
#define MT_WF_RMAC_MIB_AIRTIME4(_band) MT_WF_RMAC(_band, 0x0390)
#define MT_WF_RMAC_MIB_QOS23_BACKOFF GENMASK(31, 0)
+#define MT_WF_RMAC_MIB_AIRTIME14(_band) MT_WF_RMAC(_band, 0x03b8)
+#define MT_MIB_OBSSTIME_MASK GENMASK(23, 0)
+#define MT_WF_RMAC_MIB_AIRTIME0(_band) MT_WF_RMAC(_band, 0x0380)
+
/* WFDMA0 */
#define MT_WFDMA0_BASE __REG(WFDMA0_ADDR)
#define MT_WFDMA0(ofs) (MT_WFDMA0_BASE + (ofs))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment