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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/marvell/octeontx2/nic/otx2_dcbnl.c
Extension
.c
Size
11438 bytes
Lines
490
Domain
Driver Families
Bucket
drivers/net
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (err) {
				dev_err(pfvf->dev,
					"%s configure PFC tx schq for lvl:%d, prio:%d failed!\n",
					__func__, lvl, prio);
				return err;
			}
		}
	}

	return 0;
}
EXPORT_SYMBOL(otx2_pfc_txschq_config);

static int otx2_pfc_txschq_alloc_one(struct otx2_nic *pfvf, u8 prio)
{
	struct nix_txsch_alloc_req *req;
	struct nix_txsch_alloc_rsp *rsp;
	int lvl, rc;

	/* Get memory to put this msg */
	req = otx2_mbox_alloc_msg_nix_txsch_alloc(&pfvf->mbox);
	if (!req)
		return -ENOMEM;

	/* Request one schq per level upto max level as configured
	 * link config level. These rest of the scheduler can be
	 * same as hw.txschq_list.
	 */
	for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++)
		req->schq[lvl] = 1;

	rc = otx2_sync_mbox_msg(&pfvf->mbox);
	if (rc)
		return rc;

	rsp = (struct nix_txsch_alloc_rsp *)
	      otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
	if (IS_ERR(rsp))
		return PTR_ERR(rsp);

	/* Setup transmit scheduler list */
	for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++) {
		if (!rsp->schq[lvl])
			return -ENOSPC;

		pfvf->pfc_schq_list[lvl][prio] = rsp->schq_list[lvl][0];
	}

	/* Set the Tx schedulers for rest of the levels same as
	 * hw.txschq_list as those will be common for all.
	 */
	for (; lvl < NIX_TXSCH_LVL_CNT; lvl++)
		pfvf->pfc_schq_list[lvl][prio] = pfvf->hw.txschq_list[lvl][0];

	pfvf->pfc_alloc_status[prio] = true;
	return 0;
}

int otx2_pfc_txschq_alloc(struct otx2_nic *pfvf)
{
	u8 pfc_en = pfvf->pfc_en;
	u8 pfc_bit_set;
	int err, prio;

	for (prio = 0; prio < NIX_PF_PFC_PRIO_MAX; prio++) {
		pfc_bit_set = pfc_en & (1 << prio);

		if (!pfc_bit_set || pfvf->pfc_alloc_status[prio])
			continue;

		/* Add new scheduler to the priority */
		err = otx2_pfc_txschq_alloc_one(pfvf, prio);
		if (err) {
			dev_err(pfvf->dev, "%s failed to allocate PFC TX schedulers\n", __func__);
			return err;
		}
	}

	return 0;
}
EXPORT_SYMBOL(otx2_pfc_txschq_alloc);

static int otx2_pfc_txschq_stop_one(struct otx2_nic *pfvf, u8 prio)
{
	int lvl;

	/* free PFC TLx nodes */
	for (lvl = 0; lvl <= pfvf->hw.txschq_link_cfg_lvl; lvl++)
		otx2_txschq_free_one(pfvf, lvl,
				     pfvf->pfc_schq_list[lvl][prio]);

Annotation

Implementation Notes