예제 #1
0
static int mlx5_esw_del_uc_addr(struct mlx5_core_dev *dev,
				struct mlx5_vport_addr *vaddr)
{
	struct hlist_head *hash = dev->priv.eswitch.l2_table.l2_hash;
	struct mlx5_esw_uc_addr *esw_uc_addr;
	u8 *mac = vaddr->node.addr;
	u32 vport = vaddr->vport;

	esw_uc_addr = mlx5_addr_hash_find(hash, mac, struct mlx5_esw_uc_addr);
	if (!esw_uc_addr || esw_uc_addr->vport != vport) {
		esw_debug(dev,
			  "MAC(%pM) doesn't belong to vport (%d)\n",
			  mac, vport);
		return -EINVAL;
	}

	mlx5_del_l2_table_entry(dev, esw_uc_addr->table_index);

	esw_debug(dev,
		  "UC- Deleted mac(%pM) vport(%d) l2_index(%d) flow_rule(%p)\n",
		  mac, vport, esw_uc_addr->table_index, vaddr->flow_rule);

	if (vaddr->flow_rule)
		mlx5_del_flow_rule(vaddr->flow_rule);
	vaddr->flow_rule = NULL;

	mlx5_addr_hash_del(&esw_uc_addr->node);
	return 0;
}
예제 #2
0
static void mlx5_eswfdb_cleanup_promisc_rules(struct mlx5_core_dev *dev)
{
	struct mlx5_eswitch *esw = &dev->priv.eswitch;
	struct mlx5_esw_mc_addr *promisc = esw->promisc;
	struct mlx5_esw_mc_addr *mc_promisc = esw->mc_promisc;

	if (promisc && promisc->uplink_rule)
		mlx5_del_flow_rule(promisc->uplink_rule);

	if (mc_promisc && mc_promisc->uplink_rule)
		mlx5_del_flow_rule(mc_promisc->uplink_rule);

	kfree(promisc);
	kfree(mc_promisc);

	esw->promisc = NULL;
	esw->mc_promisc = NULL;
}
예제 #3
0
파일: en_rep.c 프로젝트: acton393/linux
static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
{
	struct mlx5_eswitch_rep *rep = priv->ppriv;
	int i;

	mlx5e_tc_cleanup(priv);
	mlx5_del_flow_rule(rep->vport_rx_rule);
	mlx5e_destroy_direct_tirs(priv);
	for (i = 0; i < priv->params.num_channels; i++)
		mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
}
예제 #4
0
static int mlx5_esw_del_mc_addr(struct mlx5_core_dev *dev,
				struct mlx5_vport_addr *vaddr)
{
	struct mlx5_eswitch *esw = &dev->priv.eswitch;
	struct hlist_head *hash = esw->mc_table;
	struct mlx5_esw_mc_addr *esw_mc_addr;
	u8 *mac = vaddr->node.addr;
	u32 vport = vaddr->vport;

	if (!esw->fdb_table.fdb)
		return 0;

	esw_mc_addr = mlx5_addr_hash_find(hash, mac, struct mlx5_esw_mc_addr);
	if (!esw_mc_addr) {
		esw_warn(dev,
			 "Failed to find eswitch MC addr for MAC(%pM) vport(%d)",
			 mac, vport);
		return -EINVAL;
	}

	esw_debug(dev,
		  "MC- Deleting MC mac(%pM) -> vport(%d) flow_rule(%p) refcnt(%d)\n",
		  mac, vport, vaddr->flow_rule,  esw_mc_addr->refcnt);
	if (vaddr->flow_rule)
		mlx5_del_flow_rule(vaddr->flow_rule);
	vaddr->flow_rule = NULL;

	if (--esw_mc_addr->refcnt)
		return 0;

	esw_debug(dev,
		  "MC- Deleting MC mac(%pM) -> vport(%d) flow_rule(%p) refcnt(%d)\n",
		  mac, UPLINK_VPORT, esw_mc_addr->uplink_rule,
		  esw_mc_addr->refcnt);
	if (esw_mc_addr->uplink_rule)
		mlx5_del_flow_rule(esw_mc_addr->uplink_rule);

	mlx5_addr_hash_del(&esw_mc_addr->node);
	return 0;
}
예제 #5
0
파일: en_rep.c 프로젝트: acton393/linux
static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
{
	struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
	struct mlx5_eswitch_rep *rep = priv->ppriv;
	struct mlx5_core_dev *mdev = priv->mdev;
	struct mlx5_flow_rule *flow_rule;
	int err;
	int i;

	err = mlx5e_create_direct_rqts(priv);
	if (err) {
		mlx5_core_warn(mdev, "create direct rqts failed, %d\n", err);
		return err;
	}

	err = mlx5e_create_direct_tirs(priv);
	if (err) {
		mlx5_core_warn(mdev, "create direct tirs failed, %d\n", err);
		goto err_destroy_direct_rqts;
	}

	flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
						      rep->vport,
						      priv->direct_tir[0].tirn);
	if (IS_ERR(flow_rule)) {
		err = PTR_ERR(flow_rule);
		goto err_destroy_direct_tirs;
	}
	rep->vport_rx_rule = flow_rule;

	err = mlx5e_tc_init(priv);
	if (err)
		goto err_del_flow_rule;

	return 0;

err_del_flow_rule:
	mlx5_del_flow_rule(rep->vport_rx_rule);
err_destroy_direct_tirs:
	mlx5e_destroy_direct_tirs(priv);
err_destroy_direct_rqts:
	for (i = 0; i < priv->params.num_channels; i++)
		mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
	return err;
}