Commit af005f26 authored by Lorenzo Bianconi's avatar Lorenzo Bianconi Committed by Felix Fietkau
Browse files

mt76: introduce mt76_sw_queue data structure



Introduce mt76_sw_queue data structure in order to support new
chipsets (e.g. mt7615) that have a shared hardware queue for all traffic
identifiers. mt76_sw_queue will be used to track outstanding packets

Signed-off-by: default avatarLorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent e226ba2e
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -43,14 +43,15 @@ mt76_queues_read(struct seq_file *s, void *data)
	int i;

	for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
		struct mt76_queue *q = &dev->q_tx[i];
		struct mt76_sw_queue *q = &dev->q_tx[i];

		if (!q->ndesc)
		if (!q->q)
			continue;

		seq_printf(s,
			   "%d:	queued=%d head=%d tail=%d swq_queued=%d\n",
			   i, q->queued, q->head, q->tail, q->swq_queued);
			   i, q->q->queued, q->q->head, q->q->tail,
			   q->swq_queued);
	}

	return 0;
+7 −7
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
	int i;

	spin_lock_init(&q->lock);
	INIT_LIST_HEAD(&q->swq);

	q->regs = dev->mmio.regs + ring_base + idx * MT_RING_SIZE;
	q->ndesc = n_desc;
@@ -147,12 +146,13 @@ mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
static void
mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
{
	struct mt76_queue *q = &dev->q_tx[qid];
	struct mt76_sw_queue *sq = &dev->q_tx[qid];
	struct mt76_queue *q = sq->q;
	struct mt76_queue_entry entry;
	bool wake = false;
	int last;

	if (!q->ndesc)
	if (!q)
		return;

	spin_lock_bh(&q->lock);
@@ -164,7 +164,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
	while (q->queued && q->tail != last) {
		mt76_dma_tx_cleanup_idx(dev, q, q->tail, &entry);
		if (entry.schedule)
			q->swq_queued--;
			dev->q_tx[qid].swq_queued--;

		q->tail = (q->tail + 1) % q->ndesc;
		q->queued--;
@@ -185,7 +185,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
	}

	if (!flush)
		mt76_txq_schedule(dev, q);
		mt76_txq_schedule(dev, sq);
	else
		mt76_dma_sync_idx(dev, q);

@@ -258,7 +258,7 @@ static int
mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, enum mt76_txq_id qid,
			  struct sk_buff *skb, u32 tx_info)
{
	struct mt76_queue *q = &dev->q_tx[qid];
	struct mt76_queue *q = dev->q_tx[qid].q;
	struct mt76_queue_buf buf;
	dma_addr_t addr;

@@ -282,7 +282,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
			  struct sk_buff *skb, struct mt76_wcid *wcid,
			  struct ieee80211_sta *sta)
{
	struct mt76_queue *q = &dev->q_tx[qid];
	struct mt76_queue *q = dev->q_tx[qid].q;
	struct mt76_queue_entry e;
	struct mt76_txwi_cache *t;
	struct mt76_queue_buf buf[32];
+3 −1
Original line number Diff line number Diff line
@@ -386,10 +386,12 @@ EXPORT_SYMBOL_GPL(mt76_rx);

static bool mt76_has_tx_pending(struct mt76_dev *dev)
{
	struct mt76_queue *q;
	int i;

	for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
		if (dev->q_tx[i].queued)
		q = dev->q_tx[i].q;
		if (q && q->queued)
			return true;
	}

+10 −6
Original line number Diff line number Diff line
@@ -117,9 +117,6 @@ struct mt76_queue {
	struct mt76_queue_entry *entry;
	struct mt76_desc *desc;

	struct list_head swq;
	int swq_queued;

	u16 first;
	u16 head;
	u16 tail;
@@ -137,6 +134,13 @@ struct mt76_queue {
	spinlock_t rx_page_lock;
};

struct mt76_sw_queue {
	struct mt76_queue *q;

	struct list_head swq;
	int swq_queued;
};

struct mt76_mcu_ops {
	int (*mcu_send_msg)(struct mt76_dev *dev, int cmd, const void *data,
			    int len, bool wait_resp);
@@ -214,7 +218,7 @@ struct mt76_wcid {

struct mt76_txq {
	struct list_head list;
	struct mt76_queue *hwq;
	struct mt76_sw_queue *swq;
	struct mt76_wcid *wcid;

	struct sk_buff_head retry_q;
@@ -437,7 +441,7 @@ struct mt76_dev {
	struct sk_buff_head rx_skb[__MT_RXQ_MAX];

	struct list_head txwi_cache;
	struct mt76_queue q_tx[__MT_TXQ_MAX];
	struct mt76_sw_queue q_tx[__MT_TXQ_MAX];
	struct mt76_queue q_rx[__MT_RXQ_MAX];
	const struct mt76_queue_ops *queue_ops;
	int tx_dma_idx[4];
@@ -659,7 +663,7 @@ void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq);
void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq);
void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,
			 bool send_bar);
void mt76_txq_schedule(struct mt76_dev *dev, struct mt76_queue *hwq);
void mt76_txq_schedule(struct mt76_dev *dev, struct mt76_sw_queue *sq);
void mt76_txq_schedule_all(struct mt76_dev *dev);
void mt76_release_buffered_frames(struct ieee80211_hw *hw,
				  struct ieee80211_sta *sta,
+5 −4
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
	mt76_wr(dev, MT_DMA_FQCR0, MT_DMA_FQCR0_BUSY |
		FIELD_PREP(MT_DMA_FQCR0_TARGET_WCID, mvif->sta.wcid.idx) |
		FIELD_PREP(MT_DMA_FQCR0_TARGET_QID,
			   dev->mt76.q_tx[MT_TXQ_CAB].hw_idx) |
			   dev->mt76.q_tx[MT_TXQ_CAB].q->hw_idx) |
		FIELD_PREP(MT_DMA_FQCR0_DEST_PORT_ID, 3) |
		FIELD_PREP(MT_DMA_FQCR0_DEST_QUEUE_ID, 8));

@@ -76,7 +76,7 @@ void mt7603_pre_tbtt_tasklet(unsigned long arg)
	data.dev = dev;
	__skb_queue_head_init(&data.q);

	q = &dev->mt76.q_tx[MT_TXQ_BEACON];
	q = dev->mt76.q_tx[MT_TXQ_BEACON].q;
	spin_lock_bh(&q->lock);
	ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
		IEEE80211_IFACE_ITER_RESUME_ALL,
@@ -93,7 +93,7 @@ void mt7603_pre_tbtt_tasklet(unsigned long arg)
	if (dev->mt76.csa_complete)
		goto out;

	q = &dev->mt76.q_tx[MT_TXQ_CAB];
	q = dev->mt76.q_tx[MT_TXQ_CAB].q;
	do {
		nframes = skb_queue_len(&data.q);
		ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
@@ -135,7 +135,8 @@ void mt7603_pre_tbtt_tasklet(unsigned long arg)

out:
	mt76_queue_tx_cleanup(dev, MT_TXQ_BEACON, false);
	if (dev->mt76.q_tx[MT_TXQ_BEACON].queued > hweight8(dev->beacon_mask))
	if (dev->mt76.q_tx[MT_TXQ_BEACON].q->queued >
	    hweight8(dev->beacon_mask))
		dev->beacon_check++;
}

Loading