2019-03-02 13:48:00

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 0/5] introduce mt76_sw_queue data structure

Add 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 is used to track outstanding packets.
Add mt76_txq_id field to mt76_queue_entry in order to properly
track outstanding frames

Lorenzo Bianconi (5):
mt76: remove mt76_queue dependency from tx_queue_skb function pointer
mt76: remove mt76_queue dependency from tx_prepare_skb function
pointer
mt76: remove mt76_queue dependency from tx_complete_skb function
pointer
mt76: introduce mt76_sw_queue data structure
mt76: introduce mt76_txq_id field in mt76_queue_entry

drivers/net/wireless/mediatek/mt76/debugfs.c | 7 +-
drivers/net/wireless/mediatek/mt76/dma.c | 19 +++---
drivers/net/wireless/mediatek/mt76/mac80211.c | 4 +-
drivers/net/wireless/mediatek/mt76/mt76.h | 27 ++++----
.../wireless/mediatek/mt76/mt7603/beacon.c | 14 ++--
.../net/wireless/mediatek/mt76/mt7603/dma.c | 13 +++-
.../net/wireless/mediatek/mt76/mt7603/mac.c | 19 +++---
.../net/wireless/mediatek/mt76/mt7603/main.c | 2 +-
.../wireless/mediatek/mt76/mt7603/mt7603.h | 6 +-
drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 +-
.../net/wireless/mediatek/mt76/mt76x02_mac.c | 4 +-
.../net/wireless/mediatek/mt76/mt76x02_mac.h | 4 +-
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 23 ++++---
.../net/wireless/mediatek/mt76/mt76x02_txrx.c | 4 +-
.../net/wireless/mediatek/mt76/mt76x02_usb.h | 6 +-
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 11 ++--
.../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
drivers/net/wireless/mediatek/mt76/tx.c | 66 ++++++++++---------
drivers/net/wireless/mediatek/mt76/usb.c | 28 +++++---
19 files changed, 149 insertions(+), 112 deletions(-)

--
2.20.1



2019-03-02 13:48:00

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 1/5] mt76: remove mt76_queue dependency from tx_queue_skb function pointer

Remove mt76_queue dependency from tx_queue_skb function pointer and
rely on mt76_tx_qid instead. This is a preliminary patch to introduce
mt76_sw_queue support

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 3 ++-
drivers/net/wireless/mediatek/mt76/mt76.h | 4 ++--
drivers/net/wireless/mediatek/mt76/mt7603/beacon.c | 6 +++---
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c | 4 ++--
drivers/net/wireless/mediatek/mt76/tx.c | 10 +++++-----
drivers/net/wireless/mediatek/mt76/usb.c | 3 ++-
6 files changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 4e2dfb0f20c3..b9a43183d5d9 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -278,10 +278,11 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, enum mt76_txq_id qid,
return 0;
}

-int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+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_entry e;
struct mt76_txwi_cache *t;
struct mt76_queue_buf buf[32];
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 477027bb9aaf..0eaa05007f6d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -158,7 +158,7 @@ struct mt76_queue_ops {
struct mt76_queue_buf *buf, int nbufs, u32 info,
struct sk_buff *skb, void *txwi);

- int (*tx_queue_skb)(struct mt76_dev *dev, struct mt76_queue *q,
+ int (*tx_queue_skb)(struct mt76_dev *dev, enum mt76_txq_id qid,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta);

@@ -647,7 +647,7 @@ static inline struct mt76_tx_cb *mt76_tx_skb_cb(struct sk_buff *skb)
return ((void *) IEEE80211_SKB_CB(skb)->status.status_driver_data);
}

-int mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+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);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
index afcd86f735b4..ae41c1ba6e9b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
@@ -23,7 +23,7 @@ mt7603_update_beacon_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
if (!skb)
return;

- mt76_dma_tx_queue_skb(&dev->mt76, &dev->mt76.q_tx[MT_TXQ_BEACON], skb,
+ mt76_dma_tx_queue_skb(&dev->mt76, MT_TXQ_BEACON, skb,
&mvif->sta.wcid, NULL);

spin_lock_bh(&dev->ps_lock);
@@ -118,8 +118,8 @@ void mt7603_pre_tbtt_tasklet(unsigned long arg)
struct ieee80211_vif *vif = info->control.vif;
struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;

- mt76_dma_tx_queue_skb(&dev->mt76, q, skb, &mvif->sta.wcid,
- NULL);
+ mt76_dma_tx_queue_skb(&dev->mt76, MT_TXQ_CAB, skb,
+ &mvif->sta.wcid, NULL);
}
mt76_queue_kick(dev, q);
spin_unlock_bh(&q->lock);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 6a34a6afcfe4..910277e55480 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -146,8 +146,8 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
struct ieee80211_vif *vif = info->control.vif;
struct mt76x02_vif *mvif = (struct mt76x02_vif *)vif->drv_priv;

- mt76_dma_tx_queue_skb(&dev->mt76, q, skb, &mvif->group_wcid,
- NULL);
+ mt76_dma_tx_queue_skb(&dev->mt76, MT_TXQ_PSD, skb,
+ &mvif->group_wcid, NULL);
}
spin_unlock_bh(&q->lock);
}
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index fc7dffe066be..5c94cffb53b7 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -286,7 +286,7 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
q = &dev->q_tx[qid];

spin_lock_bh(&q->lock);
- dev->queue_ops->tx_queue_skb(dev, q, skb, wcid, sta);
+ dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid, sta);
dev->queue_ops->kick(dev, q);

if (q->queued > q->ndesc - 8 && !q->stopped) {
@@ -327,7 +327,6 @@ mt76_queue_ps_skb(struct mt76_dev *dev, struct ieee80211_sta *sta,
{
struct mt76_wcid *wcid = (struct mt76_wcid *) sta->drv_priv;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct mt76_queue *hwq = &dev->q_tx[MT_TXQ_PSD];

info->control.flags |= IEEE80211_TX_CTRL_PS_RESPONSE;
if (last)
@@ -335,7 +334,7 @@ mt76_queue_ps_skb(struct mt76_dev *dev, struct ieee80211_sta *sta,
IEEE80211_TX_CTL_REQ_TX_STATUS;

mt76_skb_set_moredata(skb, !last);
- dev->queue_ops->tx_queue_skb(dev, hwq, skb, wcid, sta);
+ dev->queue_ops->tx_queue_skb(dev, MT_TXQ_PSD, skb, wcid, sta);
}

void
@@ -387,6 +386,7 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq,
struct mt76_txq *mtxq, bool *empty)
{
struct ieee80211_txq *txq = mtxq_to_txq(mtxq);
+ enum mt76_txq_id qid = mt76_txq_get_qid(txq);
struct ieee80211_tx_info *info;
struct mt76_wcid *wcid = mtxq->wcid;
struct sk_buff *skb;
@@ -420,7 +420,7 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq,
if (ampdu)
mt76_check_agg_ssn(mtxq, skb);

- idx = dev->queue_ops->tx_queue_skb(dev, hwq, skb, wcid, txq->sta);
+ idx = dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid, txq->sta);

if (idx < 0)
return idx;
@@ -455,7 +455,7 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq,
if (cur_ampdu)
mt76_check_agg_ssn(mtxq, skb);

- idx = dev->queue_ops->tx_queue_skb(dev, hwq, skb, wcid,
+ idx = dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid,
txq->sta);
if (idx < 0)
return idx;
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index c30878d2dc5c..47ca79ef1db4 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -726,10 +726,11 @@ mt76u_tx_build_sg(struct mt76_dev *dev, struct sk_buff *skb,
}

static int
-mt76u_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+mt76u_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 mt76u_buf *buf;
u16 idx = q->tail;
int err;
--
2.20.1


2019-03-02 13:48:01

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 3/5] mt76: remove mt76_queue dependency from tx_complete_skb function pointer

Remove mt76_queue dependency from tx_complete_skb function pointer and
rely on mt76_tx_qid instead. Remove flush from tx_complete_skb
signature. This is a preliminary patch to introduce mt76_sw_queue
support

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76.h | 4 ++--
drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 6 +++---
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x02_mac.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x02_mac.h | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x02_usb.h | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 4 ++--
drivers/net/wireless/mediatek/mt76/usb.c | 2 +-
9 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index a9f0195ef0b7..58c67df9f185 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -171,7 +171,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)

if (entry.skb) {
spin_unlock_bh(&q->lock);
- dev->drv->tx_complete_skb(dev, q, &entry, flush);
+ dev->drv->tx_complete_skb(dev, qid, &entry);
spin_lock_bh(&q->lock);
}

@@ -348,7 +348,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
free:
e.skb = skb;
e.txwi = t;
- dev->drv->tx_complete_skb(dev, q, &e, true);
+ dev->drv->tx_complete_skb(dev, qid, &e);
mt76_put_txwi(dev, t);
return ret;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index ef7677f84755..e9bb1812c4cf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -292,8 +292,8 @@ struct mt76_driver_ops {
struct mt76_wcid *wcid,
struct ieee80211_sta *sta, u32 *tx_info);

- void (*tx_complete_skb)(struct mt76_dev *dev, struct mt76_queue *q,
- struct mt76_queue_entry *e, bool flush);
+ void (*tx_complete_skb)(struct mt76_dev *dev, enum mt76_txq_id qid,
+ struct mt76_queue_entry *e);

bool (*tx_status_data)(struct mt76_dev *dev, u8 *update);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 08ec43765f28..7a7f898f5400 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -1168,8 +1168,8 @@ void mt7603_mac_add_txs(struct mt7603_dev *dev, void *data)
rcu_read_unlock();
}

-void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
- struct mt76_queue_entry *e, bool flush)
+void mt7603_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
+ struct mt76_queue_entry *e)
{
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
struct sk_buff *skb = e->skb;
@@ -1179,7 +1179,7 @@ void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
return;
}

- if (q - dev->mt76.q_tx < 4)
+ if (qid < 4)
dev->tx_hang_check = 0;

mt76_tx_complete_skb(mdev, skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index 49eeab0f97cf..8bd00b97066a 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -227,8 +227,8 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info);

-void mt7603_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
- struct mt76_queue_entry *e, bool flush);
+void mt7603_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
+ struct mt76_queue_entry *e);

void mt7603_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
struct sk_buff *skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
index e1e0c8da5a8c..e2077ba3c761 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
@@ -755,8 +755,8 @@ void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq)
}
}

-void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
- struct mt76_queue_entry *e, bool flush)
+void mt76x02_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
+ struct mt76_queue_entry *e)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
struct mt76x02_txwi *txwi;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
index caeeef96c42f..e4a9e0d0924b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mac.h
@@ -198,8 +198,8 @@ void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
struct sk_buff *skb, struct mt76_wcid *wcid,
struct ieee80211_sta *sta, int len);
void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq);
-void mt76x02_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
- struct mt76_queue_entry *e, bool flush);
+void mt76x02_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
+ struct mt76_queue_entry *e);
void mt76x02_update_channel(struct mt76_dev *mdev);
void mt76x02_mac_work(struct work_struct *work);

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
index 20e0cee6e4e4..98e647c8c7c7 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
@@ -29,6 +29,6 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info);
-void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
- struct mt76_queue_entry *e, bool flush);
+void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
+ struct mt76_queue_entry *e);
#endif /* __MT76x02_USB_H */
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 643a817ae079..6ad2f9f95120 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -26,8 +26,8 @@ static void mt76x02u_remove_dma_hdr(struct sk_buff *skb)
mt76x02_remove_hdr_pad(skb, 2);
}

-void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
- struct mt76_queue_entry *e, bool flush)
+void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
+ struct mt76_queue_entry *e)
{
mt76x02u_remove_dma_hdr(e->skb);
mt76_tx_complete_skb(mdev, e->skb);
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 918dc03acfb3..e5485c83267b 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -651,7 +651,7 @@ static void mt76u_tx_tasklet(unsigned long data)
q->queued--;

spin_unlock_bh(&q->lock);
- dev->drv->tx_complete_skb(dev, q, &entry, false);
+ dev->drv->tx_complete_skb(dev, i, &entry);
spin_lock_bh(&q->lock);
}
mt76_txq_schedule(dev, q);
--
2.20.1


2019-03-02 13:48:00

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 2/5] mt76: remove mt76_queue dependency from tx_prepare_skb function pointer

Remove mt76_queue dependency from tx_prepare_skb function pointer and
rely on mt76_tx_qid instead. This is a preliminary patch to introduce
mt76_sw_queue support

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt7603/mac.c | 11 ++++++-----
drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c | 4 ++--
drivers/net/wireless/mediatek/mt76/mt76x02_usb.h | 2 +-
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c | 7 +++----
drivers/net/wireless/mediatek/mt76/usb.c | 2 +-
9 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index b9a43183d5d9..a9f0195ef0b7 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -301,7 +301,7 @@ int mt76_dma_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
skb->prev = skb->next = NULL;
dma_sync_single_for_cpu(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
- ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, q, wcid, sta,
+ ret = dev->drv->tx_prepare_skb(dev, &t->txwi, skb, qid, wcid, sta,
&tx_info);
dma_sync_single_for_device(dev->dev, t->dma_addr, sizeof(t->txwi),
DMA_TO_DEVICE);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 0eaa05007f6d..ef7677f84755 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -288,7 +288,7 @@ struct mt76_driver_ops {
void (*update_survey)(struct mt76_dev *dev);

int (*tx_prepare_skb)(struct mt76_dev *dev, void *txwi_ptr,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid,
struct ieee80211_sta *sta, u32 *tx_info);

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 0a0115861b51..08ec43765f28 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -820,7 +820,7 @@ int mt7603_wtbl_set_key(struct mt7603_dev *dev, int wcid,

static int
mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
int pid, struct ieee80211_key_conf *key)
{
@@ -828,6 +828,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
struct ieee80211_tx_rate *rate = &info->control.rates[0];
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_vif *vif = info->control.vif;
+ struct mt76_queue *q = &dev->mt76.q_tx[qid];
struct mt7603_vif *mvif;
int wlan_idx;
int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
@@ -841,7 +842,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
if (vif) {
mvif = (struct mt7603_vif *)vif->drv_priv;
vif_idx = mvif->idx;
- if (vif_idx && q >= &dev->mt76.q_tx[MT_TXQ_BEACON])
+ if (vif_idx && qid >= MT_TXQ_BEACON)
vif_idx += 0x10;
}

@@ -915,7 +916,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
}

/* use maximum tx count for beacons and buffered multicast */
- if (q >= &dev->mt76.q_tx[MT_TXQ_BEACON])
+ if (qid >= MT_TXQ_BEACON)
tx_count = 0x1f;

val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, tx_count) |
@@ -936,7 +937,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
}

int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info)
{
@@ -968,7 +969,7 @@ int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
spin_unlock_bh(&dev->mt76.lock);
}

- mt7603_mac_write_txwi(dev, txwi_ptr, skb, q, wcid, sta, pid, key);
+ mt7603_mac_write_txwi(dev, txwi_ptr, skb, qid, wcid, sta, pid, key);

return 0;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
index dc9f2e9b20f6..49eeab0f97cf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mt7603.h
@@ -223,7 +223,7 @@ void mt7603_wtbl_set_smps(struct mt7603_dev *dev, struct mt7603_sta *sta,
void mt7603_filter_tx(struct mt7603_dev *dev, int idx, bool abort);

int mt7603_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info);

diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02.h b/drivers/net/wireless/mediatek/mt76/mt76x02.h
index 3d93017c3227..e42262fd7380 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02.h
@@ -169,7 +169,7 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance);
void mt76x02_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
struct sk_buff *skb);
int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info);
void mt76x02_sw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
index 94f47248c59f..ce9ace11339d 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_txrx.c
@@ -147,7 +147,7 @@ bool mt76x02_tx_status_data(struct mt76_dev *mdev, u8 *update)
EXPORT_SYMBOL_GPL(mt76x02_tx_status_data);

int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info)
{
@@ -157,7 +157,7 @@ int mt76x02_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
int pid;
int ret;

- if (q == &dev->mt76.q_tx[MT_TXQ_PSD] && wcid && wcid->idx < 128)
+ if (qid == MT_TXQ_PSD && wcid && wcid->idx < 128)
mt76x02_mac_wcid_set_drop(dev, wcid->idx, false);

mt76x02_mac_write_txwi(dev, txwi, skb, wcid, sta, skb->len);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
index 0126e51d77ed..20e0cee6e4e4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb.h
@@ -26,7 +26,7 @@ int mt76x02u_mcu_fw_send_data(struct mt76x02_dev *dev, const void *data,

int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags);
int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info);
void mt76x02u_tx_complete_skb(struct mt76_dev *mdev, struct mt76_queue *q,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 6fb52b596d42..643a817ae079 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -72,16 +72,15 @@ int mt76x02u_skb_dma_info(struct sk_buff *skb, int port, u32 flags)
}

int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
- struct sk_buff *skb, struct mt76_queue *q,
+ struct sk_buff *skb, enum mt76_txq_id qid,
struct mt76_wcid *wcid, struct ieee80211_sta *sta,
u32 *tx_info)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
+ int pid, len = skb->len, ep = q2ep(mdev->q_tx[qid].hw_idx);
struct mt76x02_txwi *txwi;
enum mt76_qsel qsel;
- int len = skb->len;
u32 flags;
- int pid;

mt76x02_insert_hdr_pad(skb);

@@ -92,7 +91,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
pid = mt76_tx_status_skb_add(mdev, wcid, skb);
txwi->pktid = pid;

- if (pid >= MT_PACKET_ID_FIRST || q2ep(q->hw_idx) == MT_EP_OUT_HCCA)
+ if (pid >= MT_PACKET_ID_FIRST || ep == MT_EP_OUT_HCCA)
qsel = MT_QSEL_MGMT;
else
qsel = MT_QSEL_EDCA;
diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index 47ca79ef1db4..918dc03acfb3 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -739,7 +739,7 @@ mt76u_tx_queue_skb(struct mt76_dev *dev, enum mt76_txq_id qid,
return -ENOSPC;

skb->prev = skb->next = NULL;
- err = dev->drv->tx_prepare_skb(dev, NULL, skb, q, wcid, sta, NULL);
+ err = dev->drv->tx_prepare_skb(dev, NULL, skb, qid, wcid, sta, NULL);
if (err < 0)
return err;

--
2.20.1


2019-03-02 13:48:06

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 4/5] 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: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/debugfs.c | 7 ++-
drivers/net/wireless/mediatek/mt76/dma.c | 12 ++--
drivers/net/wireless/mediatek/mt76/mac80211.c | 4 +-
drivers/net/wireless/mediatek/mt76/mt76.h | 16 ++++--
.../wireless/mediatek/mt76/mt7603/beacon.c | 8 +--
.../net/wireless/mediatek/mt76/mt7603/dma.c | 13 ++++-
.../net/wireless/mediatek/mt76/mt7603/mac.c | 4 +-
.../net/wireless/mediatek/mt76/mt7603/main.c | 2 +-
.../net/wireless/mediatek/mt76/mt76x02_mmio.c | 19 +++++--
.../wireless/mediatek/mt76/mt76x02_usb_core.c | 2 +-
.../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
drivers/net/wireless/mediatek/mt76/tx.c | 55 ++++++++++---------
drivers/net/wireless/mediatek/mt76/usb.c | 23 +++++---
13 files changed, 100 insertions(+), 67 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/debugfs.c b/drivers/net/wireless/mediatek/mt76/debugfs.c
index a5adf22c3ffa..840615362b08 100644
--- a/drivers/net/wireless/mediatek/mt76/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/debugfs.c
@@ -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->ndesc)
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;
diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index 58c67df9f185..a37a1af74981 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -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,7 +146,8 @@ 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;
@@ -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];
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index a033745adb2f..47eecb4d4d01 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -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;
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index e9bb1812c4cf..e3160dc7c515 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -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,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
index ae41c1ba6e9b..addfeec51f60 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/beacon.c
@@ -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,7 @@ 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 >
+ if (dev->mt76.q_tx[MT_TXQ_BEACON].q->queued >
__sw_hweight8(dev->beacon_mask))
dev->beacon_check++;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
index 5067c49142f7..56c02423370c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/dma.c
@@ -5,16 +5,23 @@
#include "../dma.h"

static int
-mt7603_init_tx_queue(struct mt7603_dev *dev, struct mt76_queue *q,
+mt7603_init_tx_queue(struct mt7603_dev *dev, struct mt76_sw_queue *q,
int idx, int n_desc)
{
+ struct mt76_queue *hwq;
int err;

- err = mt76_queue_alloc(dev, q, idx, n_desc, 0,
- MT_TX_RING_BASE);
+ hwq = devm_kzalloc(dev->mt76.dev, sizeof(*hwq), GFP_KERNEL);
+ if (!hwq)
+ return -ENOMEM;
+
+ err = mt76_queue_alloc(dev, hwq, idx, n_desc, 0, MT_TX_RING_BASE);
if (err < 0)
return err;

+ INIT_LIST_HEAD(&q->swq);
+ q->q = hwq;
+
mt7603_irq_enable(dev, MT_INT_TX_DONE(idx));

return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
index 7a7f898f5400..c640f3e2e640 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c
@@ -828,7 +828,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi,
struct ieee80211_tx_rate *rate = &info->control.rates[0];
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_vif *vif = info->control.vif;
- struct mt76_queue *q = &dev->mt76.q_tx[qid];
+ struct mt76_queue *q = dev->mt76.q_tx[qid].q;
struct mt7603_vif *mvif;
int wlan_idx;
int hdr_len = ieee80211_get_hdrlen_from_skb(skb);
@@ -1411,7 +1411,7 @@ static bool mt7603_tx_hang(struct mt7603_dev *dev)
int i;

for (i = 0; i < 4; i++) {
- q = &dev->mt76.q_tx[i];
+ q = dev->mt76.q_tx[i].q;

if (!q->queued)
continue;
diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/main.c b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
index b10775ed92e6..05fd8009a5fe 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/main.c
@@ -476,7 +476,7 @@ mt7603_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
u16 cw_max = (1 << 10) - 1;
u32 val;

- queue = dev->mt76.q_tx[queue].hw_idx;
+ queue = dev->mt76.q_tx[queue].q->hw_idx;

if (params->cw_min)
cw_min = params->cw_min;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
index 910277e55480..c2a2fa353297 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
@@ -103,7 +103,7 @@ mt76x02_resync_beacon_timer(struct mt76x02_dev *dev)
static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
{
struct mt76x02_dev *dev = (struct mt76x02_dev *)arg;
- struct mt76_queue *q = &dev->mt76.q_tx[MT_TXQ_PSD];
+ struct mt76_queue *q = dev->mt76.q_tx[MT_TXQ_PSD].q;
struct beacon_bc_data data = {};
struct sk_buff *skb;
int i, nframes;
@@ -153,16 +153,23 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)
}

static int
-mt76x02_init_tx_queue(struct mt76x02_dev *dev, struct mt76_queue *q,
+mt76x02_init_tx_queue(struct mt76x02_dev *dev, struct mt76_sw_queue *q,
int idx, int n_desc)
{
+ struct mt76_queue *hwq;
int err;

- err = mt76_queue_alloc(dev, q, idx, n_desc, 0,
- MT_TX_RING_BASE);
+ hwq = devm_kzalloc(dev->mt76.dev, sizeof(*hwq), GFP_KERNEL);
+ if (!hwq)
+ return -ENOMEM;
+
+ err = mt76_queue_alloc(dev, hwq, idx, n_desc, 0, MT_TX_RING_BASE);
if (err < 0)
return err;

+ INIT_LIST_HEAD(&q->swq);
+ q->q = hwq;
+
mt76x02_irq_enable(dev, MT_INT_TX_DONE(idx));

return 0;
@@ -313,7 +320,7 @@ irqreturn_t mt76x02_irq_handler(int irq, void *dev_instance)
if (dev->mt76.csa_complete)
mt76_csa_finish(&dev->mt76);
else
- mt76_queue_kick(dev, &dev->mt76.q_tx[MT_TXQ_PSD]);
+ mt76_queue_kick(dev, dev->mt76.q_tx[MT_TXQ_PSD].q);
}

if (intr & MT_INT_TX_STAT) {
@@ -385,7 +392,7 @@ static bool mt76x02_tx_hang(struct mt76x02_dev *dev)
int i;

for (i = 0; i < 4; i++) {
- q = &dev->mt76.q_tx[i];
+ q = dev->mt76.q_tx[i].q;

if (!q->queued)
continue;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
index 6ad2f9f95120..8ab63255ba6f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c
@@ -77,7 +77,7 @@ int mt76x02u_tx_prepare_skb(struct mt76_dev *mdev, void *data,
u32 *tx_info)
{
struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
- int pid, len = skb->len, ep = q2ep(mdev->q_tx[qid].hw_idx);
+ int pid, len = skb->len, ep = q2ep(mdev->q_tx[qid].q->hw_idx);
struct mt76x02_txwi *txwi;
enum mt76_qsel qsel;
u32 flags;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
index cd072ac614f7..b14a55737829 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x02_util.c
@@ -465,7 +465,7 @@ int mt76x02_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
u8 cw_min = 5, cw_max = 10, qid;
u32 val;

- qid = dev->mt76.q_tx[queue].hw_idx;
+ qid = dev->mt76.q_tx[queue].q->hw_idx;

if (params->cw_min)
cw_min = fls(params->cw_min);
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 5c94cffb53b7..240ef2cc5c79 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -283,7 +283,7 @@ mt76_tx(struct mt76_dev *dev, struct ieee80211_sta *sta,
mt76_check_agg_ssn(mtxq, skb);
}

- q = &dev->q_tx[qid];
+ q = dev->q_tx[qid].q;

spin_lock_bh(&q->lock);
dev->queue_ops->tx_queue_skb(dev, qid, skb, wcid, sta);
@@ -345,7 +345,7 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
{
struct mt76_dev *dev = hw->priv;
struct sk_buff *last_skb = NULL;
- struct mt76_queue *hwq = &dev->q_tx[MT_TXQ_PSD];
+ struct mt76_queue *hwq = dev->q_tx[MT_TXQ_PSD].q;
int i;

spin_lock_bh(&hwq->lock);
@@ -382,13 +382,14 @@ mt76_release_buffered_frames(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
EXPORT_SYMBOL_GPL(mt76_release_buffered_frames);

static int
-mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq,
+mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_sw_queue *sq,
struct mt76_txq *mtxq, bool *empty)
{
struct ieee80211_txq *txq = mtxq_to_txq(mtxq);
enum mt76_txq_id qid = mt76_txq_get_qid(txq);
- struct ieee80211_tx_info *info;
struct mt76_wcid *wcid = mtxq->wcid;
+ struct mt76_queue *hwq = sq->q;
+ struct ieee80211_tx_info *info;
struct sk_buff *skb;
int n_frames = 1, limit;
struct ieee80211_tx_rate tx_rate;
@@ -464,8 +465,8 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq,
} while (n_frames < limit);

if (!probe) {
- hwq->swq_queued++;
hwq->entry[idx].schedule = true;
+ sq->swq_queued++;
}

dev->queue_ops->kick(dev, hwq);
@@ -474,14 +475,15 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_queue *hwq,
}

static int
-mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_queue *hwq)
+mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_sw_queue *sq)
{
+ struct mt76_queue *hwq = sq->q;
struct mt76_txq *mtxq, *mtxq_last;
int len = 0;

restart:
- mtxq_last = list_last_entry(&hwq->swq, struct mt76_txq, list);
- while (!list_empty(&hwq->swq)) {
+ mtxq_last = list_last_entry(&sq->swq, struct mt76_txq, list);
+ while (!list_empty(&sq->swq)) {
bool empty = false;
int cur;

@@ -489,7 +491,7 @@ mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_queue *hwq)
test_bit(MT76_RESET, &dev->state))
return -EBUSY;

- mtxq = list_first_entry(&hwq->swq, struct mt76_txq, list);
+ mtxq = list_first_entry(&sq->swq, struct mt76_txq, list);
if (mtxq->send_bar && mtxq->aggr) {
struct ieee80211_txq *txq = mtxq_to_txq(mtxq);
struct ieee80211_sta *sta = txq->sta;
@@ -506,9 +508,9 @@ mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_queue *hwq)

list_del_init(&mtxq->list);

- cur = mt76_txq_send_burst(dev, hwq, mtxq, &empty);
+ cur = mt76_txq_send_burst(dev, sq, mtxq, &empty);
if (!empty)
- list_add_tail(&mtxq->list, &hwq->swq);
+ list_add_tail(&mtxq->list, &sq->swq);

if (cur < 0)
return cur;
@@ -522,16 +524,16 @@ mt76_txq_schedule_list(struct mt76_dev *dev, struct mt76_queue *hwq)
return len;
}

-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)
{
int len;

rcu_read_lock();
do {
- if (hwq->swq_queued >= 4 || list_empty(&hwq->swq))
+ if (sq->swq_queued >= 4 || list_empty(&sq->swq))
break;

- len = mt76_txq_schedule_list(dev, hwq);
+ len = mt76_txq_schedule_list(dev, sq);
} while (len > 0);
rcu_read_unlock();
}
@@ -542,10 +544,10 @@ void mt76_txq_schedule_all(struct mt76_dev *dev)
int i;

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

spin_lock_bh(&q->lock);
- mt76_txq_schedule(dev, q);
+ mt76_txq_schedule(dev, &dev->q_tx[i]);
spin_unlock_bh(&q->lock);
}
}
@@ -558,18 +560,20 @@ void mt76_stop_tx_queues(struct mt76_dev *dev, struct ieee80211_sta *sta,

for (i = 0; i < ARRAY_SIZE(sta->txq); i++) {
struct ieee80211_txq *txq = sta->txq[i];
+ struct mt76_queue *hwq;
struct mt76_txq *mtxq;

if (!txq)
continue;

mtxq = (struct mt76_txq *)txq->drv_priv;
+ hwq = mtxq->swq->q;

- spin_lock_bh(&mtxq->hwq->lock);
+ spin_lock_bh(&hwq->lock);
mtxq->send_bar = mtxq->aggr && send_bar;
if (!list_empty(&mtxq->list))
list_del_init(&mtxq->list);
- spin_unlock_bh(&mtxq->hwq->lock);
+ spin_unlock_bh(&hwq->lock);
}
}
EXPORT_SYMBOL_GPL(mt76_stop_tx_queues);
@@ -577,31 +581,32 @@ EXPORT_SYMBOL_GPL(mt76_stop_tx_queues);
void mt76_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
{
struct mt76_dev *dev = hw->priv;
- struct mt76_txq *mtxq = (struct mt76_txq *) txq->drv_priv;
- struct mt76_queue *hwq = mtxq->hwq;
+ struct mt76_txq *mtxq = (struct mt76_txq *)txq->drv_priv;
+ struct mt76_sw_queue *sq = mtxq->swq;
+ struct mt76_queue *hwq = sq->q;

if (!test_bit(MT76_STATE_RUNNING, &dev->state))
return;

spin_lock_bh(&hwq->lock);
if (list_empty(&mtxq->list))
- list_add_tail(&mtxq->list, &hwq->swq);
- mt76_txq_schedule(dev, hwq);
+ list_add_tail(&mtxq->list, &sq->swq);
+ mt76_txq_schedule(dev, sq);
spin_unlock_bh(&hwq->lock);
}
EXPORT_SYMBOL_GPL(mt76_wake_tx_queue);

void mt76_txq_remove(struct mt76_dev *dev, struct ieee80211_txq *txq)
{
- struct mt76_txq *mtxq;
struct mt76_queue *hwq;
+ struct mt76_txq *mtxq;
struct sk_buff *skb;

if (!txq)
return;

mtxq = (struct mt76_txq *) txq->drv_priv;
- hwq = mtxq->hwq;
+ hwq = mtxq->swq->q;

spin_lock_bh(&hwq->lock);
if (!list_empty(&mtxq->list))
@@ -620,7 +625,7 @@ void mt76_txq_init(struct mt76_dev *dev, struct ieee80211_txq *txq)
INIT_LIST_HEAD(&mtxq->list);
skb_queue_head_init(&mtxq->retry_q);

- mtxq->hwq = &dev->q_tx[mt76_txq_get_qid(txq)];
+ mtxq->swq = &dev->q_tx[mt76_txq_get_qid(txq)];
}
EXPORT_SYMBOL_GPL(mt76_txq_init);

diff --git a/drivers/net/wireless/mediatek/mt76/usb.c b/drivers/net/wireless/mediatek/mt76/usb.c
index e5485c83267b..7cff5c2b547b 100644
--- a/drivers/net/wireless/mediatek/mt76/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/usb.c
@@ -627,13 +627,15 @@ static void mt76u_tx_tasklet(unsigned long data)
{
struct mt76_dev *dev = (struct mt76_dev *)data;
struct mt76_queue_entry entry;
+ struct mt76_sw_queue *sq;
struct mt76u_buf *buf;
struct mt76_queue *q;
bool wake;
int i;

for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- q = &dev->q_tx[i];
+ sq = &dev->q_tx[i];
+ q = sq->q;

spin_lock_bh(&q->lock);
while (true) {
@@ -643,7 +645,7 @@ static void mt76u_tx_tasklet(unsigned long data)

if (q->entry[q->head].schedule) {
q->entry[q->head].schedule = false;
- q->swq_queued--;
+ sq->swq_queued--;
}

entry = q->entry[q->head];
@@ -654,7 +656,7 @@ static void mt76u_tx_tasklet(unsigned long data)
dev->drv->tx_complete_skb(dev, i, &entry);
spin_lock_bh(&q->lock);
}
- mt76_txq_schedule(dev, q);
+ mt76_txq_schedule(dev, sq);

wake = q->stopped && q->queued < q->ndesc - 8;
if (wake)
@@ -730,7 +732,7 @@ mt76u_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 mt76u_buf *buf;
u16 idx = q->tail;
int err;
@@ -792,10 +794,15 @@ static int mt76u_alloc_tx(struct mt76_dev *dev)
int i, j;

for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- q = &dev->q_tx[i];
+ INIT_LIST_HEAD(&dev->q_tx[i].swq);
+
+ q = devm_kzalloc(dev->dev, sizeof(*q), GFP_KERNEL);
+ if (!q)
+ return -ENOMEM;
+
spin_lock_init(&q->lock);
- INIT_LIST_HEAD(&q->swq);
q->hw_idx = mt76_ac_to_hwq(i);
+ dev->q_tx[i].q = q;

q->entry = devm_kcalloc(dev->dev,
MT_NUM_TX_ENTRIES, sizeof(*q->entry),
@@ -832,7 +839,7 @@ static void mt76u_free_tx(struct mt76_dev *dev)
int i, j;

for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- q = &dev->q_tx[i];
+ q = dev->q_tx[i].q;
for (j = 0; j < q->ndesc; j++)
usb_free_urb(q->entry[j].ubuf.urb);
}
@@ -844,7 +851,7 @@ static void mt76u_stop_tx(struct mt76_dev *dev)
int i, j;

for (i = 0; i < IEEE80211_NUM_ACS; i++) {
- q = &dev->q_tx[i];
+ q = dev->q_tx[i].q;
for (j = 0; j < q->ndesc; j++)
usb_kill_urb(q->entry[j].ubuf.urb);
}
--
2.20.1


2019-03-02 13:48:07

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH 5/5] mt76: introduce mt76_txq_id field in mt76_queue_entry

Add mt76_txq_id field to mt76_queue_entry in order to properly
track outstanding frames for mt7615 that relies on a single hw queue

Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/dma.c | 2 +-
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
drivers/net/wireless/mediatek/mt76/tx.c | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c
index a37a1af74981..75ea381ff64a 100644
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -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)
- dev->q_tx[qid].swq_queued--;
+ dev->q_tx[entry.qid].swq_queued--;

q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index e3160dc7c515..51245623b427 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -100,6 +100,7 @@ struct mt76_queue_entry {
struct mt76_txwi_cache *txwi;
struct mt76u_buf ubuf;
};
+ enum mt76_txq_id qid;
bool schedule;
};

diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index 240ef2cc5c79..b59cdf88a224 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -465,6 +465,7 @@ mt76_txq_send_burst(struct mt76_dev *dev, struct mt76_sw_queue *sq,
} while (n_frames < limit);

if (!probe) {
+ hwq->entry[idx].qid = sq - dev->q_tx;
hwq->entry[idx].schedule = true;
sq->swq_queued++;
}
--
2.20.1


2019-03-12 15:59:57

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 0/5] introduce mt76_sw_queue data structure

On 2019-03-02 14:47, Lorenzo Bianconi wrote:
> Add 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 is used to track outstanding packets.
> Add mt76_txq_id field to mt76_queue_entry in order to properly
> track outstanding frames
>
> Lorenzo Bianconi (5):
> mt76: remove mt76_queue dependency from tx_queue_skb function pointer
> mt76: remove mt76_queue dependency from tx_prepare_skb function
> pointer
> mt76: remove mt76_queue dependency from tx_complete_skb function
> pointer
> mt76: introduce mt76_sw_queue data structure
> mt76: introduce mt76_txq_id field in mt76_queue_entry
Applied, thanks.

- Felix

2019-03-13 11:31:43

by Felix Fietkau

[permalink] [raw]
Subject: Re: [PATCH 4/5] mt76: introduce mt76_sw_queue data structure

On 2019-03-02 14:47, Lorenzo Bianconi wrote:
> 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: Lorenzo Bianconi <[email protected]>
> ---
> drivers/net/wireless/mediatek/mt76/debugfs.c | 7 ++-
> drivers/net/wireless/mediatek/mt76/dma.c | 12 ++--
> drivers/net/wireless/mediatek/mt76/mac80211.c | 4 +-
> drivers/net/wireless/mediatek/mt76/mt76.h | 16 ++++--
> .../wireless/mediatek/mt76/mt7603/beacon.c | 8 +--
> .../net/wireless/mediatek/mt76/mt7603/dma.c | 13 ++++-
> .../net/wireless/mediatek/mt76/mt7603/mac.c | 4 +-
> .../net/wireless/mediatek/mt76/mt7603/main.c | 2 +-
> .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 19 +++++--
> .../wireless/mediatek/mt76/mt76x02_usb_core.c | 2 +-
> .../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
> drivers/net/wireless/mediatek/mt76/tx.c | 55 ++++++++++---------
> drivers/net/wireless/mediatek/mt76/usb.c | 23 +++++---
> 13 files changed, 100 insertions(+), 67 deletions(-)
>
Turns out this causes a crash on cleanup if not all queues are
initialized. I will fold in the following fix:
---
--- a/drivers/net/wireless/mediatek/mt76/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/debugfs.c
@@ -45,7 +45,7 @@ mt76_queues_read(struct seq_file *s, void *data)
for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
struct mt76_sw_queue *q = &dev->q_tx[i];

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

seq_printf(s,
--- a/drivers/net/wireless/mediatek/mt76/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/dma.c
@@ -152,7 +152,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
bool wake = false;
int last;

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

spin_lock_bh(&q->lock);

2019-03-13 12:14:15

by Lorenzo Bianconi

[permalink] [raw]
Subject: Re: [PATCH 4/5] mt76: introduce mt76_sw_queue data structure

> On 2019-03-02 14:47, Lorenzo Bianconi wrote:
> > 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: Lorenzo Bianconi <[email protected]>
> > ---
> > drivers/net/wireless/mediatek/mt76/debugfs.c | 7 ++-
> > drivers/net/wireless/mediatek/mt76/dma.c | 12 ++--
> > drivers/net/wireless/mediatek/mt76/mac80211.c | 4 +-
> > drivers/net/wireless/mediatek/mt76/mt76.h | 16 ++++--
> > .../wireless/mediatek/mt76/mt7603/beacon.c | 8 +--
> > .../net/wireless/mediatek/mt76/mt7603/dma.c | 13 ++++-
> > .../net/wireless/mediatek/mt76/mt7603/mac.c | 4 +-
> > .../net/wireless/mediatek/mt76/mt7603/main.c | 2 +-
> > .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 19 +++++--
> > .../wireless/mediatek/mt76/mt76x02_usb_core.c | 2 +-
> > .../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +-
> > drivers/net/wireless/mediatek/mt76/tx.c | 55 ++++++++++---------
> > drivers/net/wireless/mediatek/mt76/usb.c | 23 +++++---
> > 13 files changed, 100 insertions(+), 67 deletions(-)
> >
> Turns out this causes a crash on cleanup if not all queues are
> initialized. I will fold in the following fix:
> ---
> --- a/drivers/net/wireless/mediatek/mt76/debugfs.c
> +++ b/drivers/net/wireless/mediatek/mt76/debugfs.c
> @@ -45,7 +45,7 @@ mt76_queues_read(struct seq_file *s, void *data)
> for (i = 0; i < ARRAY_SIZE(dev->q_tx); i++) {
> struct mt76_sw_queue *q = &dev->q_tx[i];
>
> - if (!q->q->ndesc)
> + if (!q->q)
> continue;
>
> seq_printf(s,
> --- a/drivers/net/wireless/mediatek/mt76/dma.c
> +++ b/drivers/net/wireless/mediatek/mt76/dma.c
> @@ -152,7 +152,7 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, enum mt76_txq_id qid, bool flush)
> bool wake = false;
> int last;
>
> - if (!q->ndesc)
> + if (!q)
> return;
>
> spin_lock_bh(&q->lock);

ack, thx for fixing it.

Regards,
Lorenzo


Attachments:
(No filename) (1.98 kB)
signature.asc (228.00 B)
Download all attachments