linux/drivers/net/wireless/mediatek/mt76/mt7915/dma.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2/* Copyright (C) 2020 MediaTek Inc. */
   3
   4#include "mt7915.h"
   5#include "../dma.h"
   6#include "mac.h"
   7
   8static int
   9mt7915_init_tx_queues(struct mt7915_dev *dev, int n_desc)
  10{
  11        struct mt76_sw_queue *q;
  12        struct mt76_queue *hwq;
  13        int err, i;
  14
  15        hwq = devm_kzalloc(dev->mt76.dev, sizeof(*hwq), GFP_KERNEL);
  16        if (!hwq)
  17                return -ENOMEM;
  18
  19        err = mt76_queue_alloc(dev, hwq, MT7915_TXQ_BAND0, n_desc, 0,
  20                               MT_TX_RING_BASE);
  21        if (err < 0)
  22                return err;
  23
  24        for (i = 0; i < MT_TXQ_MCU; i++) {
  25                q = &dev->mt76.q_tx[i];
  26                INIT_LIST_HEAD(&q->swq);
  27                q->q = hwq;
  28        }
  29
  30        return 0;
  31}
  32
  33static int
  34mt7915_init_mcu_queue(struct mt7915_dev *dev, struct mt76_sw_queue *q,
  35                      int idx, int n_desc)
  36{
  37        struct mt76_queue *hwq;
  38        int err;
  39
  40        hwq = devm_kzalloc(dev->mt76.dev, sizeof(*hwq), GFP_KERNEL);
  41        if (!hwq)
  42                return -ENOMEM;
  43
  44        err = mt76_queue_alloc(dev, hwq, idx, n_desc, 0, MT_TX_RING_BASE);
  45        if (err < 0)
  46                return err;
  47
  48        INIT_LIST_HEAD(&q->swq);
  49        q->q = hwq;
  50
  51        return 0;
  52}
  53
  54void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
  55                         struct sk_buff *skb)
  56{
  57        struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
  58        __le32 *rxd = (__le32 *)skb->data;
  59        enum rx_pkt_type type;
  60
  61        type = FIELD_GET(MT_RXD0_PKT_TYPE, le32_to_cpu(rxd[0]));
  62
  63        switch (type) {
  64        case PKT_TYPE_TXRX_NOTIFY:
  65                mt7915_mac_tx_free(dev, skb);
  66                break;
  67        case PKT_TYPE_RX_EVENT:
  68                mt7915_mcu_rx_event(dev, skb);
  69                break;
  70        case PKT_TYPE_NORMAL:
  71                if (!mt7915_mac_fill_rx(dev, skb)) {
  72                        mt76_rx(&dev->mt76, q, skb);
  73                        return;
  74                }
  75                /* fall through */
  76        default:
  77                dev_kfree_skb(skb);
  78                break;
  79        }
  80}
  81
  82static void
  83mt7915_tx_cleanup(struct mt7915_dev *dev)
  84{
  85        mt76_queue_tx_cleanup(dev, MT_TXQ_MCU, false);
  86        mt76_queue_tx_cleanup(dev, MT_TXQ_MCU_WA, false);
  87        mt76_queue_tx_cleanup(dev, MT_TXQ_PSD, false);
  88        mt76_queue_tx_cleanup(dev, MT_TXQ_BE, false);
  89}
  90
  91static int mt7915_poll_tx(struct napi_struct *napi, int budget)
  92{
  93        struct mt7915_dev *dev;
  94
  95        dev = container_of(napi, struct mt7915_dev, mt76.tx_napi);
  96
  97        mt7915_tx_cleanup(dev);
  98
  99        if (napi_complete_done(napi, 0))
 100                mt7915_irq_enable(dev, MT_INT_TX_DONE_ALL);
 101
 102        mt7915_tx_cleanup(dev);
 103
 104        mt7915_mac_sta_poll(dev);
 105
 106        tasklet_schedule(&dev->mt76.tx_tasklet);
 107
 108        return 0;
 109}
 110
 111void mt7915_dma_prefetch(struct mt7915_dev *dev)
 112{
 113#define PREFETCH(base, depth)   ((base) << 16 | (depth))
 114
 115        mt76_wr(dev, MT_WFDMA0_RX_RING0_EXT_CTRL, PREFETCH(0x0, 0x4));
 116        mt76_wr(dev, MT_WFDMA0_RX_RING1_EXT_CTRL, PREFETCH(0x40, 0x4));
 117        mt76_wr(dev, MT_WFDMA0_RX_RING2_EXT_CTRL, PREFETCH(0x80, 0x0));
 118
 119        mt76_wr(dev, MT_WFDMA1_TX_RING0_EXT_CTRL, PREFETCH(0x80, 0x4));
 120        mt76_wr(dev, MT_WFDMA1_TX_RING1_EXT_CTRL, PREFETCH(0xc0, 0x4));
 121        mt76_wr(dev, MT_WFDMA1_TX_RING2_EXT_CTRL, PREFETCH(0x100, 0x4));
 122        mt76_wr(dev, MT_WFDMA1_TX_RING3_EXT_CTRL, PREFETCH(0x140, 0x4));
 123        mt76_wr(dev, MT_WFDMA1_TX_RING4_EXT_CTRL, PREFETCH(0x180, 0x4));
 124        mt76_wr(dev, MT_WFDMA1_TX_RING5_EXT_CTRL, PREFETCH(0x1c0, 0x4));
 125        mt76_wr(dev, MT_WFDMA1_TX_RING6_EXT_CTRL, PREFETCH(0x200, 0x4));
 126        mt76_wr(dev, MT_WFDMA1_TX_RING7_EXT_CTRL, PREFETCH(0x240, 0x4));
 127
 128        mt76_wr(dev, MT_WFDMA1_TX_RING16_EXT_CTRL, PREFETCH(0x280, 0x4));
 129        mt76_wr(dev, MT_WFDMA1_TX_RING17_EXT_CTRL, PREFETCH(0x2c0, 0x4));
 130        mt76_wr(dev, MT_WFDMA1_TX_RING18_EXT_CTRL, PREFETCH(0x300, 0x4));
 131        mt76_wr(dev, MT_WFDMA1_TX_RING19_EXT_CTRL, PREFETCH(0x340, 0x4));
 132        mt76_wr(dev, MT_WFDMA1_TX_RING20_EXT_CTRL, PREFETCH(0x380, 0x4));
 133        mt76_wr(dev, MT_WFDMA1_TX_RING21_EXT_CTRL, PREFETCH(0x3c0, 0x0));
 134
 135        mt76_wr(dev, MT_WFDMA1_RX_RING0_EXT_CTRL, PREFETCH(0x3c0, 0x4));
 136        mt76_wr(dev, MT_WFDMA1_RX_RING1_EXT_CTRL, PREFETCH(0x400, 0x4));
 137        mt76_wr(dev, MT_WFDMA1_RX_RING2_EXT_CTRL, PREFETCH(0x440, 0x4));
 138        mt76_wr(dev, MT_WFDMA1_RX_RING3_EXT_CTRL, PREFETCH(0x480, 0x0));
 139}
 140
 141int mt7915_dma_init(struct mt7915_dev *dev)
 142{
 143        /* Increase buffer size to receive large VHT/HE MPDUs */
 144        int rx_buf_size = MT_RX_BUF_SIZE * 2;
 145        int ret;
 146
 147        mt76_dma_attach(&dev->mt76);
 148
 149        /* configure global setting */
 150        mt76_set(dev, MT_WFDMA1_GLO_CFG,
 151                 MT_WFDMA1_GLO_CFG_OMIT_TX_INFO |
 152                 MT_WFDMA1_GLO_CFG_OMIT_RX_INFO);
 153
 154        /* configure perfetch settings */
 155        mt7915_dma_prefetch(dev);
 156
 157        /* reset dma idx */
 158        mt76_wr(dev, MT_WFDMA0_RST_DTX_PTR, ~0);
 159        mt76_wr(dev, MT_WFDMA1_RST_DTX_PTR, ~0);
 160
 161        /* configure delay interrupt */
 162        mt76_wr(dev, MT_WFDMA0_PRI_DLY_INT_CFG0, 0);
 163        mt76_wr(dev, MT_WFDMA1_PRI_DLY_INT_CFG0, 0);
 164
 165        /* init tx queue */
 166        ret = mt7915_init_tx_queues(dev, MT7915_TX_RING_SIZE);
 167        if (ret)
 168                return ret;
 169
 170        /* command to WM */
 171        ret = mt7915_init_mcu_queue(dev, &dev->mt76.q_tx[MT_TXQ_MCU],
 172                                    MT7915_TXQ_MCU_WM,
 173                                    MT7915_TX_MCU_RING_SIZE);
 174        if (ret)
 175                return ret;
 176
 177        /* command to WA */
 178        ret = mt7915_init_mcu_queue(dev, &dev->mt76.q_tx[MT_TXQ_MCU_WA],
 179                                    MT7915_TXQ_MCU_WA,
 180                                    MT7915_TX_MCU_RING_SIZE);
 181        if (ret)
 182                return ret;
 183
 184        /* firmware download */
 185        ret = mt7915_init_mcu_queue(dev, &dev->mt76.q_tx[MT_TXQ_FWDL],
 186                                    MT7915_TXQ_FWDL,
 187                                    MT7915_TX_FWDL_RING_SIZE);
 188        if (ret)
 189                return ret;
 190
 191        /* event from WM */
 192        ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU],
 193                               MT7915_RXQ_MCU_WM, MT7915_RX_MCU_RING_SIZE,
 194                               rx_buf_size, MT_RX_EVENT_RING_BASE);
 195        if (ret)
 196                return ret;
 197
 198        /* event from WA */
 199        ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MCU_WA],
 200                               MT7915_RXQ_MCU_WA, MT7915_RX_MCU_RING_SIZE,
 201                               rx_buf_size, MT_RX_EVENT_RING_BASE);
 202        if (ret)
 203                return ret;
 204
 205        /* rx data */
 206        ret = mt76_queue_alloc(dev, &dev->mt76.q_rx[MT_RXQ_MAIN], 0,
 207                               MT7915_RX_RING_SIZE, rx_buf_size,
 208                               MT_RX_DATA_RING_BASE);
 209        if (ret)
 210                return ret;
 211
 212        ret = mt76_init_queues(dev);
 213        if (ret < 0)
 214                return ret;
 215
 216        netif_tx_napi_add(&dev->mt76.napi_dev, &dev->mt76.tx_napi,
 217                          mt7915_poll_tx, NAPI_POLL_WEIGHT);
 218        napi_enable(&dev->mt76.tx_napi);
 219
 220        /* hif wait WFDMA idle */
 221        mt76_set(dev, MT_WFDMA0_BUSY_ENA,
 222                 MT_WFDMA0_BUSY_ENA_TX_FIFO0 |
 223                 MT_WFDMA0_BUSY_ENA_TX_FIFO1 |
 224                 MT_WFDMA0_BUSY_ENA_RX_FIFO);
 225
 226        mt76_set(dev, MT_WFDMA1_BUSY_ENA,
 227                 MT_WFDMA1_BUSY_ENA_TX_FIFO0 |
 228                 MT_WFDMA1_BUSY_ENA_TX_FIFO1 |
 229                 MT_WFDMA1_BUSY_ENA_RX_FIFO);
 230
 231        mt76_set(dev, MT_WFDMA0_PCIE1_BUSY_ENA,
 232                 MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO0 |
 233                 MT_WFDMA0_PCIE1_BUSY_ENA_TX_FIFO1 |
 234                 MT_WFDMA0_PCIE1_BUSY_ENA_RX_FIFO);
 235
 236        mt76_set(dev, MT_WFDMA1_PCIE1_BUSY_ENA,
 237                 MT_WFDMA1_PCIE1_BUSY_ENA_TX_FIFO0 |
 238                 MT_WFDMA1_PCIE1_BUSY_ENA_TX_FIFO1 |
 239                 MT_WFDMA1_PCIE1_BUSY_ENA_RX_FIFO);
 240
 241        mt76_poll(dev, MT_WFDMA_EXT_CSR_HIF_MISC,
 242                  MT_WFDMA_EXT_CSR_HIF_MISC_BUSY, 0, 1000);
 243
 244        /* set WFDMA Tx/Rx */
 245        mt76_set(dev, MT_WFDMA0_GLO_CFG,
 246                 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
 247        mt76_set(dev, MT_WFDMA1_GLO_CFG,
 248                 MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN);
 249
 250        /* enable interrupts for TX/RX rings */
 251        mt7915_irq_enable(dev, MT_INT_RX_DONE_ALL | MT_INT_TX_DONE_ALL |
 252                          MT_INT_MCU_CMD);
 253
 254        return 0;
 255}
 256
 257void mt7915_dma_cleanup(struct mt7915_dev *dev)
 258{
 259        /* disable */
 260        mt76_clear(dev, MT_WFDMA0_GLO_CFG,
 261                   MT_WFDMA0_GLO_CFG_TX_DMA_EN |
 262                   MT_WFDMA0_GLO_CFG_RX_DMA_EN);
 263        mt76_clear(dev, MT_WFDMA1_GLO_CFG,
 264                   MT_WFDMA1_GLO_CFG_TX_DMA_EN |
 265                   MT_WFDMA1_GLO_CFG_RX_DMA_EN);
 266
 267        /* reset */
 268        mt76_clear(dev, MT_WFDMA1_RST,
 269                   MT_WFDMA1_RST_DMASHDL_ALL_RST |
 270                   MT_WFDMA1_RST_LOGIC_RST);
 271
 272        mt76_set(dev, MT_WFDMA1_RST,
 273                 MT_WFDMA1_RST_DMASHDL_ALL_RST |
 274                 MT_WFDMA1_RST_LOGIC_RST);
 275
 276        mt76_clear(dev, MT_WFDMA0_RST,
 277                   MT_WFDMA0_RST_DMASHDL_ALL_RST |
 278                   MT_WFDMA0_RST_LOGIC_RST);
 279
 280        mt76_set(dev, MT_WFDMA0_RST,
 281                 MT_WFDMA0_RST_DMASHDL_ALL_RST |
 282                 MT_WFDMA0_RST_LOGIC_RST);
 283
 284        tasklet_kill(&dev->mt76.tx_tasklet);
 285        mt76_dma_cleanup(&dev->mt76);
 286}
 287