Commit cfe5efec authored by Michal Kubiak's avatar Michal Kubiak Committed by Tony Nguyen
Browse files

idpf: add 4-byte completion descriptor definition



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: default avatarMichal Kubiak <michal.kubiak@intel.com>
Signed-off-by: default avatarAlexander Lobakin <aleksander.lobakin@intel.com>
Tested-by: default avatarRamu R <ramu.r@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent bd74a86b
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -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 */
+19 −15
Original line number Diff line number Diff line
@@ -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 @@ static int idpf_tx_desc_alloc(const struct idpf_vport *vport,
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,
	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->comp)
	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,
+9 −2
Original line number Diff line number Diff line
@@ -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);
	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);