Move mcu queue to a dedicated array q_mcu in mt76_dev structure.
This is a preliminary patch to move data queues in mt76_phy and properly
support dbdc
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
mt76_worker_disable(&dev->tx_worker);
netif_napi_del(&dev->tx_napi);
+
for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++)
mt76_dma_tx_cleanup(dev, dev->q_tx[i], true);
+ for (i = 0; i < ARRAY_SIZE(dev->q_mcu); i++)
+ mt76_dma_tx_cleanup(dev, dev->q_mcu[i], true);
+
mt76_for_each_q_rx(dev, i) {
netif_napi_del(&dev->napi[i]);
mt76_dma_rx_cleanup(dev, &dev->q_rx[i]);
len -= cur_len;
if (dev->queue_ops->tx_cleanup)
- dev->queue_ops->tx_cleanup(dev, dev->q_tx[MT_TXQ_FWDL],
+ dev->queue_ops->tx_cleanup(dev,
+ dev->q_mcu[MT_MCUQ_FWDL],
false);
}
MT_TXQ_BE = IEEE80211_AC_BE,
MT_TXQ_BK = IEEE80211_AC_BK,
MT_TXQ_PSD,
- MT_TXQ_MCU,
- MT_TXQ_MCU_WA,
MT_TXQ_BEACON,
MT_TXQ_CAB,
- MT_TXQ_FWDL,
__MT_TXQ_MAX
};
enum mt76_mcuq_id {
+ MT_MCUQ_WM,
+ MT_MCUQ_WA,
+ MT_MCUQ_FWDL,
__MT_MCUQ_MAX
};
if (IS_ERR(q))
return PTR_ERR(q);
- q->qid = qid;
+ q->qid = __MT_TXQ_MAX + qid;
dev->q_mcu[qid] = q;
return 0;
#include "mac.h"
#include "../dma.h"
-static int
-mt7603_init_tx_queue(struct mt7603_dev *dev, int qid, int idx, int n_desc)
-{
- int err;
-
- err = mt76_init_tx_queue(&dev->mphy, qid, idx, n_desc,
- MT_TX_RING_BASE);
- if (err < 0)
- return err;
-
- mt7603_irq_enable(dev, MT_INT_TX_DONE(idx));
-
- return 0;
-}
-
static void
mt7603_rx_loopback_skb(struct mt7603_dev *dev, struct sk_buff *skb)
{
dev = container_of(napi, struct mt7603_dev, mt76.tx_napi);
dev->tx_dma_check = 0;
- for (i = MT_TXQ_MCU; i >= 0; i--)
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false);
+ for (i = MT_TXQ_PSD; i >= 0; i--)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], false);
if (napi_complete_done(napi, 0))
mt7603_irq_enable(dev, MT_INT_TX_DONE_ALL);
- for (i = MT_TXQ_MCU; i >= 0; i--)
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false);
+ for (i = MT_TXQ_PSD; i >= 0; i--)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], false);
mt7603_mac_sta_poll(dev);
mt7603_pse_client_reset(dev);
for (i = 0; i < ARRAY_SIZE(wmm_queue_map); i++) {
- ret = mt7603_init_tx_queue(dev, i, wmm_queue_map[i],
- MT7603_TX_RING_SIZE);
+ ret = mt76_init_tx_queue(&dev->mphy, i, wmm_queue_map[i],
+ MT7603_TX_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
}
- ret = mt7603_init_tx_queue(dev, MT_TXQ_PSD,
- MT_TX_HW_QUEUE_MGMT, MT7603_PSD_RING_SIZE);
+ ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
+ MT7603_PSD_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
- ret = mt7603_init_tx_queue(dev, MT_TXQ_MCU,
- MT_TX_HW_QUEUE_MCU, MT_MCU_RING_SIZE);
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT_TX_HW_QUEUE_MCU,
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
- ret = mt7603_init_tx_queue(dev, MT_TXQ_BEACON,
- MT_TX_HW_QUEUE_BCN, MT_MCU_RING_SIZE);
+ ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_BEACON, MT_TX_HW_QUEUE_BCN,
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
- ret = mt7603_init_tx_queue(dev, MT_TXQ_CAB,
- MT_TX_HW_QUEUE_BMC, MT_MCU_RING_SIZE);
+ ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_CAB, MT_TX_HW_QUEUE_BMC,
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
+ mt7603_irq_enable(dev,
+ MT_INT_TX_DONE(IEEE80211_AC_VO) |
+ MT_INT_TX_DONE(IEEE80211_AC_VI) |
+ MT_INT_TX_DONE(IEEE80211_AC_BE) |
+ MT_INT_TX_DONE(IEEE80211_AC_BK) |
+ MT_INT_TX_DONE(MT_TX_HW_QUEUE_MGMT) |
+ MT_INT_TX_DONE(MT_TX_HW_QUEUE_MCU) |
+ MT_INT_TX_DONE(MT_TX_HW_QUEUE_BCN) |
+ MT_INT_TX_DONE(MT_TX_HW_QUEUE_BMC));
+
ret = mt7603_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1,
MT7603_MCU_RX_RING_SIZE, MT_RX_BUF_SIZE);
if (ret)
mt7603_pse_client_reset(dev);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], true);
for (i = 0; i < __MT_TXQ_MAX; i++)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], true);
if (wait_seq)
*wait_seq = seq;
- return mt76_tx_queue_skb_raw(dev, mdev->q_tx[MT_TXQ_MCU], skb, 0);
+ return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, 0);
}
static int
mt7615_queues_read(struct seq_file *s, void *data)
{
struct mt7615_dev *dev = dev_get_drvdata(s->private);
- static const struct {
+ struct {
+ struct mt76_queue *q;
char *queue;
- int id;
} queue_map[] = {
- { "PDMA0", MT_TXQ_BE },
- { "MCUQ", MT_TXQ_MCU },
- { "MCUFWQ", MT_TXQ_FWDL },
+ { dev->mt76.q_tx[MT_TXQ_BE], "PDMA0" },
+ { dev->mt76.q_mcu[MT_MCUQ_WM], "MCUQ" },
+ { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" },
};
int i;
for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
- struct mt76_queue *q = dev->mt76.q_tx[queue_map[i].id];
-
- if (!q)
- continue;
+ struct mt76_queue *q = queue_map[i].q;
seq_printf(s,
"%s: queued=%d head=%d tail=%d\n",
if (ret)
return ret;
- return mt76_init_tx_queue(&dev->mphy, MT_TXQ_MCU, MT7622_TXQ_MCU,
- MT7615_TX_MCU_RING_SIZE,
- MT_TX_RING_BASE);
+ return mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7622_TXQ_MCU,
+ MT7615_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
}
static int
{
int ret, i;
- ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_FWDL, MT7615_TXQ_FWDL,
- MT7615_TX_FWDL_RING_SIZE,
- MT_TX_RING_BASE);
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7615_TXQ_FWDL,
+ MT7615_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
if (ret)
return ret;
- for (i = 1; i < MT_TXQ_MCU; i++)
+ for (i = 1; i <= MT_TXQ_PSD ; i++)
dev->mt76.q_tx[i] = dev->mt76.q_tx[0];
- return mt76_init_tx_queue(&dev->mphy, MT_TXQ_MCU, MT7615_TXQ_MCU,
- MT7615_TX_MCU_RING_SIZE,
- MT_TX_RING_BASE);
+ return mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7615_TXQ_MCU,
+ MT7615_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
}
static int mt7615_poll_tx(struct napi_struct *napi, int budget)
dev = container_of(napi, struct mt7615_dev, mt76.tx_napi);
- mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[MT_TXQ_MCU], false);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false);
if (napi_complete_done(napi, 0))
mt7615_irq_enable(dev, mt7615_tx_mcu_int_mask(dev));
MT_WPDMA_GLO_CFG_TX_WRITEBACK_DONE);
usleep_range(1000, 2000);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], true);
for (i = 0; i < __MT_TXQ_MAX; i++)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], true);
mt7615_mcu_fill_msg(dev, skb, cmd, seq);
if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
- qid = MT_TXQ_MCU;
+ qid = MT_MCUQ_WM;
else
- qid = MT_TXQ_FWDL;
+ qid = MT_MCUQ_FWDL;
- return mt76_tx_queue_skb_raw(dev, dev->mt76.q_tx[qid], skb, 0);
+ return mt76_tx_queue_skb_raw(dev, dev->mt76.q_mcu[qid], skb, 0);
}
u32 mt7615_rf_rr(struct mt7615_dev *dev, u32 wf, u32 reg)
if (ret)
return ret;
- mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[MT_TXQ_FWDL], false);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
dev_dbg(dev->mt76.dev, "Firmware init done\n");
set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
mt7615_mcu_fw_log_2_host(dev, 0);
static inline u32 mt7615_tx_mcu_int_mask(struct mt7615_dev *dev)
{
- return MT_INT_TX_DONE(dev->mt76.q_tx[MT_TXQ_MCU]->hw_idx);
+ return MT_INT_TX_DONE(dev->mt76.q_mcu[MT_MCUQ_WM]->hw_idx);
}
void mt7615_dma_reset(struct mt7615_dev *dev);
int ret;
mt7615_mcu_fill_msg(dev, skb, cmd, seq);
- ret = mt76_tx_queue_skb_raw(dev, mdev->q_tx[MT_TXQ_MCU], skb, 0);
+ ret = mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, 0);
if (ret)
return ret;
- mt76_queue_kick(dev, mdev->q_tx[MT_TXQ_MCU]);
+ mt76_queue_kick(dev, mdev->q_mcu[MT_MCUQ_WM]);
return ret;
}
static int mt7663s_tx_run_queue(struct mt76_dev *dev, struct mt76_queue *q)
{
int qid, err, nframes = 0, len = 0, pse_sz = 0, ple_sz = 0;
- bool mcu = q == dev->q_tx[MT_TXQ_MCU];
+ bool mcu = q == dev->q_mcu[MT_MCUQ_WM];
struct mt76_sdio *sdio = &dev->sdio;
qid = mcu ? ARRAY_SIZE(sdio->xmit_buf) - 1 : q->qid;
nframes = 0;
/* tx */
- for (i = 0; i < MT_TXQ_MCU_WA; i++) {
+ for (i = 0; i <= MT_TXQ_PSD; i++) {
ret = mt7663s_tx_run_queue(dev, dev->q_tx[i]);
if (ret > 0)
nframes += ret;
}
+ ret = mt7663s_tx_run_queue(dev, dev->q_mcu[MT_MCUQ_WM]);
+ if (ret > 0)
+ nframes += ret;
/* rx */
ret = mt7663s_rx_handler(dev);
FIELD_PREP(MT_MCU_MSG_PORT, CPU_TX_PORT) |
FIELD_PREP(MT_MCU_MSG_LEN, skb->len);
- ret = mt76_tx_queue_skb_raw(dev, mdev->q_tx[MT_TXQ_MCU], skb, tx_info);
+ ret = mt76_tx_queue_skb_raw(dev, mdev->q_mcu[MT_MCUQ_WM], skb, tx_info);
if (ret)
goto out;
}
EXPORT_SYMBOL_GPL(mt76x02e_init_beacon_config);
-static int
-mt76x02_init_tx_queue(struct mt76x02_dev *dev, int qid, int idx, int n_desc)
-{
- int err;
-
- err = mt76_init_tx_queue(&dev->mphy, qid, idx, n_desc,
- MT_TX_RING_BASE);
- if (err < 0)
- return err;
-
- mt76x02_irq_enable(dev, MT_INT_TX_DONE(idx));
-
- return 0;
-}
-
static int
mt76x02_init_rx_queue(struct mt76x02_dev *dev, struct mt76_queue *q,
int idx, int n_desc, int bufsize)
mt76x02_mac_poll_tx_status(dev, false);
- for (i = MT_TXQ_MCU; i >= 0; i--)
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false);
+ for (i = MT_TXQ_PSD; i >= 0; i--)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], false);
if (napi_complete_done(napi, 0))
mt76x02_irq_enable(dev, MT_INT_TX_DONE_ALL);
- for (i = MT_TXQ_MCU; i >= 0; i--)
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false);
+ for (i = MT_TXQ_PSD; i >= 0; i--)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], false);
mt76_worker_schedule(&dev->mt76.tx_worker);
mt76_wr(dev, MT_WPDMA_RST_IDX, ~0);
for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- ret = mt76x02_init_tx_queue(dev, i, mt76_ac_to_hwq(i),
- MT76x02_TX_RING_SIZE);
+ ret = mt76_init_tx_queue(&dev->mphy, i, mt76_ac_to_hwq(i),
+ MT76x02_TX_RING_SIZE,
+ MT_TX_RING_BASE);
if (ret)
return ret;
}
- ret = mt76x02_init_tx_queue(dev, MT_TXQ_PSD,
- MT_TX_HW_QUEUE_MGMT, MT76x02_PSD_RING_SIZE);
+ ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_PSD, MT_TX_HW_QUEUE_MGMT,
+ MT76x02_PSD_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
- ret = mt76x02_init_tx_queue(dev, MT_TXQ_MCU,
- MT_TX_HW_QUEUE_MCU, MT_MCU_RING_SIZE);
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT_TX_HW_QUEUE_MCU,
+ MT_MCU_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
+ mt76x02_irq_enable(dev,
+ MT_INT_TX_DONE(IEEE80211_AC_VO) |
+ MT_INT_TX_DONE(IEEE80211_AC_VI) |
+ MT_INT_TX_DONE(IEEE80211_AC_BE) |
+ MT_INT_TX_DONE(IEEE80211_AC_BK) |
+ MT_INT_TX_DONE(MT_TX_HW_QUEUE_MGMT) |
+ MT_INT_TX_DONE(MT_TX_HW_QUEUE_MCU));
+
ret = mt76x02_init_rx_queue(dev, &dev->mt76.q_rx[MT_RXQ_MCU], 1,
MT_MCU_RING_SIZE, MT_RX_BUF_SIZE);
if (ret)
if (restart)
mt76_mcu_restart(dev);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], true);
for (i = 0; i < __MT_TXQ_MAX; i++)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], true);
mt7915_queues_read(struct seq_file *s, void *data)
{
struct mt7915_dev *dev = dev_get_drvdata(s->private);
- static const struct {
+ struct {
+ struct mt76_queue *q;
char *queue;
- int id;
} queue_map[] = {
- { "WFDMA0", MT_TXQ_BE },
- { "MCUWM", MT_TXQ_MCU },
- { "MCUWA", MT_TXQ_MCU_WA },
- { "MCUFWQ", MT_TXQ_FWDL },
+ { dev->mt76.q_tx[MT_TXQ_BE], "WFDMA0" },
+ { dev->mt76.q_mcu[MT_MCUQ_WM], "MCUWM" },
+ { dev->mt76.q_mcu[MT_MCUQ_WA], "MCUWA" },
+ { dev->mt76.q_mcu[MT_MCUQ_FWDL], "MCUFWQ" },
};
int i;
for (i = 0; i < ARRAY_SIZE(queue_map); i++) {
- struct mt76_queue *q = dev->mt76.q_tx[queue_map[i].id];
-
- if (!q)
- continue;
+ struct mt76_queue *q = queue_map[i].q;
seq_printf(s,
"%s: queued=%d head=%d tail=%d\n",
if (err < 0)
return err;
- for (i = 0; i < MT_TXQ_MCU; i++)
+ for (i = 0; i <= MT_TXQ_PSD; i++)
dev->mt76.q_tx[i] = dev->mt76.q_tx[0];
return 0;
static void
mt7915_tx_cleanup(struct mt7915_dev *dev)
{
- mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[MT_TXQ_MCU], false);
- mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[MT_TXQ_MCU_WA], false);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WM], false);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WA], false);
}
static int mt7915_poll_tx(struct napi_struct *napi, int budget)
return ret;
/* command to WM */
- ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_MCU, MT7915_TXQ_MCU_WM,
- MT7915_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WM, MT7915_TXQ_MCU_WM,
+ MT7915_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
/* command to WA */
- ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_MCU_WA, MT7915_TXQ_MCU_WA,
- MT7915_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_WA, MT7915_TXQ_MCU_WA,
+ MT7915_TX_MCU_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
/* firmware download */
- ret = mt76_init_tx_queue(&dev->mphy, MT_TXQ_FWDL, MT7915_TXQ_FWDL,
- MT7915_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
+ ret = mt76_init_mcu_queue(&dev->mt76, MT_MCUQ_FWDL, MT7915_TXQ_FWDL,
+ MT7915_TX_FWDL_RING_SIZE, MT_TX_RING_BASE);
if (ret)
return ret;
MT_WFDMA1_GLO_CFG_TX_DMA_EN | MT_WFDMA1_GLO_CFG_RX_DMA_EN);
usleep_range(1000, 2000);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_WA], true);
for (i = 0; i < __MT_TXQ_MAX; i++)
mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[i], true);
seq = ++dev->mt76.mcu.msg_seq & 0xf;
if (cmd == -MCU_CMD_FW_SCATTER) {
- txq = MT_TXQ_FWDL;
+ txq = MT_MCUQ_FWDL;
goto exit;
}
mcu_txd = (struct mt7915_mcu_txd *)skb_push(skb, sizeof(*mcu_txd));
if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) {
- txq = MT_TXQ_MCU_WA;
+ txq = MT_MCUQ_WA;
qidx = MT_TX_MCU_PORT_RX_Q0;
pkt_fmt = MT_TX_TYPE_CMD;
} else {
- txq = MT_TXQ_MCU;
+ txq = MT_MCUQ_WM;
qidx = MT_TX_MCU_PORT_RX_Q0;
pkt_fmt = MT_TX_TYPE_CMD;
}
if (wait_seq)
*wait_seq = seq;
- return mt76_tx_queue_skb_raw(dev, mdev->q_tx[txq], skb, 0);
+ return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);
}
static void
return -EIO;
}
- mt76_queue_tx_cleanup(dev, dev->mt76.q_tx[MT_TXQ_FWDL], false);
+ mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
dev_dbg(dev->mt76.dev, "Firmware init done\n");
if (IS_ERR(q))
return PTR_ERR(q);
- q->qid = MT_TXQ_MCU;
- dev->q_tx[MT_TXQ_MCU] = q;
+ q->qid = MT_MCUQ_WM;
+ dev->q_mcu[MT_MCUQ_WM] = q;
return 0;
}
static int mt76s_process_tx_queue(struct mt76_dev *dev, struct mt76_queue *q)
{
- bool wake, mcu = q == dev->q_tx[MT_TXQ_MCU];
+ bool wake, mcu = q == dev->q_mcu[MT_MCUQ_WM];
struct mt76_queue_entry entry;
int nframes = 0;
int i, nframes;
do {
- nframes = 0;
- for (i = 0; i < MT_TXQ_MCU_WA; i++)
+ nframes = mt76s_process_tx_queue(dev, dev->q_mcu[MT_MCUQ_WM]);
+
+ for (i = 0; i <= MT_TXQ_PSD; i++)
nframes += mt76s_process_tx_queue(dev, dev->q_tx[i]);
if (dev->drv->tx_status_data &&