drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/octeontx2/nic/qos_sq.c
Extension
.c
Size
7579 bytes
Lines
320
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/* Marvell RVU Physical Function ethernet driver
 *
 * Copyright (C) 2023 Marvell.
 *
 */

#include <linux/netdevice.h>
#include <net/tso.h>

#include "cn10k.h"
#include "otx2_reg.h"
#include "otx2_common.h"
#include "otx2_txrx.h"
#include "otx2_struct.h"

#define OTX2_QOS_MAX_LEAF_NODES 16

static void otx2_qos_aura_pool_free(struct otx2_nic *pfvf, int pool_id)
{
	struct otx2_pool *pool;

	if (!pfvf->qset.pool)
		return;

	pool = &pfvf->qset.pool[pool_id];
	qmem_free(pfvf->dev, pool->stack);
	qmem_free(pfvf->dev, pool->fc_addr);
	pool->stack = NULL;
	pool->fc_addr = NULL;
}

static int otx2_qos_sq_aura_pool_init(struct otx2_nic *pfvf, int qidx)
{
	struct otx2_qset *qset = &pfvf->qset;
	int pool_id, stack_pages, num_sqbs;
	struct otx2_hw *hw = &pfvf->hw;
	struct otx2_snd_queue *sq;
	struct otx2_pool *pool;
	dma_addr_t bufptr;
	int err, ptr;
	u64 iova, pa;

	/* Calculate number of SQBs needed.
	 *
	 * For a 128byte SQE, and 4K size SQB, 31 SQEs will fit in one SQB.
	 * Last SQE is used for pointing to next SQB.
	 */
	num_sqbs = (hw->sqb_size / 128) - 1;
	num_sqbs = (qset->sqe_cnt + num_sqbs) / num_sqbs;

	/* Get no of stack pages needed */
	stack_pages =
		(num_sqbs + hw->stack_pg_ptrs - 1) / hw->stack_pg_ptrs;

	pool_id = otx2_get_pool_idx(pfvf, AURA_NIX_SQ, qidx);
	pool = &pfvf->qset.pool[pool_id];

	/* Initialize aura context */
	err = otx2_aura_init(pfvf, pool_id, pool_id, num_sqbs);
	if (err)
		return err;

	/* Initialize pool context */
	err = otx2_pool_init(pfvf, pool_id, stack_pages,
			     num_sqbs, hw->sqb_size, AURA_NIX_SQ);
	if (err)
		goto aura_free;

	/* Flush accumulated messages */
	err = otx2_sync_mbox_msg(&pfvf->mbox);
	if (err)
		goto pool_free;

	/* Allocate pointers and free them to aura/pool */
	sq = &qset->sq[qidx];
	sq->sqb_count = 0;
	sq->sqb_ptrs = kcalloc(num_sqbs, sizeof(*sq->sqb_ptrs), GFP_KERNEL);
	if (!sq->sqb_ptrs) {
		err = -ENOMEM;
		goto pool_free;
	}

	for (ptr = 0; ptr < num_sqbs; ptr++) {
		err = otx2_alloc_rbuf(pfvf, pool, &bufptr, pool_id, ptr);
		if (err)
			goto sqb_free;
		pfvf->hw_ops->aura_freeptr(pfvf, pool_id, bufptr);
		sq->sqb_ptrs[sq->sqb_count++] = (u64)bufptr;
	}

Annotation

Implementation Notes