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

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

File Facts

System
Linux kernel
Corpus path
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
Extension
.c
Size
36253 bytes
Lines
1323
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

if (err) {
			if (err == -EMSGSIZE) {
				if (!j)
					goto err_entry_append;
				break;
			}
			goto err_entry_append;
		}
		j++;
	}

	devlink_dpipe_entry_ctx_close(dump_ctx);
	if (i != rif_count)
		goto start_again;
	mutex_unlock(&mlxsw_sp->router->lock);

	devlink_dpipe_entry_clear(&entry);
	return 0;
err_entry_append:
err_entry_get:
err_ctx_prepare:
	mutex_unlock(&mlxsw_sp->router->lock);
	devlink_dpipe_entry_clear(&entry);
	return err;
}

static int mlxsw_sp_dpipe_table_erif_counters_update(void *priv, bool enable)
{
	struct mlxsw_sp *mlxsw_sp = priv;
	int i;

	mutex_lock(&mlxsw_sp->router->lock);
	for (i = 0; i < MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS); i++) {
		struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);

		if (!rif)
			continue;
		if (enable)
			mlxsw_sp_rif_counter_alloc(rif,
						   MLXSW_SP_RIF_COUNTER_EGRESS);
		else
			mlxsw_sp_rif_counter_free(rif,
						  MLXSW_SP_RIF_COUNTER_EGRESS);
	}
	mutex_unlock(&mlxsw_sp->router->lock);
	return 0;
}

static u64 mlxsw_sp_dpipe_table_erif_size_get(void *priv)
{
	struct mlxsw_sp *mlxsw_sp = priv;

	return MLXSW_CORE_RES_GET(mlxsw_sp->core, MAX_RIFS);
}

static const struct devlink_dpipe_table_ops mlxsw_sp_erif_ops = {
	.matches_dump = mlxsw_sp_dpipe_table_erif_matches_dump,
	.actions_dump = mlxsw_sp_dpipe_table_erif_actions_dump,
	.entries_dump = mlxsw_sp_dpipe_table_erif_entries_dump,
	.counters_set_update = mlxsw_sp_dpipe_table_erif_counters_update,
	.size_get = mlxsw_sp_dpipe_table_erif_size_get,
};

static int mlxsw_sp_dpipe_erif_table_init(struct mlxsw_sp *mlxsw_sp)
{
	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);

	return devl_dpipe_table_register(devlink,
					 MLXSW_SP_DPIPE_TABLE_NAME_ERIF,
					 &mlxsw_sp_erif_ops,
					 mlxsw_sp, false);
}

static void mlxsw_sp_dpipe_erif_table_fini(struct mlxsw_sp *mlxsw_sp)
{
	struct devlink *devlink = priv_to_devlink(mlxsw_sp->core);

	devl_dpipe_table_unregister(devlink, MLXSW_SP_DPIPE_TABLE_NAME_ERIF);
}

static int mlxsw_sp_dpipe_table_host_matches_dump(struct sk_buff *skb, int type)
{
	struct devlink_dpipe_match match = {0};
	int err;

	match.type = DEVLINK_DPIPE_MATCH_TYPE_FIELD_EXACT;
	match.header = &mlxsw_sp_dpipe_header_metadata;
	match.field_id = MLXSW_SP_DPIPE_FIELD_METADATA_ERIF_PORT;

	err = devlink_dpipe_match_put(skb, &match);

Annotation

Implementation Notes