* ring_tx_db - ring a Tx queue's doorbell * @adap: the adapter * @q: the Tx queue * @n: number of new descriptors to give to HW * * Ring the doorbell for a Tx queue. */
| 616 | * Ring the doorbell for a Tx queue. |
| 617 | */ |
| 618 | static inline void ring_tx_db(struct adapter *adap, struct sge_txq *q) |
| 619 | { |
| 620 | int n = Q_IDXDIFF(q, dbidx); |
| 621 | |
| 622 | /* |
| 623 | * Make sure that all writes to the TX Descriptors are committed |
| 624 | * before we tell the hardware about them. |
| 625 | */ |
| 626 | rte_wmb(); |
| 627 | |
| 628 | /* |
| 629 | * If we don't have access to the new User Doorbell (T5+), use the old |
| 630 | * doorbell mechanism; otherwise use the new BAR2 mechanism. |
| 631 | */ |
| 632 | if (unlikely(!q->bar2_addr)) { |
| 633 | u32 val = V_PIDX(n); |
| 634 | |
| 635 | /* |
| 636 | * For T4 we need to participate in the Doorbell Recovery |
| 637 | * mechanism. |
| 638 | */ |
| 639 | if (!q->db_disabled) |
| 640 | t4_write_reg(adap, MYPF_REG(A_SGE_PF_KDOORBELL), |
| 641 | V_QID(q->cntxt_id) | val); |
| 642 | else |
| 643 | q->db_pidx_inc += n; |
| 644 | q->db_pidx = q->pidx; |
| 645 | } else { |
| 646 | u32 val = V_PIDX_T5(n); |
| 647 | |
| 648 | /* |
| 649 | * T4 and later chips share the same PIDX field offset within |
| 650 | * the doorbell, but T5 and later shrank the field in order to |
| 651 | * gain a bit for Doorbell Priority. The field was absurdly |
| 652 | * large in the first place (14 bits) so we just use the T5 |
| 653 | * and later limits and warn if a Queue ID is too large. |
| 654 | */ |
| 655 | WARN_ON(val & F_DBPRIO); |
| 656 | |
| 657 | writel(val | V_QID(q->bar2_qid), |
| 658 | (void *)((uintptr_t)q->bar2_addr + SGE_UDB_KDOORBELL)); |
| 659 | |
| 660 | /* |
| 661 | * This Write Memory Barrier will force the write to the User |
| 662 | * Doorbell area to be flushed. This is needed to prevent |
| 663 | * writes on different CPUs for the same queue from hitting |
| 664 | * the adapter out of order. This is required when some Work |
| 665 | * Requests take the Write Combine Gather Buffer path (user |
| 666 | * doorbell area offset [SGE_UDB_WCDOORBELL..+63]) and some |
| 667 | * take the traditional path where we simply increment the |
| 668 | * PIDX (User Doorbell area SGE_UDB_KDOORBELL) and have the |
| 669 | * hardware DMA read the actual Work Request. |
| 670 | */ |
| 671 | rte_wmb(); |
| 672 | } |
| 673 | q->dbidx = q->pidx; |
| 674 | } |
| 675 |
no test coverage detected