introduce mt76_hw_queue data structure
Subsystems (2)
Lorenzo Bianconi
maintainercover introduce mt76_hw_queue data structure
Add mt76_hw_queue data structure since new chipsets (e.g 7615) rely on a different tx queue enumeration scheme.
This series implements the approach suggested by Felix in
https://patchwork.kernel.org/cover/10816521/
Lorenzo Bianconi (2):
mt76: rename mt76_queue pointer occurrences from hwq to q
mt76: introduce mt76_hw_queue data structure
drivers/net/wireless/mediatek/mt76/debugfs.c | 6 +- drivers/net/wireless/mediatek/mt76/dma.c | 249 +++++++++--------- drivers/net/wireless/mediatek/mt76/mac80211.c | 4 +- drivers/net/wireless/mediatek/mt76/mt76.h | 36 ++- .../wireless/mediatek/mt76/mt7603/beacon.c | 26 +- .../net/wireless/mediatek/mt76/mt7603/dma.c | 21 +- .../net/wireless/mediatek/mt76/mt7603/mac.c | 12 +- .../net/wireless/mediatek/mt76/mt7603/main.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 38 +-- .../wireless/mediatek/mt76/mt76x02_usb_core.c | 3 +- .../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +- drivers/net/wireless/mediatek/mt76/tx.c | 79 +++--- drivers/net/wireless/mediatek/mt76/usb.c | 222 +++++++++------- 13 files changed, 377 insertions(+), 323 deletions(-)
Signature · 1 line
2.20.1
Lorenzo Bianconi
maintainerRFC 1/2 mt76: rename mt76_queue pointer occurrences from hwq to q
This is a preliminary patch for the introduction on mt76_hw_queue structure needed to properly support new chipsets (e.g. mt7615)
--- drivers/net/wireless/mediatek/mt76/mt76.h | 2 +- drivers/net/wireless/mediatek/mt76/tx.c | 71 +++++++++++------------ 2 files changed, 35 insertions(+), 38 deletions(-)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -1
@@ -212,7 +212,7 @@ struct mt76_wcid {struct mt76_txq {struct list_head list; -struct mt76_queue *hwq; +struct mt76_queue *q;struct mt76_wcid *wcid;struct sk_buff_head retry_q;
drivers/net/wireless/mediatek/mt76/tx.c +34 -37
202 lines not on this page · raw message
Signature · 1 line
2.20.1
Lorenzo Bianconi
maintainerRFC 2/2 mt76: introduce mt76_hw_queue data structure
In reply to Lorenzo BianconiIntroduce mt76_hw_queue data structure in order to support new chipsets (mt7615) that have a shared hardware queue for all traffic identifier. mt76_queue will be used to track outstanding packets
--- drivers/net/wireless/mediatek/mt76/debugfs.c | 6 +- drivers/net/wireless/mediatek/mt76/dma.c | 249 +++++++++--------- drivers/net/wireless/mediatek/mt76/mac80211.c | 4 +- drivers/net/wireless/mediatek/mt76/mt76.h | 34 ++- .../wireless/mediatek/mt76/mt7603/beacon.c | 26 +- .../net/wireless/mediatek/mt76/mt7603/dma.c | 21 +- .../net/wireless/mediatek/mt76/mt7603/mac.c | 12 +- .../net/wireless/mediatek/mt76/mt7603/main.c | 2 +- .../net/wireless/mediatek/mt76/mt76x02_mmio.c | 38 +-- .../wireless/mediatek/mt76/mt76x02_usb_core.c | 3 +- .../net/wireless/mediatek/mt76/mt76x02_util.c | 2 +- drivers/net/wireless/mediatek/mt76/tx.c | 50 ++-- drivers/net/wireless/mediatek/mt76/usb.c | 222 +++++++++------- 13 files changed, 363 insertions(+), 306 deletions(-)
drivers/net/wireless/mediatek/mt76/debugfs.c +4 -2
@@ -44,13 +44,15 @@ mt76_queues_read(struct seq_file *s, void *data)for (i =0 ; i <ARRAY_SIZE (dev->q_tx); i++) {struct mt76_queue *q = &dev->q_tx[i]; +struct mt76_hw_queue *hwq = q->hwq; -if (!q->ndesc) +if (!hwq->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, hwq->queued, hwq->head, hwq->tail, + q->swq_queued); }return 0 ;
drivers/net/wireless/mediatek/mt76/dma.c +130 -119
520 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mac80211.c +3 -1
@@ -386,10 +386,12 @@ EXPORT_SYMBOL_GPL(mt76_rx);static bool mt76_has_tx_pending (struct mt76_dev *dev) { +struct mt76_hw_queue *hwq;int i;for (i =0 ; i <ARRAY_SIZE (dev->q_tx); i++) { -if (dev->q_tx[i].queued) + hwq = dev->q_tx[i].hwq; +if (hwq && hwq->queued)return true; }
drivers/net/wireless/mediatek/mt76/mt76.h +21 -13
@@ -100,6 +100,7 @@ struct mt76_queue_entry {struct mt76_txwi_cache *txwi;struct mt76u_buf ubuf; }; +enum mt76_txq_id qid;bool schedule; };
@@ -110,30 +111,37 @@ struct mt76_queue_regs {u32 dma_idx; } __packed__aligned(4) ; -struct mt76_queue { +struct mt76_hw_queue {struct mt76_queue_regs __iomem *regs; -spinlock_t lock;struct mt76_queue_entry *entry;struct mt76_desc *desc; +spinlock_t lock; -struct list_head swq; -int swq_queued; +int queued; +int ndesc;u16 first;u16 head;u16 tail; -int ndesc; -int queued; -int buf_size; +dma_addr_t desc_dma; + +int buf_size;u8 buf_offset; +u8 hw_idx; -dma_addr_t desc_dma; -struct sk_buff *rx_head;struct page_frag_cache rx_page;spinlock_t rx_page_lock; +struct sk_buff *rx_head; +}; + +struct mt76_queue { +struct mt76_hw_queue *hwq; + +struct list_head swq; +int swq_queued; };struct mt76_mcu_ops {
@@ -148,9 +156,9 @@ struct mt76_mcu_ops {struct mt76_queue_ops {int (*init)(struct mt76_dev *dev); -int (*alloc)(struct mt76_dev *dev,struct mt76_queue *q, -int idx,int n_desc,int bufsize, -u32 ring_base); +struct mt76_hw_queue *(*alloc)(struct mt76_dev *dev, +int idx,int n_desc,int bufsize, +u32 ring_base); int (*add_buf)(struct mt76_dev *dev, struct mt76_queue *q, struct mt76_queue_buf *buf, int nbufs, u32 info,
@@ -171,7 +179,7 @@ struct mt76_queue_ops {void (*tx_cleanup)(struct mt76_dev *dev,enum mt76_txq_id qid,bool flush); -void (*kick)(struct mt76_dev *dev,struct mt76_queue *q); +void (*kick)(struct mt76_dev *dev,struct mt76_hw_queue *hwq); };enum mt76_wcid_flags {
drivers/net/wireless/mediatek/mt76/mt7603/beacon.c +13 -13
@@ -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 ].hwq->hw_idx) |FIELD_PREP (MT_DMA_FQCR0_DEST_PORT_ID ,3 ) |FIELD_PREP (MT_DMA_FQCR0_DEST_QUEUE_ID ,8 ));
@@ -68,7 +68,7 @@ mt7603_add_buffered_bc(void *priv, u8 *mac, struct ieee80211_vif *vif)void mt7603_pre_tbtt_tasklet (unsigned long arg) {struct mt7603_dev *dev = (struct mt7603_dev *)arg; -struct mt76_queue *q; +struct mt76_hw_queue *hwq;struct beacon_bc_data data = {};struct sk_buff *skb;int i, nframes;
@@ -76,13 +76,13 @@ 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 ]; -spin_lock_bh (&q->lock); + hwq = dev->mt76.q_tx[MT_TXQ_BEACON ].hwq; +spin_lock_bh (&hwq->lock);ieee80211_iterate_active_interfaces_atomic (mt76_hw (dev),IEEE80211_IFACE_ITER_RESUME_ALL , mt7603_update_beacon_iter, dev); -mt76_queue_kick (dev, q); -spin_unlock_bh (&q->lock); +mt76_queue_kick (dev, hwq); +spin_unlock_bh (&hwq->lock);/* Flush all previous CAB queue packets */ mt76_wr (dev,MT_WF_ARB_CAB_FLUSH ,GENMASK (30 ,16 ) |BIT (0 ));
@@ -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 ]; + hwq = dev->mt76.q_tx[MT_TXQ_CAB ].hwq; do { nframes = skb_queue_len(&data.q); ieee80211_iterate_active_interfaces_atomic(mt76_hw(dev),
@@ -112,17 +112,17 @@ void mt7603_pre_tbtt_tasklet(unsigned long arg)mt76_skb_set_moredata (data.tail[i], false); } -spin_lock_bh (&q->lock); +spin_lock_bh (&hwq->lock);while ((skb =__skb_dequeue (&data.q)) !=NULL ) {struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);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, &dev->mt76.q_tx[MT_TXQ_CAB ], + skb, &mvif->sta.wcid,NULL ); } -mt76_queue_kick (dev, q); -spin_unlock_bh (&q->lock); +mt76_queue_kick (dev, hwq); +spin_unlock_bh (&hwq->lock);for (i =0 ; i <ARRAY_SIZE (data.count); i++) mt76_wr(dev, MT_WF_ARB_CAB_COUNT_B0_REG(i),
@@ -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 ].hwq->queued >__sw_hweight8 (dev->beacon_mask)) dev->beacon_check++; }
drivers/net/wireless/mediatek/mt76/mt7603/dma.c +12 -9
@@ -8,12 +8,14 @@ static int mt7603_init_tx_queue(struct mt7603_dev *dev, struct mt76_queue *q, int idx, int n_desc) { - int err; + struct mt76_hw_queue *hwq; - err =mt76_queue_alloc (dev, q, idx, n_desc,0 , -MT_TX_RING_BASE ); -if (err <0 ) -return err; + hwq =mt76_queue_alloc (dev, idx, n_desc,0 ,MT_TX_RING_BASE ); +if (IS_ERR (hwq)) +return PTR_ERR (hwq); + +INIT_LIST_HEAD (&q->swq); + q->hwq = hwq;mt7603_irq_enable (dev,MT_INT_TX_DONE (idx));
@@ -103,13 +105,14 @@ static int mt7603_init_rx_queue(struct mt7603_dev *dev, struct mt76_queue *q, int idx, int n_desc, int bufsize) { - int err; + struct mt76_hw_queue *hwq; - err =mt76_queue_alloc (dev, q, idx, n_desc, bufsize, + hwq =mt76_queue_alloc (dev, idx, n_desc, bufsize,MT_RX_RING_BASE ); -if (err <0 ) -return err; +if (IS_ERR (hwq)) +return PTR_ERR (hwq); + q->hwq = hwq;mt7603_irq_enable (dev,MT_INT_RX_DONE (idx));return 0 ;
drivers/net/wireless/mediatek/mt76/mt7603/mac.c +6 -6
@@ -860,7 +860,7 @@ mt7603_mac_write_txwi(struct mt7603_dev *dev, __le32 *txwi, frame_subtype = (fc &IEEE80211_FCTL_STYPE ) >>4 ; val =FIELD_PREP (MT_TXD0_TX_BYTES , skb->len +MT_TXD_SIZE ) | -FIELD_PREP (MT_TXD0_Q_IDX , q->hw_idx); +FIELD_PREP (MT_TXD0_Q_IDX , q->hwq->hw_idx); txwi[0 ] =cpu_to_le32 (val); val = MT_TXD1_LONG_FORMAT |
@@ -1405,22 +1405,22 @@ static bool mt7603_tx_dma_busy(struct mt7603_dev *dev)static bool mt7603_tx_hang (struct mt7603_dev *dev) { -struct mt76_queue *q; +struct mt76_hw_queue *hwq;u32 dma_idx, prev_dma_idx;int i;for (i =0 ; i <4 ; i++) { - q = &dev->mt76.q_tx[i]; + hwq = dev->mt76.q_tx[i].hwq; -if (!q->queued) +if (!hwq->queued)continue ; prev_dma_idx = dev->tx_dma_idx[i]; - dma_idx =ioread32 (&q->regs->dma_idx); + dma_idx =ioread32 (&hwq->regs->dma_idx); dev->tx_dma_idx[i] = dma_idx;if (dma_idx == prev_dma_idx && - dma_idx !=ioread32 (&q->regs->cpu_idx)) + dma_idx !=ioread32 (&hwq->regs->cpu_idx))break ; }
drivers/net/wireless/mediatek/mt76/mt7603/main.c +1 -1
@@ -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].hwq->hw_idx;if (params->cw_min) cw_min = params->cw_min;
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c +21 -17
@@ -139,7 +139,7 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)mt76_skb_set_moredata (data.tail[i], false); } -spin_lock_bh (&q->lock); +spin_lock_bh (&q->hwq->lock);while ((skb =__skb_dequeue (&data.q)) !=NULL ) {struct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);struct ieee80211_vif *vif = info->control.vif;
@@ -148,19 +148,21 @@ static void mt76x02_pre_tbtt_tasklet(unsigned long arg)mt76_dma_tx_queue_skb (&dev->mt76, q, skb, &mvif->group_wcid,NULL ); } -spin_unlock_bh (&q->lock); +spin_unlock_bh (&q->hwq->lock); }static int mt76x02_init_tx_queue (struct mt76x02_dev *dev,struct mt76_queue *q,int idx,int n_desc) { -int err; +struct mt76_hw_queue *hwq; - err =mt76_queue_alloc (dev, q, idx, n_desc,0 , -MT_TX_RING_BASE ); -if (err <0 ) -return err; + hwq =mt76_queue_alloc (dev, idx, n_desc,0 ,MT_TX_RING_BASE ); +if (IS_ERR (hwq)) +return PTR_ERR (hwq); + +INIT_LIST_HEAD (&q->swq); + q->hwq = hwq;mt76x02_irq_enable (dev,MT_INT_TX_DONE (idx));
@@ -171,13 +173,14 @@ static int mt76x02_init_rx_queue(struct mt76x02_dev *dev, struct mt76_queue *q, int idx, int n_desc, int bufsize) { - int err; + struct mt76_hw_queue *hwq; - err =mt76_queue_alloc (dev, q, idx, n_desc, bufsize, + hwq =mt76_queue_alloc (dev, idx, n_desc, bufsize,MT_RX_RING_BASE ); -if (err <0 ) -return err; +if (IS_ERR (hwq)) +return PTR_ERR (hwq); + q->hwq = hwq;mt76x02_irq_enable (dev,MT_INT_RX_DONE (idx));return 0 ;
@@ -255,12 +258,13 @@ int mt76x02_dma_init(struct mt76x02_dev *dev)return ret; q = &dev->mt76.q_rx[MT_RXQ_MAIN ]; - q->buf_offset =MT_RX_HEADROOM -sizeof (struct mt76x02_rxwi ); ret =mt76x02_init_rx_queue (dev, q,0 ,MT76X02_RX_RING_SIZE ,MT_RX_BUF_SIZE );if (ret)return ret; + q->hwq->buf_offset =MT_RX_HEADROOM -sizeof (struct mt76x02_rxwi ); +return mt76_init_queues (dev); }EXPORT_SYMBOL_GPL (mt76x02_dma_init);
@@ -312,7 +316,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 ].hwq); }if (intr &MT_INT_TX_STAT ) {
@@ -380,17 +384,17 @@ EXPORT_SYMBOL_GPL(mt76x02_mac_start);static bool mt76x02_tx_hang (struct mt76x02_dev *dev) {u32 dma_idx, prev_dma_idx; -struct mt76_queue *q; +struct mt76_hw_queue *hwq;int i;for (i =0 ; i <4 ; i++) { - q = &dev->mt76.q_tx[i]; + hwq = dev->mt76.q_tx[i].hwq; -if (!q->queued) +if (!hwq->queued)continue ; prev_dma_idx = dev->mt76.tx_dma_idx[i]; - dma_idx =ioread32 (&q->regs->dma_idx); + dma_idx =ioread32 (&hwq->regs->dma_idx); dev->mt76.tx_dma_idx[i] = dma_idx;if (prev_dma_idx == dma_idx)
drivers/net/wireless/mediatek/mt76/mt76x02_usb_core.c +2 -1
@@ -91,7 +91,8 @@ 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 || +q2ep (q->hwq->hw_idx) ==MT_EP_OUT_HCCA ) qsel =MT_QSEL_MGMT ;else qsel =MT_QSEL_EDCA ;
drivers/net/wireless/mediatek/mt76/mt76x02_util.c +1 -1
@@ -459,7 +459,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].hwq->hw_idx;if (params->cw_min) cw_min =fls (params->cw_min);
drivers/net/wireless/mediatek/mt76/tx.c +29 -21
146 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/usb.c +120 -102
469 lines not on this page · raw message
Signature · 1 line
2.20.1
Re: [RFC 2/2] mt76: introduce mt76_hw_queue data structure
Quoted 20 lines · Lorenzo Bianconi
drivers/net/wireless/mediatek/mt76/mt76.h +5
-6-struct mt76_queue { +struct mt76_hw_queue {u16 first;u16 head;u16 tail; -int ndesc; -int queued; -int buf_size; +dma_addr_t desc_dma; + +int buf_size;u8 buf_offset; +u8 hw_idx; -dma_addr_t desc_dma; -struct sk_buff *rx_head;struct page_frag_cache rx_page;
drivers/net/wireless/mediatek/mt76/mt76.h struct mt76_queue_regs { · line 145
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76.h +8
-0spinlock_t rx_page_lock; +struct sk_buff *rx_head; +}; + +struct mt76_queue { +struct mt76_hw_queue *hwq; + +struct list_head swq; +int swq_queued; };
I don't think massive renaming is necessary. It makes patch more complex and eventual future backporting of fixes harder. Simpler approach would be doing:
struct mt76_sw_queue {
struct mt76_queue *q;
struct list_head swq;
int swq_queued;
}what should achieve the same goal without massive changes in the code.
Stanislaw
Re: [RFC 2/2] mt76: introduce mt76_hw_queue data structure
Quoted 36 lines · Lorenzo Bianconi
Quoted 20 lines
drivers/net/wireless/mediatek/mt76/mt76.h +5
-6-struct mt76_queue { +struct mt76_hw_queue {u16 first;u16 head;u16 tail; -int ndesc; -int queued; -int buf_size; +dma_addr_t desc_dma; + +int buf_size;u8 buf_offset; +u8 hw_idx; -dma_addr_t desc_dma; -struct sk_buff *rx_head;struct page_frag_cache rx_page;drivers/net/wireless/mediatek/mt76/mt76.h struct mt76_queue_regs { · line 145
Quoted 10 lines
drivers/net/wireless/mediatek/mt76/mt76.h +8
-0spinlock_t rx_page_lock; +struct sk_buff *rx_head; +}; + +struct mt76_queue { +struct mt76_hw_queue *hwq; + +struct list_head swq; +int swq_queued; };I don't think massive renaming is necessary. It makes patch more complex and eventual future backporting of fixes harder. Simpler approach would be doing:
Quoted 6 lines
struct mt76_sw_queue {
struct mt76_queue *q;
struct list_head swq;
int swq_queued;
}ack, it sounds good to me. Anyway mt76_queue is pretty spread as well :( I will post a v2 squashing this change.
Regards,
Lorenzo
Quoted 4 lines
what should achieve the same goal without massive changes in the code.
Stanislaw