mlx5: support link status update
Link information is retrieved using ethtool ioctls. Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com> Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
This commit is contained in:
parent
1bdbe1af99
commit
cb8faed7dd
@ -137,6 +137,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
|
||||
.promiscuous_disable = mlx5_promiscuous_disable,
|
||||
.allmulticast_enable = mlx5_allmulticast_enable,
|
||||
.allmulticast_disable = mlx5_allmulticast_disable,
|
||||
.link_update = mlx5_link_update,
|
||||
.stats_get = mlx5_stats_get,
|
||||
.stats_reset = mlx5_stats_reset,
|
||||
.dev_infos_get = mlx5_dev_infos_get,
|
||||
|
@ -164,6 +164,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
|
||||
int priv_set_flags(struct priv *, unsigned int, unsigned int);
|
||||
int mlx5_dev_configure(struct rte_eth_dev *);
|
||||
void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
|
||||
int mlx5_link_update(struct rte_eth_dev *, int);
|
||||
int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
|
||||
int mlx5_ibv_device_to_pci_addr(const struct ibv_device *,
|
||||
struct rte_pci_addr *);
|
||||
|
@ -45,6 +45,8 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/sockios.h>
|
||||
|
||||
/* DPDK headers don't like -pedantic. */
|
||||
#ifdef PEDANTIC
|
||||
@ -534,6 +536,75 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
|
||||
priv_unlock(priv);
|
||||
}
|
||||
|
||||
/**
|
||||
* DPDK callback to retrieve physical link information (unlocked version).
|
||||
*
|
||||
* @param dev
|
||||
* Pointer to Ethernet device structure.
|
||||
* @param wait_to_complete
|
||||
* Wait for request completion (ignored).
|
||||
*/
|
||||
static int
|
||||
mlx5_link_update_unlocked(struct rte_eth_dev *dev, int wait_to_complete)
|
||||
{
|
||||
struct priv *priv = dev->data->dev_private;
|
||||
struct ethtool_cmd edata = {
|
||||
.cmd = ETHTOOL_GSET
|
||||
};
|
||||
struct ifreq ifr;
|
||||
struct rte_eth_link dev_link;
|
||||
int link_speed = 0;
|
||||
|
||||
(void)wait_to_complete;
|
||||
if (priv_ifreq(priv, SIOCGIFFLAGS, &ifr)) {
|
||||
WARN("ioctl(SIOCGIFFLAGS) failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
memset(&dev_link, 0, sizeof(dev_link));
|
||||
dev_link.link_status = ((ifr.ifr_flags & IFF_UP) &&
|
||||
(ifr.ifr_flags & IFF_RUNNING));
|
||||
ifr.ifr_data = &edata;
|
||||
if (priv_ifreq(priv, SIOCETHTOOL, &ifr)) {
|
||||
WARN("ioctl(SIOCETHTOOL, ETHTOOL_GSET) failed: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
link_speed = ethtool_cmd_speed(&edata);
|
||||
if (link_speed == -1)
|
||||
dev_link.link_speed = 0;
|
||||
else
|
||||
dev_link.link_speed = link_speed;
|
||||
dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
|
||||
ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
|
||||
if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
|
||||
/* Link status changed. */
|
||||
dev->data->dev_link = dev_link;
|
||||
return 0;
|
||||
}
|
||||
/* Link status is still the same. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* DPDK callback to retrieve physical link information.
|
||||
*
|
||||
* @param dev
|
||||
* Pointer to Ethernet device structure.
|
||||
* @param wait_to_complete
|
||||
* Wait for request completion (ignored).
|
||||
*/
|
||||
int
|
||||
mlx5_link_update(struct rte_eth_dev *dev, int wait_to_complete)
|
||||
{
|
||||
struct priv *priv = dev->data->dev_private;
|
||||
int ret;
|
||||
|
||||
priv_lock(priv);
|
||||
ret = mlx5_link_update_unlocked(dev, wait_to_complete);
|
||||
priv_unlock(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* DPDK callback to change the MTU.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user