drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c
Extension
.c
Size
41638 bytes
Lines
1592
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

struct sparx5_wildcard_rule {
	bool selected;
	u8 value;
	u8 mask;
	enum vcap_keyfield_set keyset;
};

struct sparx5_multiple_rules {
	struct sparx5_wildcard_rule rule[SPX5_MAX_RULE_SIZE];
};

struct sparx5_tc_flower_template {
	struct list_head list; /* for insertion in the list of templates */
	int cid; /* chain id */
	enum vcap_keyfield_set orig; /* keyset used before the template */
	enum vcap_keyfield_set keyset; /* new keyset used by template */
	u16 l3_proto; /* protocol specified in the template */
};

/* SparX-5 VCAP fragment types:
 * 0 = no fragment, 1 = initial fragment,
 * 2 = suspicious fragment, 3 = valid follow-up fragment
 */
enum {                   /* key / mask */
	FRAG_NOT   = 0x03, /* 0 / 3 */
	FRAG_SOME  = 0x11, /* 1 / 1 */
	FRAG_FIRST = 0x13, /* 1 / 3 */
	FRAG_LATER = 0x33, /* 3 / 3 */
	FRAG_INVAL = 0xff, /* invalid */
};

/* Flower fragment flag to VCAP fragment type mapping */
static const u8 sparx5_vcap_frag_map[4][4] = {		  /* is_frag */
	{ FRAG_INVAL, FRAG_INVAL, FRAG_INVAL, FRAG_FIRST }, /* 0/0 */
	{ FRAG_NOT,   FRAG_NOT,   FRAG_INVAL, FRAG_INVAL }, /* 0/1 */
	{ FRAG_INVAL, FRAG_INVAL, FRAG_INVAL, FRAG_INVAL }, /* 1/0 */
	{ FRAG_SOME,  FRAG_LATER, FRAG_INVAL, FRAG_FIRST }  /* 1/1 */
	/* 0/0	      0/1	  1/0	      1/1 <-- first_frag */
};

static int
sparx5_tc_flower_es0_tpid(struct vcap_tc_flower_parse_usage *st)
{
	int err = 0;

	switch (st->tpid) {
	case ETH_P_8021Q:
		err = vcap_rule_add_key_u32(st->vrule,
					    VCAP_KF_8021Q_TPID,
					    SPX5_TPID_SEL_8100, ~0);
		break;
	case ETH_P_8021AD:
		err = vcap_rule_add_key_u32(st->vrule,
					    VCAP_KF_8021Q_TPID,
					    SPX5_TPID_SEL_88A8, ~0);
		break;
	default:
		NL_SET_ERR_MSG_MOD(st->fco->common.extack,
				   "Invalid vlan proto");
		err = -EINVAL;
		break;
	}
	return err;
}

static int
sparx5_tc_flower_handler_basic_usage(struct vcap_tc_flower_parse_usage *st)
{
	struct flow_match_basic mt;
	int err = 0;

	flow_rule_match_basic(st->frule, &mt);

	if (mt.mask->n_proto) {
		st->l3_proto = be16_to_cpu(mt.key->n_proto);
		if (!sparx5_vcap_is_known_etype(st->admin, st->l3_proto)) {
			err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ETYPE,
						    st->l3_proto, ~0);
			if (err)
				goto out;
		} else if (st->l3_proto == ETH_P_IP) {
			err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_IP4_IS,
						    VCAP_BIT_1);
			if (err)
				goto out;
		} else if (st->l3_proto == ETH_P_IPV6) {
			err = vcap_rule_add_key_bit(st->vrule, VCAP_KF_IP4_IS,
						    VCAP_BIT_0);
			if (err)
				goto out;

Annotation

Implementation Notes