]> www.infradead.org Git - users/hch/misc.git/commitdiff
idpf: add 4-byte completion descriptor definition
authorMichal Kubiak <michal.kubiak@intel.com>
Tue, 26 Aug 2025 15:54:59 +0000 (17:54 +0200)
committerTony Nguyen <anthony.l.nguyen@intel.com>
Mon, 8 Sep 2025 18:05:17 +0000 (11:05 -0700)
In the queue-based scheduling mode, Tx completion descriptor is 4 bytes
comparing to 8 bytes in flow-based.
Add definition for it and allocate the corresponding amount of memory
for the descriptors during the completion queue creation.
This does not include handling 4-byte completions during Tx polling, as
for now, the only user of QB will be XDP, which has its own routines.

Signed-off-by: Michal Kubiak <michal.kubiak@intel.com>
Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Tested-by: Ramu R <ramu.r@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
drivers/net/ethernet/intel/idpf/idpf_lan_txrx.h
drivers/net/ethernet/intel/idpf/idpf_txrx.c
drivers/net/ethernet/intel/idpf/idpf_txrx.h

index 7492d1713243140f1a88dc43989487e2a5f2184e..20d5af64e750715757baf76f55cf9017d6aade31 100644 (file)
@@ -186,13 +186,17 @@ struct idpf_base_tx_desc {
        __le64 qw1; /* type_cmd_offset_bsz_l2tag1 */
 }; /* read used with buffer queues */
 
-struct idpf_splitq_tx_compl_desc {
+struct idpf_splitq_4b_tx_compl_desc {
        /* qid=[10:0] comptype=[13:11] rsvd=[14] gen=[15] */
        __le16 qid_comptype_gen;
        union {
                __le16 q_head; /* Queue head */
                __le16 compl_tag; /* Completion tag */
        } q_head_compl_tag;
+}; /* writeback used with completion queues */
+
+struct idpf_splitq_tx_compl_desc {
+       struct idpf_splitq_4b_tx_compl_desc common;
        u8 ts[3];
        u8 rsvd; /* Reserved */
 }; /* writeback used with completion queues */
index 563de9a3291962d228beeb2a1bf6bba582b1654b..875a849c87f48cb13acd6259c7a931e456d14251 100644 (file)
@@ -115,8 +115,8 @@ static void idpf_compl_desc_rel(struct idpf_compl_queue *complq)
                return;
 
        dma_free_coherent(complq->netdev->dev.parent, complq->size,
-                         complq->comp, complq->dma);
-       complq->comp = NULL;
+                         complq->desc_ring, complq->dma);
+       complq->desc_ring = NULL;
        complq->next_to_use = 0;
        complq->next_to_clean = 0;
 }
@@ -246,12 +246,16 @@ err_alloc:
 static int idpf_compl_desc_alloc(const struct idpf_vport *vport,
                                 struct idpf_compl_queue *complq)
 {
-       complq->size = array_size(complq->desc_count, sizeof(*complq->comp));
+       u32 desc_size;
 
-       complq->comp = dma_alloc_coherent(complq->netdev->dev.parent,
-                                         complq->size, &complq->dma,
-                                         GFP_KERNEL);
-       if (!complq->comp)
+       desc_size = idpf_queue_has(FLOW_SCH_EN, complq) ?
+                   sizeof(*complq->comp) : sizeof(*complq->comp_4b);
+       complq->size = array_size(complq->desc_count, desc_size);
+
+       complq->desc_ring = dma_alloc_coherent(complq->netdev->dev.parent,
+                                              complq->size, &complq->dma,
+                                              GFP_KERNEL);
+       if (!complq->desc_ring)
                return -ENOMEM;
 
        complq->next_to_use = 0;
@@ -1759,7 +1763,7 @@ static void idpf_tx_handle_rs_completion(struct idpf_tx_queue *txq,
        /* RS completion contains queue head for queue based scheduling or
         * completion tag for flow based scheduling.
         */
-       u16 rs_compl_val = le16_to_cpu(desc->q_head_compl_tag.q_head);
+       u16 rs_compl_val = le16_to_cpu(desc->common.q_head_compl_tag.q_head);
 
        if (!idpf_queue_has(FLOW_SCH_EN, txq)) {
                idpf_tx_splitq_clean(txq, rs_compl_val, budget, cleaned, false);
@@ -1794,19 +1798,19 @@ static bool idpf_tx_clean_complq(struct idpf_compl_queue *complq, int budget,
        do {
                struct libeth_sq_napi_stats cleaned_stats = { };
                struct idpf_tx_queue *tx_q;
+               __le16 hw_head;
                int rel_tx_qid;
-               u16 hw_head;
                u8 ctype;       /* completion type */
                u16 gen;
 
                /* if the descriptor isn't done, no work yet to do */
-               gen = le16_get_bits(tx_desc->qid_comptype_gen,
+               gen = le16_get_bits(tx_desc->common.qid_comptype_gen,
                                    IDPF_TXD_COMPLQ_GEN_M);
                if (idpf_queue_has(GEN_CHK, complq) != gen)
                        break;
 
                /* Find necessary info of TX queue to clean buffers */
-               rel_tx_qid = le16_get_bits(tx_desc->qid_comptype_gen,
+               rel_tx_qid = le16_get_bits(tx_desc->common.qid_comptype_gen,
                                           IDPF_TXD_COMPLQ_QID_M);
                if (rel_tx_qid >= complq->txq_grp->num_txq ||
                    !complq->txq_grp->txqs[rel_tx_qid]) {
@@ -1816,14 +1820,14 @@ static bool idpf_tx_clean_complq(struct idpf_compl_queue *complq, int budget,
                tx_q = complq->txq_grp->txqs[rel_tx_qid];
 
                /* Determine completion type */
-               ctype = le16_get_bits(tx_desc->qid_comptype_gen,
+               ctype = le16_get_bits(tx_desc->common.qid_comptype_gen,
                                      IDPF_TXD_COMPLQ_COMPL_TYPE_M);
                switch (ctype) {
                case IDPF_TXD_COMPLT_RE:
-                       hw_head = le16_to_cpu(tx_desc->q_head_compl_tag.q_head);
+                       hw_head = tx_desc->common.q_head_compl_tag.q_head;
 
-                       idpf_tx_splitq_clean(tx_q, hw_head, budget,
-                                            &cleaned_stats, true);
+                       idpf_tx_splitq_clean(tx_q, le16_to_cpu(hw_head),
+                                            budget, &cleaned_stats, true);
                        break;
                case IDPF_TXD_COMPLT_RS:
                        idpf_tx_handle_rs_completion(tx_q, tx_desc,
index 52753dff381c311705e745e3b6603bdfa38509b0..11a318fd48d444453f64089da6bcdde8fcbf9674 100644 (file)
@@ -728,7 +728,9 @@ libeth_cacheline_set_assert(struct idpf_buf_queue, 64, 24, 32);
 
 /**
  * struct idpf_compl_queue - software structure representing a completion queue
- * @comp: completion descriptor array
+ * @comp: 8-byte completion descriptor array
+ * @comp_4b: 4-byte completion descriptor array
+ * @desc_ring: virtual descriptor ring address
  * @txq_grp: See struct idpf_txq_group
  * @flags: See enum idpf_queue_flags_t
  * @desc_count: Number of descriptors
@@ -748,7 +750,12 @@ libeth_cacheline_set_assert(struct idpf_buf_queue, 64, 24, 32);
  */
 struct idpf_compl_queue {
        __cacheline_group_begin_aligned(read_mostly);
-       struct idpf_splitq_tx_compl_desc *comp;
+       union {
+               struct idpf_splitq_tx_compl_desc *comp;
+               struct idpf_splitq_4b_tx_compl_desc *comp_4b;
+
+               void *desc_ring;
+       };
        struct idpf_txq_group *txq_grp;
 
        DECLARE_BITMAP(flags, __IDPF_Q_FLAGS_NBITS);