ca041cd44f
Enabling/disabling of allmulticast mode is not always successful and it should be taken into account to be able to handle it properly. When correct return status is unclear from driver code, -EAGAIN is used. Signed-off-by: Ivan Ilchenko <ivan.ilchenko@oktetlabs.ru> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com> Acked-by: Hyong Youb Kim <hyonkim@cisco.com>
171 lines
3.6 KiB
C
171 lines
3.6 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright 2015 6WIND S.A.
|
|
* Copyright 2015 Mellanox Technologies, Ltd
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
|
|
/* Verbs header. */
|
|
/* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
|
|
#ifdef PEDANTIC
|
|
#pragma GCC diagnostic ignored "-Wpedantic"
|
|
#endif
|
|
#include <infiniband/verbs.h>
|
|
#ifdef PEDANTIC
|
|
#pragma GCC diagnostic error "-Wpedantic"
|
|
#endif
|
|
|
|
#include <rte_ethdev_driver.h>
|
|
|
|
#include "mlx5.h"
|
|
#include "mlx5_rxtx.h"
|
|
#include "mlx5_utils.h"
|
|
|
|
/**
|
|
* DPDK callback to enable promiscuous mode.
|
|
*
|
|
* @param dev
|
|
* Pointer to Ethernet device structure.
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
|
*/
|
|
int
|
|
mlx5_promiscuous_enable(struct rte_eth_dev *dev)
|
|
{
|
|
struct mlx5_priv *priv = dev->data->dev_private;
|
|
int ret;
|
|
|
|
dev->data->promiscuous = 1;
|
|
if (priv->isolated) {
|
|
DRV_LOG(WARNING,
|
|
"port %u cannot enable promiscuous mode"
|
|
" in flow isolation mode",
|
|
dev->data->port_id);
|
|
return 0;
|
|
}
|
|
if (priv->config.vf) {
|
|
ret = mlx5_nl_promisc(dev, 1);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
ret = mlx5_traffic_restart(dev);
|
|
if (ret)
|
|
DRV_LOG(ERR, "port %u cannot enable promiscuous mode: %s",
|
|
dev->data->port_id, strerror(rte_errno));
|
|
|
|
/*
|
|
* rte_eth_dev_promiscuous_enable() rollback
|
|
* dev->data->promiscuous in the case of failure.
|
|
*/
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* DPDK callback to disable promiscuous mode.
|
|
*
|
|
* @param dev
|
|
* Pointer to Ethernet device structure.
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
|
*/
|
|
int
|
|
mlx5_promiscuous_disable(struct rte_eth_dev *dev)
|
|
{
|
|
struct mlx5_priv *priv = dev->data->dev_private;
|
|
int ret;
|
|
|
|
dev->data->promiscuous = 0;
|
|
if (priv->config.vf) {
|
|
ret = mlx5_nl_promisc(dev, 0);
|
|
if (ret)
|
|
return ret;
|
|
}
|
|
ret = mlx5_traffic_restart(dev);
|
|
if (ret)
|
|
DRV_LOG(ERR, "port %u cannot disable promiscuous mode: %s",
|
|
dev->data->port_id, strerror(rte_errno));
|
|
|
|
/*
|
|
* rte_eth_dev_promiscuous_disable() rollback
|
|
* dev->data->promiscuous in the case of failure.
|
|
*/
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* DPDK callback to enable allmulti mode.
|
|
*
|
|
* @param dev
|
|
* Pointer to Ethernet device structure.
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
|
*/
|
|
int
|
|
mlx5_allmulticast_enable(struct rte_eth_dev *dev)
|
|
{
|
|
struct mlx5_priv *priv = dev->data->dev_private;
|
|
int ret;
|
|
|
|
dev->data->all_multicast = 1;
|
|
if (priv->isolated) {
|
|
DRV_LOG(WARNING,
|
|
"port %u cannot enable allmulticast mode"
|
|
" in flow isolation mode",
|
|
dev->data->port_id);
|
|
return 0;
|
|
}
|
|
if (priv->config.vf) {
|
|
ret = mlx5_nl_allmulti(dev, 1);
|
|
if (ret)
|
|
goto error;
|
|
}
|
|
ret = mlx5_traffic_restart(dev);
|
|
if (ret)
|
|
DRV_LOG(ERR, "port %u cannot enable allmulicast mode: %s",
|
|
dev->data->port_id, strerror(rte_errno));
|
|
error:
|
|
/*
|
|
* rte_eth_allmulticast_enable() rollback
|
|
* dev->data->all_multicast in the case of failure.
|
|
*/
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* DPDK callback to disable allmulti mode.
|
|
*
|
|
* @param dev
|
|
* Pointer to Ethernet device structure.
|
|
*
|
|
* @return
|
|
* 0 on success, a negative errno value otherwise and rte_errno is set.
|
|
*/
|
|
int
|
|
mlx5_allmulticast_disable(struct rte_eth_dev *dev)
|
|
{
|
|
struct mlx5_priv *priv = dev->data->dev_private;
|
|
int ret;
|
|
|
|
dev->data->all_multicast = 0;
|
|
if (priv->config.vf) {
|
|
ret = mlx5_nl_allmulti(dev, 0);
|
|
if (ret)
|
|
goto error;
|
|
}
|
|
ret = mlx5_traffic_restart(dev);
|
|
if (ret)
|
|
DRV_LOG(ERR, "port %u cannot disable allmulicast mode: %s",
|
|
dev->data->port_id, strerror(rte_errno));
|
|
error:
|
|
/*
|
|
* rte_eth_allmulticast_disable() rollback
|
|
* dev->data->all_multicast in the case of failure.
|
|
*/
|
|
return ret;
|
|
}
|