1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 5 */ 6 7 #include "mt76x2.h" 8 9 void mt76x2_mac_stop(struct mt76x02_dev *dev, bool force) 10 { 11 bool stopped = false; 12 u32 rts_cfg; 13 int i; 14 15 mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN); 16 mt76_clear(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN); 17 18 mt76_wr(dev, MT_MAC_SYS_CTRL, 0); 19 20 rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG); 21 mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT); 22 23 /* Wait for MAC to become idle */ 24 for (i = 0; i < 300; i++) { 25 if ((mt76_rr(dev, MT_MAC_STATUS) & 26 (MT_MAC_STATUS_RX | MT_MAC_STATUS_TX)) || 27 mt76_rr(dev, MT_BBP(IBI, 12))) { 28 udelay(1); 29 continue; 30 } 31 32 stopped = true; 33 break; 34 } 35 36 if (force && !stopped) { 37 mt76_set(dev, MT_BBP(CORE, 4), BIT(1)); 38 mt76_clear(dev, MT_BBP(CORE, 4), BIT(1)); 39 40 mt76_set(dev, MT_BBP(CORE, 4), BIT(0)); 41 mt76_clear(dev, MT_BBP(CORE, 4), BIT(0)); 42 } 43 44 mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg); 45 } 46 EXPORT_SYMBOL_GPL(mt76x2_mac_stop); 47