drivers/net/ethernet/netronome/nfp/flower/match.c

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/netronome/nfp/flower/match.c
Extension
.c
Size
21131 bytes
Lines
723
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 (!cmsg_port) {
			NL_SET_ERR_MSG_MOD(extack, "unsupported offload: invalid ingress interface for match offload");
			return -EOPNOTSUPP;
		}
		frame->in_port = cpu_to_be32(cmsg_port);
	}

	return 0;
}

void
nfp_flower_compile_mac(struct nfp_flower_mac_mpls *ext,
		       struct nfp_flower_mac_mpls *msk,
		       struct flow_rule *rule)
{
	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
		struct flow_match_eth_addrs match;
		u8 tmp;
		int i;

		flow_rule_match_eth_addrs(rule, &match);
		/* Populate mac frame. */
		for (i = 0; i < ETH_ALEN; i++) {
			tmp = match.key->dst[i] & match.mask->dst[i];
			ext->mac_dst[i] |= tmp & (~msk->mac_dst[i]);
			msk->mac_dst[i] |= match.mask->dst[i];

			tmp = match.key->src[i] & match.mask->src[i];
			ext->mac_src[i] |= tmp & (~msk->mac_src[i]);
			msk->mac_src[i] |= match.mask->src[i];
		}
	}
}

int
nfp_flower_compile_mpls(struct nfp_flower_mac_mpls *ext,
			struct nfp_flower_mac_mpls *msk,
			struct flow_rule *rule,
			struct netlink_ext_ack *extack)
{
	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS)) {
		struct flow_match_mpls match;
		u32 key_mpls, msk_mpls;

		flow_rule_match_mpls(rule, &match);

		/* Only support matching the first LSE */
		if (match.mask->used_lses != 1) {
			NL_SET_ERR_MSG_MOD(extack,
					   "unsupported offload: invalid LSE depth for MPLS match offload");
			return -EOPNOTSUPP;
		}

		key_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB,
				      match.key->ls[0].mpls_label) |
			   FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC,
				      match.key->ls[0].mpls_tc) |
			   FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS,
				      match.key->ls[0].mpls_bos) |
			   NFP_FLOWER_MASK_MPLS_Q;

		msk_mpls = FIELD_PREP(NFP_FLOWER_MASK_MPLS_LB,
				      match.mask->ls[0].mpls_label) |
			   FIELD_PREP(NFP_FLOWER_MASK_MPLS_TC,
				      match.mask->ls[0].mpls_tc) |
			   FIELD_PREP(NFP_FLOWER_MASK_MPLS_BOS,
				      match.mask->ls[0].mpls_bos) |
			   NFP_FLOWER_MASK_MPLS_Q;

		ext->mpls_lse |= cpu_to_be32((key_mpls & msk_mpls));
		msk->mpls_lse |= cpu_to_be32(msk_mpls);
	} else if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
		/* Check for mpls ether type and set NFP_FLOWER_MASK_MPLS_Q
		 * bit, which indicates an mpls ether type but without any
		 * mpls fields.
		 */
		struct flow_match_basic match;

		flow_rule_match_basic(rule, &match);
		if (match.key->n_proto == cpu_to_be16(ETH_P_MPLS_UC) ||
		    match.key->n_proto == cpu_to_be16(ETH_P_MPLS_MC)) {
			ext->mpls_lse |= cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
			msk->mpls_lse |= cpu_to_be32(NFP_FLOWER_MASK_MPLS_Q);
		}
	}

	return 0;
}

static int

Annotation

Implementation Notes