drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ste.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ste.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_ste.c
Extension
.c
Size
45703 bytes
Lines
1466
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 dr_hw_ste_format {
	u8 ctrl[DR_STE_SIZE_CTRL];
	u8 tag[DR_STE_SIZE_TAG];
	u8 mask[DR_STE_SIZE_MASK];
};

static u32 dr_ste_crc32_calc(const void *input_data, size_t length)
{
	u32 crc = crc32(0, input_data, length);

	return (__force u32)((crc >> 24) & 0xff) | ((crc << 8) & 0xff0000) |
			    ((crc >> 8) & 0xff00) | ((crc << 24) & 0xff000000);
}

bool mlx5dr_ste_supp_ttl_cs_recalc(struct mlx5dr_cmd_caps *caps)
{
	return caps->sw_format_ver > MLX5_STEERING_FORMAT_CONNECTX_5;
}

u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl)
{
	u32 num_entries = mlx5dr_icm_pool_get_chunk_num_of_entries(htbl->chunk);
	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
	u8 masked[DR_STE_SIZE_TAG] = {};
	u32 crc32, index;
	u16 bit;
	int i;

	/* Don't calculate CRC if the result is predicted */
	if (num_entries == 1 || htbl->byte_mask == 0)
		return 0;

	/* Mask tag using byte mask, bit per byte */
	bit = 1 << (DR_STE_SIZE_TAG - 1);
	for (i = 0; i < DR_STE_SIZE_TAG; i++) {
		if (htbl->byte_mask & bit)
			masked[i] = hw_ste->tag[i];

		bit = bit >> 1;
	}

	crc32 = dr_ste_crc32_calc(masked, DR_STE_SIZE_TAG);
	index = crc32 & (num_entries - 1);

	return index;
}

u16 mlx5dr_ste_conv_bit_to_byte_mask(u8 *bit_mask)
{
	u16 byte_mask = 0;
	int i;

	for (i = 0; i < DR_STE_SIZE_MASK; i++) {
		byte_mask = byte_mask << 1;
		if (bit_mask[i] == 0xff)
			byte_mask |= 1;
	}
	return byte_mask;
}

static u8 *dr_ste_get_tag(u8 *hw_ste_p)
{
	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;

	return hw_ste->tag;
}

void mlx5dr_ste_set_bit_mask(u8 *hw_ste_p, u8 *bit_mask)
{
	struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;

	memcpy(hw_ste->mask, bit_mask, DR_STE_SIZE_MASK);
}

static void dr_ste_set_always_hit(struct dr_hw_ste_format *hw_ste)
{
	memset(&hw_ste->tag, 0, sizeof(hw_ste->tag));
	memset(&hw_ste->mask, 0, sizeof(hw_ste->mask));
}

static void dr_ste_set_always_miss(struct dr_hw_ste_format *hw_ste)
{
	hw_ste->tag[0] = 0xdc;
	hw_ste->mask[0] = 0;
}

bool mlx5dr_ste_is_miss_addr_set(struct mlx5dr_ste_ctx *ste_ctx,
				 u8 *hw_ste_p)
{
	if (!ste_ctx->is_miss_addr_set)

Annotation

Implementation Notes