drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_ofld.c

Source file repositories/reference/linux-study-clean/drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_ofld.c

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlx5/core/esw/acl/egress_ofld.c
Extension
.c
Size
7673 bytes
Lines
275
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) 2020 Mellanox Technologies Inc. All rights reserved. */

#include "mlx5_core.h"
#include "eswitch.h"
#include "helper.h"
#include "ofld.h"

static void esw_acl_egress_ofld_fwd2vport_destroy(struct mlx5_vport *vport)
{
	if (!vport->egress.offloads.fwd_rule)
		return;

	mlx5_del_flow_rules(vport->egress.offloads.fwd_rule);
	vport->egress.offloads.fwd_rule = NULL;
}

void esw_acl_egress_ofld_bounce_rule_destroy(struct mlx5_vport *vport, int rule_index)
{
	struct mlx5_flow_handle *bounce_rule =
		xa_load(&vport->egress.offloads.bounce_rules, rule_index);

	if (!bounce_rule)
		return;

	mlx5_del_flow_rules(bounce_rule);
	xa_erase(&vport->egress.offloads.bounce_rules, rule_index);
}

static void esw_acl_egress_ofld_bounce_rules_destroy(struct mlx5_vport *vport)
{
	struct mlx5_flow_handle *bounce_rule;
	unsigned long i;

	xa_for_each(&vport->egress.offloads.bounce_rules, i, bounce_rule) {
		mlx5_del_flow_rules(bounce_rule);
		xa_erase(&vport->egress.offloads.bounce_rules, i);
	}
}

static int esw_acl_egress_ofld_fwd2vport_create(struct mlx5_eswitch *esw,
						struct mlx5_vport *vport,
						struct mlx5_flow_destination *fwd_dest)
{
	struct mlx5_flow_act flow_act = {};
	int err = 0;

	esw_debug(esw->dev, "vport(%d) configure egress acl rule fwd2vport(%d)\n",
		  vport->vport, fwd_dest->vport.num);

	/* Delete the old egress forward-to-vport rule if any */
	esw_acl_egress_ofld_fwd2vport_destroy(vport);

	flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;

	vport->egress.offloads.fwd_rule =
		mlx5_add_flow_rules(vport->egress.acl, NULL,
				    &flow_act, fwd_dest, 1);
	if (IS_ERR(vport->egress.offloads.fwd_rule)) {
		err = PTR_ERR(vport->egress.offloads.fwd_rule);
		esw_warn(esw->dev,
			 "vport(%d) failed to add fwd2vport acl rule err(%d)\n",
			 vport->vport, err);
		vport->egress.offloads.fwd_rule = NULL;
	}

	return err;
}

static int esw_acl_egress_ofld_rules_create(struct mlx5_eswitch *esw,
					    struct mlx5_vport *vport,
					    struct mlx5_flow_destination *fwd_dest)
{
	int err = 0;
	int action;

	if (MLX5_CAP_GEN(esw->dev, prio_tag_required)) {
		/* For prio tag mode, there is only 1 FTEs:
		 * 1) prio tag packets - pop the prio tag VLAN, allow
		 * Unmatched traffic is allowed by default
		 */
		esw_debug(esw->dev,
			  "vport[%d] configure prio tag egress rules\n", vport->vport);

		action = MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
		action |= fwd_dest ? MLX5_FLOW_CONTEXT_ACTION_FWD_DEST :
			  MLX5_FLOW_CONTEXT_ACTION_ALLOW;

		/* prio tag vlan rule - pop it so vport receives untagged packets */
		err = esw_egress_acl_vlan_create(esw, vport, fwd_dest, 0, action);

Annotation

Implementation Notes