Commit b4c268ca authored by Ryder Lee's avatar Ryder Lee Committed by Felix Fietkau
Browse files

mt76: mt7915: introduce mt7915_mac_severe_check()



In rare cases, TRB pointers might be out of sync leads to RMAC stopping
Rx that requires minimal recovery, so add this helper to periodically
check TRB status.

Tested-by: default avatarChad Monroe <chad.monroe@smartrg.com>
Signed-off-by: default avatarRyder Lee <ryder.lee@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent bdd2ca78
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -2305,6 +2305,32 @@ void mt7915_mac_update_stats(struct mt7915_phy *phy)
	}
}

static void mt7915_mac_severe_check(struct mt7915_phy *phy)
{
	struct mt7915_dev *dev = phy->dev;
	bool ext_phy = phy != &dev->phy;
	u32 trb;

	if (!phy->omac_mask)
		return;

	/* In rare cases, TRB pointers might be out of sync leads to RMAC
	 * stopping Rx, so check status periodically to see if TRB hardware
	 * requires minimal recovery.
	 */
	trb = mt76_rr(dev, MT_TRB_RXPSR0(phy->band_idx));

	if ((FIELD_GET(MT_TRB_RXPSR0_RX_RMAC_PTR, trb) !=
	     FIELD_GET(MT_TRB_RXPSR0_RX_WTBL_PTR, trb)) &&
	    (FIELD_GET(MT_TRB_RXPSR0_RX_RMAC_PTR, phy->trb_ts) !=
	     FIELD_GET(MT_TRB_RXPSR0_RX_WTBL_PTR, phy->trb_ts)) &&
	    trb == phy->trb_ts)
		mt7915_mcu_set_ser(dev, SER_RECOVER, SER_SET_RECOVER_L3_RX_ABORT,
				   ext_phy);

	phy->trb_ts = trb;
}

void mt7915_mac_sta_rc_work(struct work_struct *work)
{
	struct mt7915_dev *dev = container_of(work, struct mt7915_dev, rc_work);
@@ -2357,6 +2383,7 @@ void mt7915_mac_work(struct work_struct *work)
		mphy->mac_work_count = 0;

		mt7915_mac_update_stats(phy);
		mt7915_mac_severe_check(phy);
	}

	mutex_unlock(&mphy->dev->mutex);
+2 −0
Original line number Diff line number Diff line
@@ -248,6 +248,8 @@ struct mt7915_phy {

	u8 rdd_state;

	u32 trb_ts;

	u32 rx_ampdu_ts;
	u32 ampdu_ref;

+8 −0
Original line number Diff line number Diff line
@@ -176,6 +176,14 @@ enum offs_rev {
#define MT_MDP_TO_HIF			0
#define MT_MDP_TO_WM			1

/* TRB: band 0(0x820e1000), band 1(0x820f1000) */
#define MT_WF_TRB_BASE(_band)		((_band) ? 0x820f1000 : 0x820e1000)
#define MT_WF_TRB(_band, ofs)		(MT_WF_TRB_BASE(_band) + (ofs))

#define MT_TRB_RXPSR0(_band)		MT_WF_TRB(_band, 0x03c)
#define MT_TRB_RXPSR0_RX_WTBL_PTR	GENMASK(25, 16)
#define MT_TRB_RXPSR0_RX_RMAC_PTR	GENMASK(9, 0)

/* TMAC: band 0(0x820e4000), band 1(0x820f4000) */
#define MT_WF_TMAC_BASE(_band)		((_band) ? 0x820f4000 : 0x820e4000)
#define MT_WF_TMAC(_band, ofs)		(MT_WF_TMAC_BASE(_band) + (ofs))