mlx5: support setting link up or down

Add driver functions to set link state up or down.
Burst functions are updated to make sure applications cannot attempt to
send/receive after link is brought down.

Signed-off-by: Or Ami <ora@mellanox.com>
This commit is contained in:
Or Ami 2016-03-17 16:38:54 +01:00 committed by Thomas Monjalon
parent ae19955e7c
commit 62072098b5
4 changed files with 93 additions and 0 deletions

View File

@ -209,6 +209,10 @@ This section should contain new features added in this release. Sample format:
Only available with Mellanox OFED >= 3.2.
* **Added mlx5 link up/down callbacks.**
Implemented callbacks to bring link up and down.
* **Changed szedata2 type of driver from vdev to pdev.**
Previously szedata2 device had to be added by ``--vdev`` option.

View File

@ -148,6 +148,8 @@ static const struct eth_dev_ops mlx5_dev_ops = {
.dev_configure = mlx5_dev_configure,
.dev_start = mlx5_dev_start,
.dev_stop = mlx5_dev_stop,
.dev_set_link_down = mlx5_set_link_down,
.dev_set_link_up = mlx5_set_link_up,
.dev_close = mlx5_dev_close,
.promiscuous_enable = mlx5_promiscuous_enable,
.promiscuous_disable = mlx5_promiscuous_disable,

View File

@ -169,6 +169,8 @@ void mlx5_dev_link_status_handler(void *);
void mlx5_dev_interrupt_handler(struct rte_intr_handle *, void *);
void priv_dev_interrupt_handler_uninstall(struct priv *, struct rte_eth_dev *);
void priv_dev_interrupt_handler_install(struct priv *, struct rte_eth_dev *);
int mlx5_set_link_down(struct rte_eth_dev *dev);
int mlx5_set_link_up(struct rte_eth_dev *dev);
/* mlx5_mac.c */

View File

@ -987,3 +987,88 @@ priv_dev_interrupt_handler_install(struct priv *priv, struct rte_eth_dev *dev)
dev);
}
}
/**
* Change the link state (UP / DOWN).
*
* @param dev
* Pointer to Ethernet device structure.
* @param up
* Nonzero for link up, otherwise link down.
*
* @return
* 0 on success, errno value on failure.
*/
static int
priv_set_link(struct priv *priv, int up)
{
struct rte_eth_dev *dev = priv->dev;
int err;
unsigned int i;
if (up) {
err = priv_set_flags(priv, ~IFF_UP, IFF_UP);
if (err)
return err;
for (i = 0; i < priv->rxqs_n; i++)
if ((*priv->rxqs)[i]->sp)
break;
/* Check if an sp queue exists.
* Note: Some old frames might be received.
*/
if (i == priv->rxqs_n)
dev->rx_pkt_burst = mlx5_rx_burst;
else
dev->rx_pkt_burst = mlx5_rx_burst_sp;
dev->tx_pkt_burst = mlx5_tx_burst;
} else {
err = priv_set_flags(priv, ~IFF_UP, ~IFF_UP);
if (err)
return err;
dev->rx_pkt_burst = removed_rx_burst;
dev->tx_pkt_burst = removed_tx_burst;
}
return 0;
}
/**
* DPDK callback to bring the link DOWN.
*
* @param dev
* Pointer to Ethernet device structure.
*
* @return
* 0 on success, errno value on failure.
*/
int
mlx5_set_link_down(struct rte_eth_dev *dev)
{
struct priv *priv = dev->data->dev_private;
int err;
priv_lock(priv);
err = priv_set_link(priv, 0);
priv_unlock(priv);
return err;
}
/**
* DPDK callback to bring the link UP.
*
* @param dev
* Pointer to Ethernet device structure.
*
* @return
* 0 on success, errno value on failure.
*/
int
mlx5_set_link_up(struct rte_eth_dev *dev)
{
struct priv *priv = dev->data->dev_private;
int err;
priv_lock(priv);
err = priv_set_link(priv, 1);
priv_unlock(priv);
return err;
}