diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c
b/drivers/net/bnx2x/bnx2x_ethdev.c
index af84175..071b44f 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -45,8 +45,8 @@ bnx2x_link_update(struct rte_eth_dev *dev)
  dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
  break;
  }
- dev->data->dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ dev->data->dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  dev->data->dev_link.link_status = sc->link_vars.link_up;
 }

diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 3e26ab0..9fb59a2 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -620,14 +620,14 @@ eth_em_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
  } else {
  num_speeds = 0;
- autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+ autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;

  /* Reset */
  hw->phy.autoneg_advertised = 0;

  if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
  ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
- ETH_LINK_SPEED_1G)) {
+ ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
  num_speeds = -1;
  goto error_invalid_config;
  }
@@ -651,7 +651,7 @@ eth_em_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
  num_speeds++;
  }
- if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
+ if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
  goto error_invalid_config;
  }

@@ -1100,14 +1100,18 @@ eth_em_link_update(struct rte_eth_dev *dev, int
wait_to_complete)
  if (link_check && (link.link_status == ETH_LINK_DOWN)) {
  uint16_t duplex, speed;
  hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
- link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+ link.link_duplex = (duplex == FULL_DUPLEX) ?
+ ETH_LINK_FULL_DUPLEX :
  ETH_LINK_HALF_DUPLEX;
  link.link_speed = speed;
  link.link_status = ETH_LINK_UP;
+ link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  } else if (!link_check && (link.link_status == ETH_LINK_UP)) {
  link.link_speed = 0;
  link.link_duplex = ETH_LINK_HALF_DUPLEX;
  link.link_status = ETH_LINK_DOWN;
+ link.link_autoneg = ETH_LINK_SPEED_FIXED;
  }
  rte_em_dev_atomic_write_link_status(dev, &link);

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index ced864c..e0053fe 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1241,14 +1241,14 @@ eth_igb_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
  } else {
  num_speeds = 0;
- autoneg = (*speeds & ETH_LINK_SPEED_AUTONEG);
+ autoneg = (*speeds & ETH_LINK_SPEED_FIXED) == 0;

  /* Reset */
  hw->phy.autoneg_advertised = 0;

  if (*speeds & ~(ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M |
  ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M |
- ETH_LINK_SPEED_1G)) {
+ ETH_LINK_SPEED_1G | ETH_LINK_SPEED_FIXED)) {
  num_speeds = -1;
  goto error_invalid_config;
  }
@@ -1272,7 +1272,7 @@ eth_igb_start(struct rte_eth_dev *dev)
  hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
  num_speeds++;
  }
- if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
+ if (num_speeds == 0 || (!autoneg && (num_speeds > 1)))
  goto error_invalid_config;
  }

@@ -2063,12 +2063,13 @@ eth_igb_link_update(struct rte_eth_dev *dev, int
wait_to_complete)
  if (link_check) {
  uint16_t duplex, speed;
  hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
- link.link_duplex = duplex ? ETH_LINK_FULL_DUPLEX :
+ link.link_duplex = (duplex == FULL_DUPLEX) ?
+ ETH_LINK_FULL_DUPLEX :
  ETH_LINK_HALF_DUPLEX;
  link.link_speed = speed;
  link.link_status = ETH_LINK_UP;
- link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  } else if (!link_check) {
  link.link_speed = 0;
  link.link_duplex = ETH_LINK_HALF_DUPLEX;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 87bc767..c9ef417 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1422,7 +1422,7 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)

  speed = i40e_parse_link_speeds(conf->link_speeds);
  abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
- if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
+ if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED))
  abilities |= I40E_AQ_PHY_AN_ENABLED;
  else
  abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1442,7 +1442,7 @@ i40e_dev_start(struct rte_eth_dev *dev)

  hw->adapter_stopped = 0;

- if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
+ if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
  PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation
disabled",
      dev->data->port_id);
  return -EINVAL;
@@ -1806,8 +1806,8 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
  break;
  }

- link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);

 out:
  rte_i40e_dev_atomic_write_link_status(dev, &link);
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c
b/drivers/net/ixgbe/ixgbe_ethdev.c
index ff23d7d..6cc2da0 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -2098,9 +2098,12 @@ ixgbe_dev_start(struct rte_eth_dev *dev)

  PMD_INIT_FUNC_TRACE();

- /* IXGBE devices don't support half duplex */
- if (!(dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_AUTONEG)) {
- PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegotiation
disabled",
+ /* IXGBE devices don't support:
+ *    - half duplex (checked afterwards for valid speeds)
+ *    - fixed speed: TODO implement
+ */
+ if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_FIXED) {
+ PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; fix speed not
supported",
      dev->data->port_id);
  return -EINVAL;
  }
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 43ac763..81528c9 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4721,8 +4721,8 @@ mlx4_link_update_unlocked(struct rte_eth_dev *dev,
int wait_to_complete)
  dev_link.link_speed = link_speed;
  dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
  ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
- dev_link.link_autoneg = (dev->data->dev_conf.link_speeds &
- ETH_LINK_SPEED_AUTONEG);
+ dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
  /* Link status changed. */
  dev->data->dev_link = dev_link;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 477939f..36b369e 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -630,6 +630,8 @@ mlx5_link_update_unlocked(struct rte_eth_dev *dev, int
wait_to_complete)
  dev_link.link_speed = link_speed;
  dev_link.link_duplex = ((edata.duplex == DUPLEX_HALF) ?
  ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX);
+ dev_link.link_autoneg = !(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_FIXED);
  if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
  /* Link status changed. */
  dev->data->dev_link = dev_link;
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index ef2502a..fb247a7 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -244,8 +244,8 @@ struct rte_eth_stats {
 /**
  * Device supported speeds bitmap flags
  */
-#define ETH_LINK_SPEED_FIXED    (0 <<  0)  /**< Disable autoneg (fixed
speed) */
-#define ETH_LINK_SPEED_AUTONEG  (1 <<  0)  /**< Autonegotiate (all speeds)
*/
+#define ETH_LINK_SPEED_AUTONEG  (0 <<  0)  /**< Autonegotiate (all speeds)
*/
+#define ETH_LINK_SPEED_FIXED    (1 <<  0)  /**< Disable autoneg (fixed
