mt76: mt76x02: fix ED/CCA enabling/disabling
ED/CCA needs to be disable before stopping the MAC to avoid hangs from tx being blocked. It must only be enabled again after the MAC has been started again. In many places this wasn't done properly, so fix this by always clearing the relevant ED/CCA bits in mt76x2_mac_stop and set it up again after channel change or calibration is done Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
72e5d479b8
commit
4606a26c0c
|
@ -187,6 +187,8 @@ void mt76x0_mac_stop(struct mt76x02_dev *dev)
|
|||
{
|
||||
int i = 200, ok = 0;
|
||||
|
||||
mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
|
||||
|
||||
/* Page count on TxQ */
|
||||
while (i-- && ((mt76_rr(dev, 0x0438) & 0xffffffff) ||
|
||||
(mt76_rr(dev, 0x0a30) & 0x000000ff) ||
|
||||
|
|
|
@ -34,6 +34,8 @@ mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
|
|||
mt76_rr(dev, MT_CH_IDLE);
|
||||
mt76_rr(dev, MT_CH_BUSY);
|
||||
|
||||
mt76x02_edcca_init(dev, true);
|
||||
|
||||
if (mt76_is_mmio(dev)) {
|
||||
mt76x02_dfs_init_params(dev);
|
||||
tasklet_enable(&dev->pre_tbtt_tasklet);
|
||||
|
|
|
@ -1007,17 +1007,13 @@ int mt76x0_phy_set_channel(struct mt76x02_dev *dev,
|
|||
|
||||
/* enable vco */
|
||||
mt76x0_rf_set(dev, MT_RF(0, 4), BIT(7));
|
||||
if (scan) {
|
||||
mt76x02_edcca_init(dev, false);
|
||||
if (scan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mt76x02_init_agc_gain(dev);
|
||||
mt76x0_phy_calibrate(dev, false);
|
||||
mt76x0_phy_set_txpower(dev);
|
||||
|
||||
mt76x02_edcca_init(dev, true);
|
||||
|
||||
ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
|
||||
MT_CALIBRATE_INTERVAL);
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ void mt76x2_mac_stop(struct mt76x02_dev *dev, bool force)
|
|||
u32 rts_cfg;
|
||||
int i;
|
||||
|
||||
mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
|
||||
mt76_clear(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN);
|
||||
|
||||
mt76_wr(dev, MT_MAC_SYS_CTRL, 0);
|
||||
|
||||
rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
|
||||
|
|
|
@ -74,6 +74,7 @@ mt76x2_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped)
|
|||
mt76x2_mac_resume(dev);
|
||||
|
||||
mt76x2_apply_gain_adj(dev);
|
||||
mt76x02_edcca_init(dev, true);
|
||||
|
||||
dev->cal.channel_cal_done = true;
|
||||
}
|
||||
|
@ -240,10 +241,8 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
|
|||
mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
|
||||
mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F);
|
||||
|
||||
if (scan) {
|
||||
mt76x02_edcca_init(dev, false);
|
||||
if (scan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
mt76x2_phy_channel_calibrate(dev, true);
|
||||
mt76x02_init_agc_gain(dev);
|
||||
|
@ -256,8 +255,6 @@ int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
|
|||
0x38);
|
||||
}
|
||||
|
||||
mt76x02_edcca_init(dev, true);
|
||||
|
||||
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
|
||||
MT_CALIBRATE_INTERVAL);
|
||||
|
||||
|
|
|
@ -143,8 +143,8 @@ int mt76x2u_mac_stop(struct mt76x02_dev *dev)
|
|||
rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG);
|
||||
mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT);
|
||||
|
||||
mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
|
||||
mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
|
||||
mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
|
||||
mt76_clear(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN);
|
||||
|
||||
/* wait tx dma to stop */
|
||||
for (i = 0; i < 2000; i++) {
|
||||
|
@ -217,6 +217,4 @@ void mt76x2u_mac_resume(struct mt76x02_dev *dev)
|
|||
mt76_wr(dev, MT_MAC_SYS_CTRL,
|
||||
MT_MAC_SYS_CTRL_ENABLE_TX |
|
||||
MT_MAC_SYS_CTRL_ENABLE_RX);
|
||||
mt76_set(dev, MT_TXOP_CTRL_CFG, BIT(20));
|
||||
mt76_set(dev, MT_TXOP_HLDR_ET, BIT(1));
|
||||
}
|
||||
|
|
|
@ -57,13 +57,12 @@ mt76x2u_set_channel(struct mt76x02_dev *dev,
|
|||
|
||||
mt76_set_channel(&dev->mt76);
|
||||
|
||||
mt76_clear(dev, MT_TXOP_CTRL_CFG, BIT(20));
|
||||
mt76_clear(dev, MT_TXOP_HLDR_ET, BIT(1));
|
||||
mt76x2_mac_stop(dev, false);
|
||||
|
||||
err = mt76x2u_phy_set_channel(dev, chandef);
|
||||
|
||||
mt76x2u_mac_resume(dev);
|
||||
mt76x02_edcca_init(dev, true);
|
||||
|
||||
clear_bit(MT76_RESET, &dev->mt76.state);
|
||||
mt76_txq_schedule_all(&dev->mt76);
|
||||
|
|
|
@ -45,6 +45,7 @@ mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped)
|
|||
if (!mac_stopped)
|
||||
mt76x2u_mac_resume(dev);
|
||||
mt76x2_apply_gain_adj(dev);
|
||||
mt76x02_edcca_init(dev, true);
|
||||
|
||||
dev->cal.channel_cal_done = true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue