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 a529ce111c2035c597753423cd8fd2c9402c51ab..bcb72e019fd2b8c435a960ffbf8345f9d18d45b4 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 a803a9b6a4c52fce069e0207f0e99bb8f14ae92b..fee16ab21edb20c0dfa2459ed45dba304b83428c 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 3467a32f5fdaeb7a1c170724b55e3217280befd9..1fd22eb841c388e71625e1229ee4292be7e21d8a 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 e25905c91ee208f459251ed4ea0194c18c50fe1d..e99d4c9bd428130d10b55cb9cabae019aff7369f 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 97ec575699d021e409bd76fd0aeff91418f8d4c2..cc1aebcb069666ea44186e94dc1016c7ee48450f 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 db2194a92e674f693957d250421dab0850b46f8d..361eb4fb979ddf95046d6b7d4af8378bd738a20a 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 10633b8de8e8e41a9955dc7bf31f4abcd066036c..9b438adfc56c85061a022c46d6328b458e0155c7 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 11d414d86c68edf59fe4b919c770abd9c24f8bc9..c8b4a17302da1b923fe1b25fbdef4586654c3367 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;
 }