Exemplo n.º 1
0
Arquivo: ipoib.c Projeto: metux/linux
static int mlx5i_create_flow_steering(struct mlx5e_priv *priv)
{
	struct ttc_params ttc_params = {};
	int tt, err;

	priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
					       MLX5_FLOW_NAMESPACE_KERNEL);

	if (!priv->fs.ns)
		return -EINVAL;

	err = mlx5e_arfs_create_tables(priv);
	if (err) {
		netdev_err(priv->netdev, "Failed to create arfs tables, err=%d\n",
			   err);
		priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
	}

	mlx5e_set_ttc_basic_params(priv, &ttc_params);
	mlx5e_set_inner_ttc_ft_params(&ttc_params);
	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
		ttc_params.indir_tirn[tt] = priv->inner_indir_tir[tt].tirn;

	err = mlx5e_create_inner_ttc_table(priv, &ttc_params, &priv->fs.inner_ttc);
	if (err) {
		netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n",
			   err);
		goto err_destroy_arfs_tables;
	}

	mlx5e_set_ttc_ft_params(&ttc_params);
	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
		ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn;

	err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
	if (err) {
		netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
			   err);
		goto err_destroy_inner_ttc_table;
	}

	return 0;

err_destroy_inner_ttc_table:
	mlx5e_destroy_inner_ttc_table(priv, &priv->fs.inner_ttc);
err_destroy_arfs_tables:
	mlx5e_arfs_destroy_tables(priv);

	return err;
}
Exemplo n.º 2
0
static int mlx5i_create_flow_steering(struct mlx5e_priv *priv)
{
	int err;

	priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
					       MLX5_FLOW_NAMESPACE_KERNEL);

	if (!priv->fs.ns)
		return -EINVAL;

	err = mlx5e_arfs_create_tables(priv);
	if (err) {
		netdev_err(priv->netdev, "Failed to create arfs tables, err=%d\n",
			   err);
		priv->netdev->hw_features &= ~NETIF_F_NTUPLE;
	}

	err = mlx5e_create_inner_ttc_table(priv);
	if (err) {
		netdev_err(priv->netdev, "Failed to create inner ttc table, err=%d\n",
			   err);
		goto err_destroy_arfs_tables;
	}

	err = mlx5e_create_ttc_table(priv);
	if (err) {
		netdev_err(priv->netdev, "Failed to create ttc table, err=%d\n",
			   err);
		goto err_destroy_inner_ttc_table;
	}

	return 0;

err_destroy_inner_ttc_table:
	mlx5e_destroy_inner_ttc_table(priv);
err_destroy_arfs_tables:
	mlx5e_arfs_destroy_tables(priv);

	return err;
}
Exemplo n.º 3
0
static int mlx5_esw_create_fdb_table(struct mlx5_core_dev *dev, int nvports)
{
	int max_fdb_size = 1 << MLX5_CAP_ESW_FLOWTABLE_FDB(dev, log_max_ft_size);
	struct mlx5_eswitch *esw = &dev->priv.eswitch;
	struct mlx5_flow_group *mc_promisc_grp;
	struct mlx5_flow_namespace *root_ns;
	struct mlx5_flow_group *promisc_grp;
	struct mlx5_flow_group *addr_grp;
	struct mlx5_flow_table *fdb;
	void *match_criteria;
	int table_size;
	u32 *grp_in;
	u8 *dmac;
	int err;

	max_fdb_size -= 2; /* FW reserve */
	table_size = MLX5_MAX_UC_PER_VPORT(dev);
	table_size += MLX5_MAX_MC_PER_VPORT(dev);
	table_size *= nvports;
	table_size += 1; /* TODO: reserve 1 as a FW W/A for modify Rule */
	table_size += 4; /* 2 Promisc groups reserve 1 per each */
	table_size = min(table_size, max_fdb_size - 2);

	esw_debug(dev, "Create FDB talbe size(%d) max_size(%d)\n",
		  table_size, max_fdb_size - 2);
	/* TODO: Don't allow vports to get more than they deserve */
	root_ns = mlx5_get_flow_namespace(dev, MLX5_FLOW_NAMESPACE_FDB);
	if (!root_ns) {
		esw_warn(dev, "Failed to get FDB flow namespace\n");
		return -ENOMEM;
	}

	fdb = mlx5_create_flow_table(root_ns, 0, "eswitch-fdb", table_size);
	if (IS_ERR_OR_NULL(fdb)) {
		esw_warn(dev, "Failed to create FDB flow table err(%ld)\n",
			 PTR_ERR(fdb));
		return PTR_ERR(fdb);
	}

	grp_in = kzalloc(MLX5_ST_SZ_BYTES(create_flow_group_in), GFP_KERNEL);
	if (!grp_in) {
		esw_warn(dev, "Failed to alloc group inbox\n");
		err = -ENOMEM;
		goto err_fdb;
	}

	MLX5_SET(create_flow_group_in, grp_in, match_criteria_enable,
		 MLX5_MATCH_OUTER_HEADERS);
	match_criteria = MLX5_ADDR_OF(create_flow_group_in, grp_in,
				      match_criteria);
	dmac = MLX5_ADDR_OF(fte_match_param, match_criteria,
			    outer_headers.dmac_47_16);

	/* MC/UC ADDR Group */
	MLX5_SET(create_flow_group_in, grp_in, start_flow_index, 0);
	MLX5_SET(create_flow_group_in, grp_in, end_flow_index, table_size - 5);
	memset(dmac, 0xff, ETH_ALEN);

	addr_grp = mlx5_create_flow_group(fdb, grp_in);
	if (IS_ERR_OR_NULL(addr_grp)) {
		esw_warn(dev, "Failed to create uc/mc addr group err(%ld)\n",
			 PTR_ERR(addr_grp));
		err = PTR_ERR(addr_grp);
		goto err_fdb;
	}

	/* MC promisc Group */
	MLX5_SET(create_flow_group_in, grp_in,
		 start_flow_index, table_size - 4);
	MLX5_SET(create_flow_group_in, grp_in,
		 end_flow_index, table_size - 3);
	memset(dmac, 0, ETH_ALEN);
	dmac[0] = 0x01;

	mc_promisc_grp = mlx5_create_flow_group(fdb, grp_in);
	if (IS_ERR_OR_NULL(mc_promisc_grp)) {
		esw_warn(dev, "Failed to create FDB MC promisc group err(%ld)\n",
			 PTR_ERR(mc_promisc_grp));
		err = PTR_ERR(mc_promisc_grp);
		goto err_addr_grp;
	}

	/* Promisc Group */
	MLX5_SET(create_flow_group_in, grp_in, match_criteria_enable, 0);
	MLX5_SET(create_flow_group_in, grp_in,
		 start_flow_index, table_size - 2);
	MLX5_SET(create_flow_group_in, grp_in,
		 end_flow_index, table_size - 1);
	memset(dmac, 0, ETH_ALEN);

	promisc_grp = mlx5_create_flow_group(fdb, grp_in);
	if (IS_ERR_OR_NULL(promisc_grp)) {
		esw_warn(dev, "Failed to create FDB promisc group err(%ld)\n",
			 PTR_ERR(promisc_grp));
		err = PTR_ERR(promisc_grp);
		goto err_mc_promisc_grp;
	}
	kfree(grp_in);

	esw->fdb_table.fdb = fdb;
	esw->fdb_table.addr_grp = addr_grp;
	esw->fdb_table.mc_promisc_grp = mc_promisc_grp;
	esw->fdb_table.promisc_grp = promisc_grp;

	return 0;

err_mc_promisc_grp:
	mlx5_destroy_flow_group(mc_promisc_grp);
err_addr_grp:
	mlx5_destroy_flow_group(addr_grp);
err_fdb:
	mlx5_destroy_flow_table(fdb);
	kfree(grp_in);
	return err;
}