drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c
Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c- Extension
.c- Size
- 31272 bytes
- Lines
- 1102
- 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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
internal.h
Detected Declarations
function hws_match_params_exceeds_definerfunction casesfunction mlx5hws_bwc_match_params_is_complexfunction hws_get_last_set_dword_idxfunction hws_match_mask_is_emptyfunction hws_dword_is_inner_ipaddr_offfunction hws_dword_is_outer_ipaddr_offfunction hws_add_dword_to_maskfunction hws_remove_dword_from_maskfunction hws_avoid_ipv6_split_offunction hws_avoid_ipv6_splitfunction hws_get_simple_paramsfunction hws_bwc_matcher_split_maskfunction hws_isolated_table_createfunction hws_submatcher_init_firstfunction hws_submatcher_initfunction hws_submatcher_destroyfunction hws_complex_data_actions_initfunction hws_complex_data_actions_destroyfunction mlx5hws_bwc_matcher_create_complexfunction mlx5hws_bwc_matcher_destroy_complexfunction hws_complex_get_subrule_datafunction hws_complex_put_subrule_datafunction hws_complex_subrule_createfunction hws_complex_subrule_destroyfunction mlx5hws_bwc_rule_create_complexfunction mlx5hws_bwc_rule_destroy_complexfunction hws_bwc_matcher_init_movefunction list_for_each_entryfunction mlx5hws_bwc_matcher_complex_movefunction list_for_each_entryfunction mlx5hws_bwc_matcher_complex_move_first
Annotated Snippet
if (ret == -E2BIG) {
is_complex = true;
mlx5hws_dbg(ctx, "Matcher definer layout: need complex matcher\n");
} else {
mlx5hws_err(ctx, "Failed to calculate matcher definer layout\n");
}
} else {
kfree(mt->fc);
}
mlx5hws_match_template_destroy(mt);
return is_complex;
}
bool mlx5hws_bwc_match_params_is_complex(struct mlx5hws_context *ctx,
u8 match_criteria_enable,
struct mlx5hws_match_parameters *mask)
{
return hws_match_params_exceeds_definer(ctx, match_criteria_enable,
mask, true);
}
static int
hws_get_last_set_dword_idx(const struct mlx5hws_match_parameters *mask)
{
int i;
for (i = mask->match_sz / 4 - 1; i >= 0; i--)
if (mask->match_buf[i])
return i;
return -1;
}
static bool hws_match_mask_is_empty(const struct mlx5hws_match_parameters *mask)
{
return hws_get_last_set_dword_idx(mask) == -1;
}
static bool hws_dword_is_inner_ipaddr_off(int dword_off)
{
/* IPv4 and IPv6 addresses share the same entry via a union, and the
* source and dest addresses are contiguous in the fte_match_param. So
* we need to check 8 words.
*/
static const int inner_ip_dword_off =
__mlx5_dw_off(fte_match_param, inner_headers.src_ipv4_src_ipv6);
return dword_off >= inner_ip_dword_off &&
dword_off < inner_ip_dword_off + 8;
}
static bool hws_dword_is_outer_ipaddr_off(int dword_off)
{
static const int outer_ip_dword_off =
__mlx5_dw_off(fte_match_param, outer_headers.src_ipv4_src_ipv6);
return dword_off >= outer_ip_dword_off &&
dword_off < outer_ip_dword_off + 8;
}
static void hws_add_dword_to_mask(struct mlx5hws_match_parameters *mask,
const struct mlx5hws_match_parameters *orig,
int dword_idx, bool *added_inner_ipv,
bool *added_outer_ipv)
{
mask->match_buf[dword_idx] |= orig->match_buf[dword_idx];
*added_inner_ipv = false;
*added_outer_ipv = false;
/* Any IP address fragment must be accompanied by a match on IP version.
* Use the `added_ipv` variables to keep track if we added IP versions
* specifically for this dword, so that we can roll them back if the
* match params become too large to fit into a definer.
*/
if (hws_dword_is_inner_ipaddr_off(dword_idx) &&
!MLX5_GET(fte_match_param, mask->match_buf,
inner_headers.ip_version)) {
MLX5_SET(fte_match_param, mask->match_buf,
inner_headers.ip_version, 0xf);
*added_inner_ipv = true;
}
if (hws_dword_is_outer_ipaddr_off(dword_idx) &&
!MLX5_GET(fte_match_param, mask->match_buf,
outer_headers.ip_version)) {
MLX5_SET(fte_match_param, mask->match_buf,
outer_headers.ip_version, 0xf);
*added_outer_ipv = true;
Annotation
- Immediate include surface: `internal.h`.
- Detected declarations: `function hws_match_params_exceeds_definer`, `function cases`, `function mlx5hws_bwc_match_params_is_complex`, `function hws_get_last_set_dword_idx`, `function hws_match_mask_is_empty`, `function hws_dword_is_inner_ipaddr_off`, `function hws_dword_is_outer_ipaddr_off`, `function hws_add_dword_to_mask`, `function hws_remove_dword_from_mask`, `function hws_avoid_ipv6_split_of`.
- Atlas domain: Driver Families / drivers/net.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.