drivers/net/ethernet/netronome/nfp/nic/dcb.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/netronome/nfp/nic/dcb.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/nic/dcb.c
Extension
.c
Size
13626 bytes
Lines
572
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

if (dcb->tc2idx[j] != tc2idx[j]) {
			change = true;
			dcb->tc2idx[j] = tc2idx[j];
		}
	}

	return change;
}

static int nfp_fill_maxrate(struct nfp_net *nn, u64 *max_rate_array)
{
	struct nfp_app *app  = nn->app;
	struct nfp_dcb *dcb;
	u32 ratembps;

	dcb = get_dcb_priv(nn);

	for (unsigned int i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
		/* Convert bandwidth from kbps to mbps. */
		ratembps = max_rate_array[i] / 1024;

		/* Reject input values >= NFP_DCB_TC_RATE_MAX */
		if (ratembps >= NFP_DCB_TC_RATE_MAX) {
			nfp_warn(app->cpp, "ratembps(%d) must less than %d.",
				 ratembps, NFP_DCB_TC_RATE_MAX);
			return -EINVAL;
		}
		/* Input value 0 mapped to NFP_DCB_TC_RATE_MAX for firmware. */
		if (ratembps == 0)
			ratembps = NFP_DCB_TC_RATE_MAX;

		writew((u16)ratembps, dcb->dcbcfg_tbl +
		       dcb->cfg_offset + NFP_DCB_DATA_OFF_RATE + dcb->tc2idx[i] * 2);
		/* for rate value from user space, need to sync to dcb structure */
		if (dcb->tc_maxrate != max_rate_array)
			dcb->tc_maxrate[i] = max_rate_array[i];
	}

	return 0;
}

static int update_dscp_maxrate(struct net_device *dev, u32 *update)
{
	struct nfp_net *nn = netdev_priv(dev);
	struct nfp_dcb *dcb;
	int err;

	dcb = get_dcb_priv(nn);

	err = nfp_fill_maxrate(nn, dcb->tc_maxrate);
	if (err)
		return err;

	*update |= NFP_DCB_MSG_MSK_RATE;

	/* We only refresh dscp in dscp trust mode. */
	if (dcb->dscp_cnt > 0) {
		for (unsigned int i = 0; i < NFP_NET_MAX_DSCP; i++) {
			writeb(dcb->tc2idx[dcb->prio2tc[dcb->dscp2prio[i]]],
			       dcb->dcbcfg_tbl + dcb->cfg_offset +
			       NFP_DCB_DATA_OFF_DSCP2IDX + i);
		}
		*update |= NFP_DCB_MSG_MSK_DSCP;
	}

	return 0;
}

static void nfp_nic_set_trust(struct nfp_net *nn, u32 *update)
{
	struct nfp_dcb *dcb;
	u8 trust;

	dcb = get_dcb_priv(nn);

	if (dcb->trust_status != NFP_DCB_TRUST_INVALID)
		return;

	trust = dcb->dscp_cnt > 0 ? NFP_DCB_TRUST_DSCP : NFP_DCB_TRUST_PCP;
	writeb(trust, dcb->dcbcfg_tbl + dcb->cfg_offset +
	       NFP_DCB_DATA_OFF_TRUST);

	dcb->trust_status = trust;
	*update |= NFP_DCB_MSG_MSK_TRUST;
}

static void nfp_nic_set_enable(struct nfp_net *nn, u32 enable, u32 *update)
{
	struct nfp_dcb *dcb;
	u32 value = 0;

Annotation

Implementation Notes