drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlxsw/spectrum2_mr_tcam.c
Extension
.c
Size
10034 bytes
Lines
335
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 mlxsw_sp2_mr_tcam {
	struct mlxsw_sp *mlxsw_sp;
	struct mlxsw_sp_flow_block *flow_block;
	struct mlxsw_sp_acl_ruleset *ruleset4;
	struct mlxsw_sp_acl_ruleset *ruleset6;
};

struct mlxsw_sp2_mr_route {
	struct mlxsw_sp2_mr_tcam *mr_tcam;
};

static struct mlxsw_sp_acl_ruleset *
mlxsw_sp2_mr_tcam_proto_ruleset(struct mlxsw_sp2_mr_tcam *mr_tcam,
				enum mlxsw_sp_l3proto proto)
{
	switch (proto) {
	case MLXSW_SP_L3_PROTO_IPV4:
		return mr_tcam->ruleset4;
	case MLXSW_SP_L3_PROTO_IPV6:
		return mr_tcam->ruleset6;
	}
	return NULL;
}

static int mlxsw_sp2_mr_tcam_bind_group(struct mlxsw_sp *mlxsw_sp,
					enum mlxsw_reg_pemrbt_protocol protocol,
					struct mlxsw_sp_acl_ruleset *ruleset)
{
	char pemrbt_pl[MLXSW_REG_PEMRBT_LEN];
	u16 group_id;

	group_id = mlxsw_sp_acl_ruleset_group_id(ruleset);

	mlxsw_reg_pemrbt_pack(pemrbt_pl, protocol, group_id);
	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pemrbt), pemrbt_pl);
}

static const enum mlxsw_afk_element mlxsw_sp2_mr_tcam_usage_ipv4[] = {
		MLXSW_AFK_ELEMENT_VIRT_ROUTER,
		MLXSW_AFK_ELEMENT_SRC_IP_0_31,
		MLXSW_AFK_ELEMENT_DST_IP_0_31,
};

static int mlxsw_sp2_mr_tcam_ipv4_init(struct mlxsw_sp2_mr_tcam *mr_tcam)
{
	struct mlxsw_afk_element_usage elusage;
	int err;

	/* Initialize IPv4 ACL group. */
	mlxsw_afk_element_usage_fill(&elusage,
				     mlxsw_sp2_mr_tcam_usage_ipv4,
				     ARRAY_SIZE(mlxsw_sp2_mr_tcam_usage_ipv4));
	mr_tcam->ruleset4 = mlxsw_sp_acl_ruleset_get(mr_tcam->mlxsw_sp,
						     mr_tcam->flow_block,
						     MLXSW_SP_L3_PROTO_IPV4,
						     MLXSW_SP_ACL_PROFILE_MR,
						     &elusage);

	if (IS_ERR(mr_tcam->ruleset4))
		return PTR_ERR(mr_tcam->ruleset4);

	/* MC Router groups should be bound before routes are inserted. */
	err = mlxsw_sp2_mr_tcam_bind_group(mr_tcam->mlxsw_sp,
					   MLXSW_REG_PEMRBT_PROTO_IPV4,
					   mr_tcam->ruleset4);
	if (err)
		goto err_bind_group;

	return 0;

err_bind_group:
	mlxsw_sp_acl_ruleset_put(mr_tcam->mlxsw_sp, mr_tcam->ruleset4);
	return err;
}

static void mlxsw_sp2_mr_tcam_ipv4_fini(struct mlxsw_sp2_mr_tcam *mr_tcam)
{
	mlxsw_sp_acl_ruleset_put(mr_tcam->mlxsw_sp, mr_tcam->ruleset4);
}

static const enum mlxsw_afk_element mlxsw_sp2_mr_tcam_usage_ipv6[] = {
		MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_3,
		MLXSW_AFK_ELEMENT_VIRT_ROUTER_4_7,
		MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB,
		MLXSW_AFK_ELEMENT_SRC_IP_96_127,
		MLXSW_AFK_ELEMENT_SRC_IP_64_95,
		MLXSW_AFK_ELEMENT_SRC_IP_32_63,
		MLXSW_AFK_ELEMENT_SRC_IP_0_31,
		MLXSW_AFK_ELEMENT_DST_IP_96_127,
		MLXSW_AFK_ELEMENT_DST_IP_64_95,

Annotation

Implementation Notes