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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/steering/sws/dr_domain.c
Extension
.c
Size
14315 bytes
Lines
558
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

// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
/* Copyright (c) 2019 Mellanox Technologies. */

#include <linux/mlx5/eswitch.h>
#include <linux/err.h>
#include "dr_types.h"

#define DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, dmn_type)	\
	((dmn)->info.caps.dmn_type##_sw_owner ||	\
	 ((dmn)->info.caps.dmn_type##_sw_owner_v2 &&	\
	  (dmn)->info.caps.sw_format_ver <= MLX5_STEERING_FORMAT_CONNECTX_8))

bool mlx5dr_domain_is_support_ptrn_arg(struct mlx5dr_domain *dmn)
{
	return dmn->info.caps.sw_format_ver >= MLX5_STEERING_FORMAT_CONNECTX_6DX &&
	       dmn->info.caps.support_modify_argument;
}

static int dr_domain_init_modify_header_resources(struct mlx5dr_domain *dmn)
{
	if (!mlx5dr_domain_is_support_ptrn_arg(dmn))
		return 0;

	dmn->ptrn_mgr = mlx5dr_ptrn_mgr_create(dmn);
	if (!dmn->ptrn_mgr) {
		mlx5dr_err(dmn, "Couldn't create ptrn_mgr\n");
		return -ENOMEM;
	}

	/* create argument pool */
	dmn->arg_mgr = mlx5dr_arg_mgr_create(dmn);
	if (!dmn->arg_mgr) {
		mlx5dr_err(dmn, "Couldn't create arg_mgr\n");
		goto free_modify_header_pattern;
	}

	return 0;

free_modify_header_pattern:
	mlx5dr_ptrn_mgr_destroy(dmn->ptrn_mgr);
	return -ENOMEM;
}

static void dr_domain_destroy_modify_header_resources(struct mlx5dr_domain *dmn)
{
	if (!mlx5dr_domain_is_support_ptrn_arg(dmn))
		return;

	mlx5dr_arg_mgr_destroy(dmn->arg_mgr);
	mlx5dr_ptrn_mgr_destroy(dmn->ptrn_mgr);
}

static void dr_domain_init_csum_recalc_fts(struct mlx5dr_domain *dmn)
{
	/* Per vport cached FW FT for checksum recalculation, this
	 * recalculation is needed due to a HW bug in STEv0.
	 */
	xa_init(&dmn->csum_fts_xa);
}

static void dr_domain_uninit_csum_recalc_fts(struct mlx5dr_domain *dmn)
{
	struct mlx5dr_fw_recalc_cs_ft *recalc_cs_ft;
	unsigned long i;

	xa_for_each(&dmn->csum_fts_xa, i, recalc_cs_ft) {
		if (recalc_cs_ft)
			mlx5dr_fw_destroy_recalc_cs_ft(dmn, recalc_cs_ft);
	}

	xa_destroy(&dmn->csum_fts_xa);
}

int mlx5dr_domain_get_recalc_cs_ft_addr(struct mlx5dr_domain *dmn,
					u16 vport_num,
					u64 *rx_icm_addr)
{
	struct mlx5dr_fw_recalc_cs_ft *recalc_cs_ft;
	int ret;

	recalc_cs_ft = xa_load(&dmn->csum_fts_xa, vport_num);
	if (!recalc_cs_ft) {
		/* Table hasn't been created yet */
		recalc_cs_ft = mlx5dr_fw_create_recalc_cs_ft(dmn, vport_num);
		if (!recalc_cs_ft)
			return -EINVAL;

		ret = xa_err(xa_store(&dmn->csum_fts_xa, vport_num,
				      recalc_cs_ft, GFP_KERNEL));
		if (ret)

Annotation

Implementation Notes