linux/drivers/net/wireless/mediatek/mt76/mt76x2/mac.c
<<
>>
Prefs
   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
   9void 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}
  46EXPORT_SYMBOL_GPL(mt76x2_mac_stop);
  47