[dpdk-dev,v2,09/13] mlx5: add link update device operation
Commit Message
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>
---
drivers/net/mlx5/mlx5.c | 1 +
drivers/net/mlx5/mlx5.h | 1 +
drivers/net/mlx5/mlx5_ethdev.c | 71 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
Comments
On Fri, 30 Oct 2015 19:52:38 +0100
Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
> +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;
DPDK style is to use the __rte_unused attribute rather than dummy statements
to avoid unused warnings.
On Mon, Nov 02, 2015 at 09:52:17AM -0800, Stephen Hemminger wrote:
> On Fri, 30 Oct 2015 19:52:38 +0100
> Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
>
> > +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;
>
> DPDK style is to use the __rte_unused attribute rather than dummy statements
> to avoid unused warnings.
Thanks for pointing this out, I'm used to avoiding C extensions whenever
possible but will stick to DPDK style next time.
Still, it would be nice if we could steer DPDK away from such extensions as
much as possible. As a library, we should allow user applications to compile
with flags we can't control (such as -pedantic -std=c99, and various
-Wsomething).
On Mon, 2 Nov 2015 19:27:40 +0100
Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
> Thanks for pointing this out, I'm used to avoiding C extensions whenever
> possible but will stick to DPDK style next time.
>
> Still, it would be nice if we could steer DPDK away from such extensions as
> much as possible. As a library, we should allow user applications to compile
> with flags we can't control (such as -pedantic -std=c99, and various
> -Wsomething)
No. The extensions are very useful, catch errors, and generate more readable code.
For example the extension to check printf formats.
@@ -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
@@ -535,6 +537,75 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
}
/**
+ * 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.
*
* Setting the MTU affects hardware MRU (packets larger than the MTU cannot be