drivers/net/ethernet/microchip/lan966x/lan966x_dcb.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/lan966x/lan966x_dcb.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/lan966x/lan966x_dcb.c
Extension
.c
Size
8743 bytes
Lines
366
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+

#include "lan966x_main.h"

enum lan966x_dcb_apptrust_values {
	LAN966X_DCB_APPTRUST_EMPTY,
	LAN966X_DCB_APPTRUST_DSCP,
	LAN966X_DCB_APPTRUST_PCP,
	LAN966X_DCB_APPTRUST_DSCP_PCP,
	__LAN966X_DCB_APPTRUST_MAX
};

static const struct lan966x_dcb_apptrust {
	u8 selectors[IEEE_8021QAZ_APP_SEL_MAX + 1];
	int nselectors;
} *lan966x_port_apptrust[NUM_PHYS_PORTS];

static const char *lan966x_dcb_apptrust_names[__LAN966X_DCB_APPTRUST_MAX] = {
	[LAN966X_DCB_APPTRUST_EMPTY]    = "empty",
	[LAN966X_DCB_APPTRUST_DSCP]     = "dscp",
	[LAN966X_DCB_APPTRUST_PCP]      = "pcp",
	[LAN966X_DCB_APPTRUST_DSCP_PCP] = "dscp pcp"
};

/* Lan966x supported apptrust policies */
static const struct lan966x_dcb_apptrust
	lan966x_dcb_apptrust_policies[__LAN966X_DCB_APPTRUST_MAX] = {
	/* Empty *must* be first */
	[LAN966X_DCB_APPTRUST_EMPTY]    = { { 0 }, 0 },
	[LAN966X_DCB_APPTRUST_DSCP]     = { { IEEE_8021QAZ_APP_SEL_DSCP }, 1 },
	[LAN966X_DCB_APPTRUST_PCP]      = { { DCB_APP_SEL_PCP }, 1 },
	[LAN966X_DCB_APPTRUST_DSCP_PCP] = { { IEEE_8021QAZ_APP_SEL_DSCP,
					      DCB_APP_SEL_PCP }, 2 },
};

static bool lan966x_dcb_apptrust_contains(int portno, u8 selector)
{
	const struct lan966x_dcb_apptrust *conf = lan966x_port_apptrust[portno];

	for (int i = 0; i < conf->nselectors; i++)
		if (conf->selectors[i] == selector)
			return true;

	return false;
}

static void lan966x_dcb_app_update(struct net_device *dev)
{
	struct dcb_ieee_app_prio_map dscp_rewr_map = {0};
	struct dcb_rewr_prio_pcp_map pcp_rewr_map = {0};
	struct lan966x_port *port = netdev_priv(dev);
	struct lan966x_port_qos qos = {0};
	struct dcb_app app_itr;
	bool dscp_rewr = false;
	bool pcp_rewr = false;

	/* Get pcp ingress mapping */
	for (int i = 0; i < ARRAY_SIZE(qos.pcp.map); i++) {
		app_itr.selector = DCB_APP_SEL_PCP;
		app_itr.protocol = i;
		qos.pcp.map[i] = dcb_getapp(dev, &app_itr);
	}

	/* Get dscp ingress mapping */
	for (int i = 0; i < ARRAY_SIZE(qos.dscp.map); i++) {
		app_itr.selector = IEEE_8021QAZ_APP_SEL_DSCP;
		app_itr.protocol = i;
		qos.dscp.map[i] = dcb_getapp(dev, &app_itr);
	}

	/* Get default prio */
	qos.default_prio = dcb_ieee_getapp_default_prio_mask(dev);
	if (qos.default_prio)
		qos.default_prio = fls(qos.default_prio) - 1;

	/* Get pcp rewrite mapping */
	dcb_getrewr_prio_pcp_mask_map(dev, &pcp_rewr_map);
	for (int i = 0; i < ARRAY_SIZE(pcp_rewr_map.map); i++) {
		if (!pcp_rewr_map.map[i])
			continue;

		pcp_rewr = true;
		qos.pcp_rewr.map[i] = fls(pcp_rewr_map.map[i]) - 1;
	}

	/* Get dscp rewrite mapping */
	dcb_getrewr_prio_dscp_mask_map(dev, &dscp_rewr_map);
	for (int i = 0; i < ARRAY_SIZE(dscp_rewr_map.map); i++) {
		if (!dscp_rewr_map.map[i])
			continue;

Annotation

Implementation Notes