198944Sobrien// SPDX-License-Identifier: ISC 246283Sdfr/* 398944Sobrien * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 446283Sdfr * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 5130803Smarcel */ 6130803Smarcel 7130803Smarcel#include "mt76x2.h" 898944Sobrien 946283Sdfrvoid mt76x2_mac_stop(struct mt76x02_dev *dev, bool force) 1098944Sobrien{ 1198944Sobrien bool stopped = false; 1298944Sobrien u32 rts_cfg; 1398944Sobrien int i; 1446283Sdfr 1598944Sobrien mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN); 1698944Sobrien mt76_clear(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN); 1798944Sobrien 1898944Sobrien mt76_wr(dev, MT_MAC_SYS_CTRL, 0); 1946283Sdfr 2098944Sobrien rts_cfg = mt76_rr(dev, MT_TX_RTS_CFG); 2198944Sobrien mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg & ~MT_TX_RTS_CFG_RETRY_LIMIT); 2298944Sobrien 2398944Sobrien /* Wait for MAC to become idle */ 2498944Sobrien for (i = 0; i < 300; i++) { 2598944Sobrien if ((mt76_rr(dev, MT_MAC_STATUS) & 2698944Sobrien (MT_MAC_STATUS_RX | MT_MAC_STATUS_TX)) || 2798944Sobrien mt76_rr(dev, MT_BBP(IBI, 12))) { 2898944Sobrien udelay(1); 2998944Sobrien continue; 3098944Sobrien } 3198944Sobrien 3298944Sobrien stopped = true; 3398944Sobrien break; 3498944Sobrien } 3598944Sobrien 3698944Sobrien if (force && !stopped) { 3798944Sobrien mt76_set(dev, MT_BBP(CORE, 4), BIT(1)); 3846283Sdfr mt76_clear(dev, MT_BBP(CORE, 4), BIT(1)); 3998944Sobrien 4098944Sobrien mt76_set(dev, MT_BBP(CORE, 4), BIT(0)); 4146283Sdfr mt76_clear(dev, MT_BBP(CORE, 4), BIT(0)); 4298944Sobrien } 4398944Sobrien 4446283Sdfr mt76_wr(dev, MT_TX_RTS_CFG, rts_cfg); 4598944Sobrien} 4646283SdfrEXPORT_SYMBOL_GPL(mt76x2_mac_stop); 4798944Sobrien