Skip to content

Commit 7f0a168

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Add completion ring pointer in TX and RX ring structures
From the TX or RX ring structure, we need to find the corresponding completion ring during initialization. On P5 chips, we use the MSIX/napi entry to locate the completion ring because there is only one RX/TX ring per MSIX. To allow multiple TX rings for each MSIX, we need to add a direct pointer from the TX ring and RX ring structures. This also simplifies the existing logic. Reviewed-by: Andy Gospodarek <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 34eec1f commit 7f0a168

File tree

3 files changed

+40
-26
lines changed

3 files changed

+40
-26
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -331,16 +331,16 @@ static void bnxt_sched_reset_rxr(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
331331
}
332332

333333
void bnxt_sched_reset_txr(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
334-
int idx)
334+
u16 curr)
335335
{
336336
struct bnxt_napi *bnapi = txr->bnapi;
337337

338338
if (bnapi->tx_fault)
339339
return;
340340

341-
netdev_err(bp->dev, "Invalid Tx completion (ring:%d tx_pkts:%d cons:%u prod:%u i:%d)",
342-
txr->txq_index, bnapi->tx_pkts,
343-
txr->tx_cons, txr->tx_prod, idx);
341+
netdev_err(bp->dev, "Invalid Tx completion (ring:%d tx_hw_cons:%u cons:%u prod:%u curr:%u)",
342+
txr->txq_index, txr->tx_hw_cons,
343+
txr->tx_cons, txr->tx_prod, curr);
344344
WARN_ON_ONCE(1);
345345
bnapi->tx_fault = 1;
346346
bnxt_queue_sp_work(bp, BNXT_RESET_TASK_SP_EVENT);
@@ -691,13 +691,13 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
691691
{
692692
struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
693693
struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, txr->txq_index);
694+
u16 hw_cons = txr->tx_hw_cons;
694695
u16 cons = txr->tx_cons;
695696
struct pci_dev *pdev = bp->pdev;
696-
int nr_pkts = bnapi->tx_pkts;
697-
int i;
698697
unsigned int tx_bytes = 0;
698+
int tx_pkts = 0;
699699

700-
for (i = 0; i < nr_pkts; i++) {
700+
while (cons != hw_cons) {
701701
struct bnxt_sw_tx_bd *tx_buf;
702702
struct sk_buff *skb;
703703
int j, last;
@@ -708,10 +708,11 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
708708
tx_buf->skb = NULL;
709709

710710
if (unlikely(!skb)) {
711-
bnxt_sched_reset_txr(bp, txr, i);
711+
bnxt_sched_reset_txr(bp, txr, cons);
712712
return;
713713
}
714714

715+
tx_pkts++;
715716
tx_bytes += skb->len;
716717

717718
if (tx_buf->is_push) {
@@ -748,10 +749,10 @@ static void bnxt_tx_int(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
748749
dev_consume_skb_any(skb);
749750
}
750751

751-
bnapi->tx_pkts = 0;
752+
bnapi->events &= ~BNXT_TX_CMP_EVENT;
752753
WRITE_ONCE(txr->tx_cons, cons);
753754

754-
__netif_txq_completed_wake(txq, nr_pkts, tx_bytes,
755+
__netif_txq_completed_wake(txq, tx_pkts, tx_bytes,
755756
bnxt_tx_avail(bp, txr), bp->tx_wake_thresh,
756757
READ_ONCE(txr->dev_state) == BNXT_DEV_STATE_CLOSING);
757758
}
@@ -2588,14 +2589,15 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
25882589
{
25892590
struct bnxt_napi *bnapi = cpr->bnapi;
25902591
u32 raw_cons = cpr->cp_raw_cons;
2592+
struct bnxt_tx_ring_info *txr;
25912593
u32 cons;
2592-
int tx_pkts = 0;
25932594
int rx_pkts = 0;
25942595
u8 event = 0;
25952596
struct tx_cmp *txcmp;
25962597

25972598
cpr->has_more_work = 0;
25982599
cpr->had_work_done = 1;
2600+
txr = bnapi->tx_ring;
25992601
while (1) {
26002602
int rc;
26012603

@@ -2610,9 +2612,15 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
26102612
*/
26112613
dma_rmb();
26122614
if (TX_CMP_TYPE(txcmp) == CMP_TYPE_TX_L2_CMP) {
2613-
tx_pkts++;
2615+
u32 opaque = txcmp->tx_cmp_opaque;
2616+
u16 tx_freed;
2617+
2618+
event |= BNXT_TX_CMP_EVENT;
2619+
txr->tx_hw_cons = TX_OPAQUE_PROD(bp, opaque);
2620+
tx_freed = (txr->tx_hw_cons - txr->tx_cons) &
2621+
bp->tx_ring_mask;
26142622
/* return full budget so NAPI will complete. */
2615-
if (unlikely(tx_pkts >= bp->tx_wake_thresh)) {
2623+
if (unlikely(tx_freed >= bp->tx_wake_thresh)) {
26162624
rx_pkts = budget;
26172625
raw_cons = NEXT_RAW_CMP(raw_cons);
26182626
if (budget)
@@ -2666,15 +2674,14 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
26662674
}
26672675

26682676
cpr->cp_raw_cons = raw_cons;
2669-
bnapi->tx_pkts += tx_pkts;
26702677
bnapi->events |= event;
26712678
return rx_pkts;
26722679
}
26732680

26742681
static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi,
26752682
int budget)
26762683
{
2677-
if (bnapi->tx_pkts && !bnapi->tx_fault)
2684+
if ((bnapi->events & BNXT_TX_CMP_EVENT) && !bnapi->tx_fault)
26782685
bnapi->tx_int(bp, bnapi, budget);
26792686

26802687
if ((bnapi->events & BNXT_RX_EVENT) && !(bnapi->in_reset)) {
@@ -2687,7 +2694,7 @@ static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi,
26872694

26882695
bnxt_db_write(bp, &rxr->rx_agg_db, rxr->rx_agg_prod);
26892696
}
2690-
bnapi->events = 0;
2697+
bnapi->events &= BNXT_TX_CMP_EVENT;
26912698
}
26922699

26932700
static int bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
@@ -4515,6 +4522,7 @@ static void bnxt_clear_ring_indices(struct bnxt *bp)
45154522
if (txr) {
45164523
txr->tx_prod = 0;
45174524
txr->tx_cons = 0;
4525+
txr->tx_hw_cons = 0;
45184526
}
45194527

45204528
rxr = bnapi->rx_ring;
@@ -4524,6 +4532,7 @@ static void bnxt_clear_ring_indices(struct bnxt *bp)
45244532
rxr->rx_sw_agg_prod = 0;
45254533
rxr->rx_next_cons = 0;
45264534
}
4535+
bnapi->events = 0;
45274536
}
45284537
}
45294538

@@ -9528,8 +9537,6 @@ static void bnxt_enable_napi(struct bnxt *bp)
95289537
cpr = &bnapi->cp_ring;
95299538
bnapi->in_reset = false;
95309539

9531-
bnapi->tx_pkts = 0;
9532-
95339540
if (bnapi->rx_ring) {
95349541
INIT_WORK(&cpr->dim.work, bnxt_dim_work);
95359542
cpr->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ struct tx_bd {
6868
#define SET_TX_OPAQUE(bp, idx, bds) \
6969
(((bds) << TX_OPAQUE_BDS_SHIFT) | ((idx) & (bp)->tx_ring_mask))
7070

71+
#define TX_OPAQUE_IDX(opq) ((opq) & TX_OPAQUE_IDX_MASK)
72+
#define TX_OPAQUE_BDS(opq) (((opq) & TX_OPAQUE_BDS_MASK) >> \
73+
TX_OPAQUE_BDS_SHIFT)
74+
#define TX_OPAQUE_PROD(bp, opq) ((TX_OPAQUE_IDX(opq) + TX_OPAQUE_BDS(opq)) &\
75+
(bp)->tx_ring_mask)
76+
7177
struct tx_bd_ext {
7278
__le32 tx_bd_hsize_lflags;
7379
#define TX_BD_FLAGS_TCP_UDP_CHKSUM (1 << 0)
@@ -709,6 +715,7 @@ struct nqe_cn {
709715
#define BNXT_AGG_EVENT 2
710716
#define BNXT_TX_EVENT 4
711717
#define BNXT_REDIRECT_EVENT 8
718+
#define BNXT_TX_CMP_EVENT 0x10
712719

713720
struct bnxt_sw_tx_bd {
714721
union {
@@ -801,6 +808,7 @@ struct bnxt_tx_ring_info {
801808
struct bnxt_napi *bnapi;
802809
u16 tx_prod;
803810
u16 tx_cons;
811+
u16 tx_hw_cons;
804812
u16 txq_index;
805813
u8 kick_pending;
806814
struct bnxt_db_info tx_db;
@@ -1027,7 +1035,6 @@ struct bnxt_napi {
10271035

10281036
void (*tx_int)(struct bnxt *, struct bnxt_napi *,
10291037
int budget);
1030-
int tx_pkts;
10311038
u8 events;
10321039
u8 tx_fault:1;
10331040

@@ -2367,7 +2374,7 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
23672374
void bnxt_tx_disable(struct bnxt *bp);
23682375
void bnxt_tx_enable(struct bnxt *bp);
23692376
void bnxt_sched_reset_txr(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
2370-
int idx);
2377+
u16 curr);
23712378
void bnxt_report_link(struct bnxt *bp);
23722379
int bnxt_update_link(struct bnxt *bp, bool chng_link_state);
23732380
int bnxt_hwrm_set_pause(struct bnxt *);

drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,17 +129,17 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
129129
{
130130
struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
131131
struct bnxt_rx_ring_info *rxr = bnapi->rx_ring;
132+
u16 tx_hw_cons = txr->tx_hw_cons;
132133
bool rx_doorbell_needed = false;
133-
int nr_pkts = bnapi->tx_pkts;
134134
struct bnxt_sw_tx_bd *tx_buf;
135135
u16 tx_cons = txr->tx_cons;
136136
u16 last_tx_cons = tx_cons;
137-
int i, j, frags;
137+
int j, frags;
138138

139139
if (!budget)
140140
return;
141141

142-
for (i = 0; i < nr_pkts; i++) {
142+
while (tx_cons != tx_hw_cons) {
143143
tx_buf = &txr->tx_buf_ring[tx_cons];
144144

145145
if (tx_buf->action == XDP_REDIRECT) {
@@ -164,13 +164,13 @@ void bnxt_tx_int_xdp(struct bnxt *bp, struct bnxt_napi *bnapi, int budget)
164164
page_pool_recycle_direct(rxr->page_pool, tx_buf->page);
165165
}
166166
} else {
167-
bnxt_sched_reset_txr(bp, txr, i);
167+
bnxt_sched_reset_txr(bp, txr, tx_cons);
168168
return;
169169
}
170170
tx_cons = NEXT_TX(tx_cons);
171171
}
172172

173-
bnapi->tx_pkts = 0;
173+
bnapi->events &= ~BNXT_TX_CMP_EVENT;
174174
WRITE_ONCE(txr->tx_cons, tx_cons);
175175
if (rx_doorbell_needed) {
176176
tx_buf = &txr->tx_buf_ring[last_tx_cons];
@@ -275,7 +275,7 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,
275275
case XDP_TX:
276276
rx_buf = &rxr->rx_buf_ring[cons];
277277
mapping = rx_buf->mapping - bp->rx_dma_offset;
278-
*event = 0;
278+
*event &= BNXT_TX_CMP_EVENT;
279279

280280
if (unlikely(xdp_buff_has_frags(&xdp))) {
281281
struct skb_shared_info *sinfo = xdp_get_shared_info_from_buff(&xdp);

0 commit comments

Comments
 (0)