mt76: mt76x02: fix ED/CCA enabling/disabling
authorFelix Fietkau <nbd@nbd.name>
Mon, 25 Feb 2019 16:25:38 +0000 (17:25 +0100)
committerFelix Fietkau <nbd@nbd.name>
Tue, 26 Feb 2019 09:28:19 +0000 (10:28 +0100)
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>
drivers/net/wireless/mediatek/mt76/mt76x0/init.c
drivers/net/wireless/mediatek/mt76/mt76x0/main.c
drivers/net/wireless/mediatek/mt76/mt76x0/phy.c
drivers/net/wireless/mediatek/mt76/mt76x2/mac.c
drivers/net/wireless/mediatek/mt76/mt76x2/pci_phy.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb_mac.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb_main.c
drivers/net/wireless/mediatek/mt76/mt76x2/usb_phy.c

index a529ce1..bcb72e0 100644 (file)
@@ -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) ||
index a803a9b..fee16ab 100644 (file)
@@ -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);
index 3467a32..1fd22eb 100644 (file)
@@ -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);
 
index e25905c..e99d4c9 100644 (file)
@@ -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);
index 97ec575..cc1aebc 100644 (file)
@@ -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);
 
index db2194a..361eb4f 100644 (file)
@@ -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));
 }
index 10633b8..9b438ad 100644 (file)
@@ -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);
index 11d414d..c8b4a17 100644 (file)
@@ -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;
 }