@@ -200,7 +200,7 @@ app_ports_check_link(void)
port = (uint8_t) app.ports[i];
memset(&link, 0, sizeof(link));
rte_eth_link_get_nowait(port, &link);
- RTE_LOG(INFO, USER1, "Port %u (%u Gbps) %s\n",
+ RTE_LOG(INFO, USER1, "Port %u (%" PRIu64 " Gbps) %s\n",
port,
link.link_speed / 1000,
link.link_status ? "UP" : "DOWN");
@@ -956,14 +956,65 @@ struct cmd_config_speed_all {
cmdline_fixed_string_t value2;
};
+static int
+parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_speed)
+{
+
+ int duplex;
+
+ if (!strcmp(value2, "half")) {
+ duplex = 0;
+ } else if (!strcmp(value2, "full")) {
+ duplex = 1;
+ } else if (!strcmp(value2, "auto")) {
+ duplex = 1;
+ } else {
+ printf("Unknown parameter\n");
+ return -1;
+ }
+
+ if (!strcmp(value1, "10")) {
+ *link_speed = (duplex) ? ETH_LINK_SPEED_10M :
+ ETH_LINK_SPEED_10M_HD;
+ } else if (!strcmp(value1, "100")) {
+ *link_speed = (duplex) ? ETH_LINK_SPEED_100M :
+ ETH_LINK_SPEED_100M_HD;
+ } else if (!strcmp(value1, "1000")) {
+ if (!duplex)
+ goto invalid_speed_param;
+ *link_speed = ETH_LINK_SPEED_1G;
+ } else if (!strcmp(value1, "10000")) {
+ if (!duplex)
+ goto invalid_speed_param;
+ *link_speed = ETH_LINK_SPEED_10G;
+ } else if (!strcmp(value1, "40000")) {
+ if (!duplex)
+ goto invalid_speed_param;
+ *link_speed = ETH_LINK_SPEED_40G;
+ } else if (!strcmp(value1, "auto")) {
+ if (!duplex)
+ goto invalid_speed_param;
+ *link_speed = ETH_LINK_SPEED_AUTONEG;
+ } else {
+ printf("Unknown parameter\n");
+ return -1;
+ }
+
+ return 0;
+
+invalid_speed_param:
+
+ printf("Invalid speed parameter\n");
+ return -1;
+}
+
static void
cmd_config_speed_all_parsed(void *parsed_result,
__attribute__((unused)) struct cmdline *cl,
__attribute__((unused)) void *data)
{
struct cmd_config_speed_all *res = parsed_result;
- uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
- uint16_t link_duplex = 0;
+ uint32_t link_speed;
portid_t pid;
if (!all_ports_stopped()) {
@@ -971,40 +1022,18 @@ cmd_config_speed_all_parsed(void *parsed_result,
return;
}
- if (!strcmp(res->value1, "10"))
- link_speed = ETH_LINK_SPEED_10;
- else if (!strcmp(res->value1, "100"))
- link_speed = ETH_LINK_SPEED_100;
- else if (!strcmp(res->value1, "1000"))
- link_speed = ETH_LINK_SPEED_1000;
- else if (!strcmp(res->value1, "10000"))
- link_speed = ETH_LINK_SPEED_10G;
- else if (!strcmp(res->value1, "40000"))
- link_speed = ETH_LINK_SPEED_40G;
- else if (!strcmp(res->value1, "auto"))
- link_speed = ETH_LINK_SPEED_AUTONEG;
- else {
- printf("Unknown parameter\n");
+ if (parse_and_check_speed_duplex(res->value1,
+ res->value2,
+ &link_speed) < 0)
return;
- }
-
- if (!strcmp(res->value2, "half"))
- link_duplex = ETH_LINK_HALF_DUPLEX;
- else if (!strcmp(res->value2, "full"))
- link_duplex = ETH_LINK_FULL_DUPLEX;
- else if (!strcmp(res->value2, "auto"))
- link_duplex = ETH_LINK_AUTONEG_DUPLEX;
- else {
- printf("Unknown parameter\n");
- return;
- }
FOREACH_PORT(pid, ports) {
- ports[pid].dev_conf.link_speed = link_speed;
- ports[pid].dev_conf.link_duplex = link_duplex;
+ ports[pid].dev_conf.link_speeds = link_speed;
}
cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
+
+ return;
}
cmdline_parse_token_string_t cmd_config_speed_all_port =
@@ -1059,8 +1088,7 @@ cmd_config_speed_specific_parsed(void *parsed_result,
__attribute__((unused)) void *data)
{
struct cmd_config_speed_specific *res = parsed_result;
- uint16_t link_speed = ETH_LINK_SPEED_AUTONEG;
- uint16_t link_duplex = 0;
+ uint32_t link_speed;
if (!all_ports_stopped()) {
printf("Please stop all ports first\n");
@@ -1070,36 +1098,12 @@ cmd_config_speed_specific_parsed(void *parsed_result,
if (port_id_is_invalid(res->id, ENABLED_WARN))
return;
- if (!strcmp(res->value1, "10"))
- link_speed = ETH_LINK_SPEED_10;
- else if (!strcmp(res->value1, "100"))
- link_speed = ETH_LINK_SPEED_100;
- else if (!strcmp(res->value1, "1000"))
- link_speed = ETH_LINK_SPEED_1000;
- else if (!strcmp(res->value1, "10000"))
- link_speed = ETH_LINK_SPEED_10000;
- else if (!strcmp(res->value1, "40000"))
- link_speed = ETH_LINK_SPEED_40G;
- else if (!strcmp(res->value1, "auto"))
- link_speed = ETH_LINK_SPEED_AUTONEG;
- else {
- printf("Unknown parameter\n");
+ if (parse_and_check_speed_duplex(res->value1,
+ res->value2,
+ &link_speed) < 0)
return;
- }
-
- if (!strcmp(res->value2, "half"))
- link_duplex = ETH_LINK_HALF_DUPLEX;
- else if (!strcmp(res->value2, "full"))
- link_duplex = ETH_LINK_FULL_DUPLEX;
- else if (!strcmp(res->value2, "auto"))
- link_duplex = ETH_LINK_AUTONEG_DUPLEX;
- else {
- printf("Unknown parameter\n");
- return;
- }
- ports[res->id].dev_conf.link_speed = link_speed;
- ports[res->id].dev_conf.link_duplex = link_duplex;
+ ports[res->id].dev_conf.link_speeds = link_speed;
cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1);
}
@@ -2241,7 +2241,7 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
return 1;
rte_eth_link_get_nowait(port_id, &link);
if (rate > link.link_speed) {
- printf("Invalid rate value:%u bigger than link speed: %u\n",
+ printf("Invalid rate value:%u bigger than link speed: %" PRIu64 "\n",
rate, link.link_speed);
return 1;
}
@@ -2266,7 +2266,7 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
return 1;
rte_eth_link_get_nowait(port_id, &link);
if (rate > link.link_speed) {
- printf("Invalid rate value:%u bigger than link speed: %u\n",
+ printf("Invalid rate value:%u bigger than link speed: %" PRIu64 "\n",
rate, link.link_speed);
return 1;
}
@@ -603,8 +603,8 @@ virtual_ethdev_create(const char *name, struct ether_addr *mac_addr,
TAILQ_INIT(&(eth_dev->link_intr_cbs));
- eth_dev->data->dev_link.link_status = 0;
- eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10000;
+ eth_dev->data->dev_link.link_status = ETH_LINK_DOWN;
+ eth_dev->data->dev_link.link_speed = ETH_SPEED_NUM_10G;
eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
eth_dev->data->mac_addrs = rte_zmalloc(name, ETHER_ADDR_LEN, 0);
@@ -116,9 +116,10 @@ static const char *valid_arguments[] = {
static const char *drivername = "AF_PACKET PMD";
static struct rte_eth_link pmd_link = {
- .link_speed = 10000,
+ .link_speed = ETH_SPEED_NUM_10G,
.link_duplex = ETH_LINK_FULL_DUPLEX,
- .link_status = 0
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_SPEED_NEG
};
static uint16_t
@@ -45,8 +45,12 @@ bnx2x_link_update(struct rte_eth_dev *dev)
dev->data->dev_link.link_duplex = ETH_LINK_HALF_DUPLEX;
break;
default:
- dev->data->dev_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
+ break;
}
+
+ dev->data->dev_link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_NO_AUTONEG);
+
dev->data->dev_link.link_status = sc->link_vars.link_up;
}
@@ -347,7 +351,7 @@ bnx2x_dev_infos_get(struct rte_eth_dev *dev, __rte_unused struct rte_eth_dev_inf
dev_info->min_rx_bufsize = BNX2X_MIN_RX_BUF_SIZE;
dev_info->max_rx_pktlen = BNX2X_MAX_RX_PKT_LEN;
dev_info->max_mac_addrs = BNX2X_MAX_MAC_ADDRS;
- dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_20G;
+ dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G;
}
static void
@@ -708,25 +708,25 @@ link_speed_key(uint16_t speed) {
uint16_t key_speed;
switch (speed) {
- case ETH_LINK_SPEED_AUTONEG:
+ case ETH_SPEED_NUM_NONE:
key_speed = 0x00;
break;
- case ETH_LINK_SPEED_10:
+ case ETH_SPEED_NUM_10M:
key_speed = BOND_LINK_SPEED_KEY_10M;
break;
- case ETH_LINK_SPEED_100:
+ case ETH_SPEED_NUM_100M:
key_speed = BOND_LINK_SPEED_KEY_100M;
break;
- case ETH_LINK_SPEED_1000:
+ case ETH_SPEED_NUM_1G:
key_speed = BOND_LINK_SPEED_KEY_1000M;
break;
- case ETH_LINK_SPEED_10G:
+ case ETH_SPEED_NUM_10G:
key_speed = BOND_LINK_SPEED_KEY_10G;
break;
- case ETH_LINK_SPEED_20G:
+ case ETH_SPEED_NUM_20G:
key_speed = BOND_LINK_SPEED_KEY_20G;
break;
- case ETH_LINK_SPEED_40G:
+ case ETH_SPEED_NUM_40G:
key_speed = BOND_LINK_SPEED_KEY_40G;
break;
default:
@@ -2159,13 +2159,13 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
if (stat & F_FW_PORT_CMD_TXPAUSE)
fc |= PAUSE_TX;
if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M))
- speed = ETH_LINK_SPEED_100;
+ speed = ETH_SPEED_NUM_100M;
else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G))
- speed = ETH_LINK_SPEED_1000;
+ speed = ETH_SPEED_NUM_1G;
else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G))
- speed = ETH_LINK_SPEED_10000;
+ speed = ETH_SPEED_NUM_10G;
else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G))
- speed = ETH_LINK_SPEED_40G;
+ speed = ETH_SPEED_NUM_40G;
for_each_port(adap, i) {
pi = adap2pinfo(adap, i);
@@ -171,7 +171,7 @@ static void cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
device_info->rx_desc_lim = cxgbe_desc_lim;
device_info->tx_desc_lim = cxgbe_desc_lim;
- device_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+ device_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
}
static void cxgbe_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
@@ -509,6 +509,9 @@ eth_em_start(struct rte_eth_dev *dev)
struct rte_intr_handle *intr_handle = &dev->pci_dev->intr_handle;
int ret, mask;
uint32_t intr_vector = 0;
+ uint32_t *speeds;
+ int num_speeds;
+ bool autoneg;
PMD_INIT_FUNC_TRACE();
@@ -583,56 +586,46 @@ eth_em_start(struct rte_eth_dev *dev)
E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX);
/* Setup link speed and duplex */
- switch (dev->data->dev_conf.link_speed) {
- case ETH_LINK_SPEED_AUTONEG:
- if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
- else if (dev->data->dev_conf.link_duplex ==
- ETH_LINK_HALF_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
- else if (dev->data->dev_conf.link_duplex ==
- ETH_LINK_FULL_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
- else
- goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_10:
- if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
- else if (dev->data->dev_conf.link_duplex ==
- ETH_LINK_HALF_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
- else if (dev->data->dev_conf.link_duplex ==
- ETH_LINK_FULL_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
- else
- goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_100:
- if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
- else if (dev->data->dev_conf.link_duplex ==
- ETH_LINK_HALF_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
- else if (dev->data->dev_conf.link_duplex ==
- ETH_LINK_FULL_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
- else
+ speeds = &dev->data->dev_conf.link_speeds;
+ if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+ hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+ } else {
+ num_speeds = 0;
+ autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+ /* 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)) {
+ num_speeds = -1;
goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_1000:
- if ((dev->data->dev_conf.link_duplex ==
- ETH_LINK_AUTONEG_DUPLEX) ||
- (dev->data->dev_conf.link_duplex ==
- ETH_LINK_FULL_DUPLEX))
- hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
- else
+ }
+ if (*speeds & ETH_LINK_SPEED_10M_HD) {
+ hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_10M) {
+ hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_100M_HD) {
+ hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_100M) {
+ hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_1G) {
+ hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+ num_speeds++;
+ }
+ if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_10000:
- default:
- goto error_invalid_config;
}
+
e1000_setup_link(hw);
if (rte_intr_allow_others(intr_handle)) {
@@ -665,9 +658,8 @@ eth_em_start(struct rte_eth_dev *dev)
return 0;
error_invalid_config:
- PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
- dev->data->dev_conf.link_speed,
- dev->data->dev_conf.link_duplex, dev->data->port_id);
+ PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+ dev->data->dev_conf.link_speeds, dev->data->port_id);
em_dev_clear_queues(dev);
return -EINVAL;
}
@@ -1024,11 +1016,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
.nb_align = EM_TXD_ALIGN,
};
- dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
- ETH_SPEED_CAP_10M_FD |
- ETH_SPEED_CAP_100M_HD |
- ETH_SPEED_CAP_100M_FD |
- ETH_SPEED_CAP_1G;
+ dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+ ETH_LINK_SPEED_10M |
+ ETH_LINK_SPEED_100M_HD |
+ ETH_LINK_SPEED_100M |
+ ETH_LINK_SPEED_1G;
}
/* return 0 means link status changed, -1 means not changed */
@@ -1077,13 +1069,17 @@ eth_em_link_update(struct rte_eth_dev *dev, int wait_to_complete)
/* Now we check if a transition has happened */
if (link_check && (link.link_status == 0)) {
- hw->mac.ops.get_link_up_info(hw, &link.link_speed,
- &link.link_duplex);
- link.link_status = 1;
+ uint16_t duplex, speed;
+ hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+
+ link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX :
+ ETH_LINK_HALF_DUPLEX;
+ link.link_speed = speed;
+ link.link_status = ETH_LINK_UP;
} else if (!link_check && (link.link_status == 1)) {
link.link_speed = 0;
- link.link_duplex = 0;
- link.link_status = 0;
+ link.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link.link_status = ETH_LINK_DOWN;
}
rte_em_dev_atomic_write_link_status(dev, &link);
@@ -1119,6 +1119,9 @@ eth_igb_start(struct rte_eth_dev *dev)
int ret, mask;
uint32_t intr_vector = 0;
uint32_t ctrl_ext;
+ uint32_t *speeds;
+ int num_speeds;
+ bool autoneg;
PMD_INIT_FUNC_TRACE();
@@ -1219,48 +1222,46 @@ eth_igb_start(struct rte_eth_dev *dev)
}
/* Setup link speed and duplex */
- switch (dev->data->dev_conf.link_speed) {
- case ETH_LINK_SPEED_AUTONEG:
- if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
- else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_HALF_DUPLEX;
- else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_FULL_DUPLEX;
- else
- goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_10:
- if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_10_SPEED;
- else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_10_HALF;
- else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_10_FULL;
- else
- goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_100:
- if (dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX)
- hw->phy.autoneg_advertised = E1000_ALL_100_SPEED;
- else if (dev->data->dev_conf.link_duplex == ETH_LINK_HALF_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_100_HALF;
- else if (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX)
- hw->phy.autoneg_advertised = ADVERTISE_100_FULL;
- else
+ speeds = &dev->data->dev_conf.link_speeds;
+ if (*speeds == ETH_LINK_SPEED_AUTONEG) {
+ hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
+ } else {
+ num_speeds = 0;
+ autoneg = ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG);
+
+ /* 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)) {
+ num_speeds = -1;
goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_1000:
- if ((dev->data->dev_conf.link_duplex == ETH_LINK_AUTONEG_DUPLEX) ||
- (dev->data->dev_conf.link_duplex == ETH_LINK_FULL_DUPLEX))
- hw->phy.autoneg_advertised = ADVERTISE_1000_FULL;
- else
+ }
+ if (*speeds & ETH_LINK_SPEED_10M_HD) {
+ hw->phy.autoneg_advertised |= ADVERTISE_10_HALF;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_10M) {
+ hw->phy.autoneg_advertised |= ADVERTISE_10_FULL;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_100M_HD) {
+ hw->phy.autoneg_advertised |= ADVERTISE_100_HALF;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_100M) {
+ hw->phy.autoneg_advertised |= ADVERTISE_100_FULL;
+ num_speeds++;
+ }
+ if (*speeds & ETH_LINK_SPEED_1G) {
+ hw->phy.autoneg_advertised |= ADVERTISE_1000_FULL;
+ num_speeds++;
+ }
+ if (num_speeds == 0 || (!autoneg && (num_speeds > 2)))
goto error_invalid_config;
- break;
- case ETH_LINK_SPEED_10000:
- default:
- goto error_invalid_config;
}
+
e1000_setup_link(hw);
if (rte_intr_allow_others(intr_handle)) {
@@ -1292,9 +1293,8 @@ eth_igb_start(struct rte_eth_dev *dev)
return 0;
error_invalid_config:
- PMD_INIT_LOG(ERR, "Invalid link_speed/link_duplex (%u/%u) for port %u",
- dev->data->dev_conf.link_speed,
- dev->data->dev_conf.link_duplex, dev->data->port_id);
+ PMD_INIT_LOG(ERR, "Invalid advertised speeds (%u) for port %u",
+ dev->data->dev_conf.link_speeds, dev->data->port_id);
igb_dev_clear_queues(dev);
return -EINVAL;
}
@@ -1909,11 +1909,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->rx_desc_lim = rx_desc_lim;
dev_info->tx_desc_lim = tx_desc_lim;
- dev_info->speed_capa = ETH_SPEED_CAP_10M_HD |
- ETH_SPEED_CAP_10M_FD |
- ETH_SPEED_CAP_100M_HD |
- ETH_SPEED_CAP_100M_FD |
- ETH_SPEED_CAP_1G;
+ dev_info->speed_capa = ETH_LINK_SPEED_10M_HD |
+ ETH_LINK_SPEED_10M |
+ ETH_LINK_SPEED_100M_HD |
+ ETH_LINK_SPEED_100M |
+ ETH_LINK_SPEED_1G;
}
static void
@@ -2023,13 +2023,20 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
/* Now we check if a transition has happened */
if (link_check) {
- hw->mac.ops.get_link_up_info(hw, &link.link_speed,
- &link.link_duplex);
- link.link_status = 1;
+ uint16_t duplex, speed;
+ hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
+
+ link.link_duplex = (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_NO_AUTONEG);
} else if (!link_check) {
link.link_speed = 0;
- link.link_duplex = 0;
- link.link_status = 0;
+ link.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link.link_status = ETH_LINK_DOWN;
+ link.link_autoneg = ETH_LINK_SPEED_FIXED;
}
rte_igb_dev_atomic_write_link_status(dev, &link);
@@ -1172,7 +1172,7 @@ fm10k_link_update(struct rte_eth_dev *dev,
* is no 50Gbps Ethernet. */
dev->data->dev_link.link_speed = 0;
dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
- dev->data->dev_link.link_status = 1;
+ dev->data->dev_link.link_status = ETH_LINK_UP;
return 0;
}
@@ -1334,9 +1334,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
.nb_align = FM10K_MULT_TX_DESC,
};
- dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_2_5G |
- ETH_SPEED_CAP_10G | ETH_SPEED_CAP_25G |
- ETH_SPEED_CAP_40G | ETH_SPEED_CAP_100G;
+ dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G |
+ ETH_LINK_SPEED_10G | ETH_LINK_SPEED_25G |
+ ETH_LINK_SPEED_40G | ETH_LINK_SPEED_100G;
}
static int
@@ -1326,27 +1326,20 @@ i40e_vsi_disable_queues_intr(struct i40e_vsi *vsi)
}
static inline uint8_t
-i40e_parse_link_speed(uint16_t eth_link_speed)
+i40e_parse_link_speeds(uint16_t link_speeds)
{
uint8_t link_speed = I40E_LINK_SPEED_UNKNOWN;
- switch (eth_link_speed) {
- case ETH_LINK_SPEED_40G:
- link_speed = I40E_LINK_SPEED_40GB;
- break;
- case ETH_LINK_SPEED_20G:
- link_speed = I40E_LINK_SPEED_20GB;
- break;
- case ETH_LINK_SPEED_10G:
- link_speed = I40E_LINK_SPEED_10GB;
- break;
- case ETH_LINK_SPEED_1000:
- link_speed = I40E_LINK_SPEED_1GB;
- break;
- case ETH_LINK_SPEED_100:
- link_speed = I40E_LINK_SPEED_100MB;
- break;
- }
+ if (link_speeds & ETH_LINK_SPEED_40G)
+ link_speed |= I40E_LINK_SPEED_40GB;
+ if (link_speeds & ETH_LINK_SPEED_20G)
+ link_speed |= I40E_LINK_SPEED_20GB;
+ if (link_speeds & ETH_LINK_SPEED_10G)
+ link_speed |= I40E_LINK_SPEED_10GB;
+ if (link_speeds & ETH_LINK_SPEED_1G)
+ link_speed |= I40E_LINK_SPEED_1GB;
+ if (link_speeds & ETH_LINK_SPEED_100M)
+ link_speed |= I40E_LINK_SPEED_100MB;
return link_speed;
}
@@ -1372,9 +1365,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev)
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct rte_eth_conf *conf = &dev->data->dev_conf;
- speed = i40e_parse_link_speed(conf->link_speed);
+ speed = i40e_parse_link_speeds(conf->link_speeds);
abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
- if (conf->link_speed == ETH_LINK_SPEED_AUTONEG)
+ if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG)
abilities |= I40E_AQ_PHY_AN_ENABLED;
else
abilities |= I40E_AQ_PHY_LINK_ENABLED;
@@ -1394,10 +1387,8 @@ i40e_dev_start(struct rte_eth_dev *dev)
hw->adapter_stopped = 0;
- if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
- (dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
- PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
- dev->data->dev_conf.link_duplex,
+ if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+ PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
dev->data->port_id);
return -EINVAL;
}
@@ -1470,6 +1461,13 @@ i40e_dev_start(struct rte_eth_dev *dev)
}
/* Apply link configure */
+ if (dev->data->dev_conf.link_speeds & ~(ETH_LINK_SPEED_100M |
+ ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G |
+ ETH_LINK_SPEED_20G | ETH_LINK_SPEED_40G)) {
+ PMD_DRV_LOG(ERR, "Invalid link setting");
+ goto err_up;
+ }
+
ret = i40e_apply_link_speed(dev);
if (I40E_SUCCESS != ret) {
PMD_DRV_LOG(ERR, "Fail to apply link setting");
@@ -1713,7 +1711,7 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
/* Get link status information from hardware */
status = i40e_aq_get_link_info(hw, false, &link_status, NULL);
if (status != I40E_SUCCESS) {
- link.link_speed = ETH_LINK_SPEED_100;
+ link.link_speed = ETH_SPEED_NUM_100M;
link.link_duplex = ETH_LINK_FULL_DUPLEX;
PMD_DRV_LOG(ERR, "Failed to get link info");
goto out;
@@ -1735,25 +1733,28 @@ i40e_dev_link_update(struct rte_eth_dev *dev,
/* Parse the link status */
switch (link_status.link_speed) {
case I40E_LINK_SPEED_100MB:
- link.link_speed = ETH_LINK_SPEED_100;
+ link.link_speed = ETH_SPEED_NUM_100M;
break;
case I40E_LINK_SPEED_1GB:
- link.link_speed = ETH_LINK_SPEED_1000;
+ link.link_speed = ETH_SPEED_NUM_1G;
break;
case I40E_LINK_SPEED_10GB:
- link.link_speed = ETH_LINK_SPEED_10G;
+ link.link_speed = ETH_SPEED_NUM_10G;
break;
case I40E_LINK_SPEED_20GB:
- link.link_speed = ETH_LINK_SPEED_20G;
+ link.link_speed = ETH_SPEED_NUM_20G;
break;
case I40E_LINK_SPEED_40GB:
- link.link_speed = ETH_LINK_SPEED_40G;
+ link.link_speed = ETH_SPEED_NUM_40G;
break;
default:
- link.link_speed = ETH_LINK_SPEED_100;
+ link.link_speed = ETH_SPEED_NUM_100M;
break;
}
+ link.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_NO_AUTONEG);
+
out:
rte_i40e_dev_atomic_write_link_status(dev, &link);
if (link.link_status == old.link_status)
@@ -2308,10 +2309,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
if (i40e_is_40G_device(hw->device_id))
/* For XL710 */
- dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+ dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
else
/* For X710 */
- dev_info->speed_capa = ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G;
+ dev_info->speed_capa = ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G;
}
@@ -7835,15 +7836,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev)
rte_i40e_dev_atomic_read_link_status(dev, &link);
switch (link.link_speed) {
- case ETH_LINK_SPEED_40G:
+ case ETH_SPEED_NUM_40G:
tsync_inc_l = I40E_PTP_40GB_INCVAL & 0xFFFFFFFF;
tsync_inc_h = I40E_PTP_40GB_INCVAL >> 32;
break;
- case ETH_LINK_SPEED_10G:
+ case ETH_SPEED_NUM_10G:
tsync_inc_l = I40E_PTP_10GB_INCVAL & 0xFFFFFFFF;
tsync_inc_h = I40E_PTP_10GB_INCVAL >> 32;
break;
- case ETH_LINK_SPEED_1000:
+ case ETH_SPEED_NUM_1G:
tsync_inc_l = I40E_PTP_1GB_INCVAL & 0xFFFFFFFF;
tsync_inc_h = I40E_PTP_1GB_INCVAL >> 32;
break;
@@ -1911,13 +1911,14 @@ i40evf_dev_link_update(struct rte_eth_dev *dev,
* DPDK pf host provide interfacet to acquire link status
* while Linux driver does not
*/
- if (vf->version_major == I40E_DPDK_VERSION_MAJOR)
+ if (vf->version_major == I40E_DPDK_VERSION_MAJOR) {
i40evf_get_link_status(dev, &new_link);
- else {
+ } else {
/* Always assume it's up, for Linux driver PF host */
- new_link.link_duplex = ETH_LINK_AUTONEG_DUPLEX;
- new_link.link_speed = ETH_LINK_SPEED_10000;
- new_link.link_status = 1;
+ new_link.link_speed = ETH_SPEED_NUM_10G;
+ new_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ new_link.link_autoneg = ETH_LINK_SPEED_NEG;
+ new_link.link_status = ETH_LINK_UP;
}
i40evf_dev_atomic_write_link_status(dev, &new_link);
@@ -1979,14 +1979,13 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
int mask = 0;
int status;
uint16_t vf, idx;
+ uint32_t *link_speeds;
PMD_INIT_FUNC_TRACE();
/* IXGBE devices don't support half duplex */
- if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
- (dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
- PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu",
- dev->data->dev_conf.link_duplex,
+ if (dev->data->dev_conf.link_speeds & ETH_LINK_SPEED_NO_AUTONEG) {
+ PMD_INIT_LOG(ERR, "Invalid link_speeds for port %hhu; autonegociation disabled",
dev->data->port_id);
return -EINVAL;
}
@@ -2076,32 +2075,22 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
if (err)
goto error;
- switch(dev->data->dev_conf.link_speed) {
- case ETH_LINK_SPEED_AUTONEG:
- speed = (hw->mac.type != ixgbe_mac_82598EB) ?
- IXGBE_LINK_SPEED_82599_AUTONEG :
- IXGBE_LINK_SPEED_82598_AUTONEG;
- break;
- case ETH_LINK_SPEED_100:
- /*
- * Invalid for 82598 but error will be detected by
- * ixgbe_setup_link()
- */
- speed = IXGBE_LINK_SPEED_100_FULL;
- break;
- case ETH_LINK_SPEED_1000:
- speed = IXGBE_LINK_SPEED_1GB_FULL;
- break;
- case ETH_LINK_SPEED_10000:
- speed = IXGBE_LINK_SPEED_10GB_FULL;
- break;
- default:
- PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu",
- dev->data->dev_conf.link_speed,
- dev->data->port_id);
+ link_speeds = &dev->data->dev_conf.link_speeds;
+ if (*link_speeds & ~(ETH_LINK_SPEED_100M | ETH_LINK_SPEED_1G |
+ ETH_LINK_SPEED_10G)) {
+ PMD_INIT_LOG(ERR, "Invalid link setting");
goto error;
}
+ speed = 0x0;
+
+ if (*link_speeds & ETH_LINK_SPEED_10G)
+ speed |= IXGBE_LINK_SPEED_10GB_FULL;
+ if (*link_speeds & ETH_LINK_SPEED_1G)
+ speed |= IXGBE_LINK_SPEED_1GB_FULL;
+ if (*link_speeds & ETH_LINK_SPEED_100M)
+ speed |= IXGBE_LINK_SPEED_100_FULL;
+
err = ixgbe_setup_link(hw, speed, link_up);
if (err)
goto error;
@@ -2828,15 +2817,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->reta_size = ixgbe_reta_size_get(hw->mac.type);
dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
- dev_info->speed_capa = ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G;
+ dev_info->speed_capa = ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G;
if (hw->mac.type == ixgbe_mac_X540 ||
hw->mac.type == ixgbe_mac_X540_vf ||
hw->mac.type == ixgbe_mac_X550 ||
- hw->mac.type == ixgbe_mac_X550_vf)
+ hw->mac.type == ixgbe_mac_X550_vf) {
- dev_info->speed_capa |= ETH_SPEED_CAP_100M_FD /*|
- ETH_SPEED_CAP_100M_HD*/;
+ dev_info->speed_capa |= ETH_LINK_SPEED_100M /*|
+ ETH_LINK_SPEED_100M_HD*/;
+ }
}
static void
@@ -2903,9 +2893,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
int link_up;
int diag;
- link.link_status = 0;
+ link.link_status = ETH_LINK_DOWN;
link.link_speed = 0;
- link.link_duplex = 0;
+ link.link_duplex = ETH_LINK_HALF_DUPLEX;
memset(&old, 0, sizeof(old));
rte_ixgbe_dev_atomic_read_link_status(dev, &old);
@@ -2918,8 +2908,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
diag = ixgbe_check_link(hw, &link_speed, &link_up, 1);
if (diag != 0) {
- link.link_speed = ETH_LINK_SPEED_100;
- link.link_duplex = ETH_LINK_HALF_DUPLEX;
+ link.link_speed = ETH_SPEED_NUM_100M;
+ link.link_duplex = ETH_LINK_FULL_DUPLEX;
rte_ixgbe_dev_atomic_write_link_status(dev, &link);
if (link.link_status == old.link_status)
return -1;
@@ -2932,26 +2922,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
return -1;
return 0;
}
- link.link_status = 1;
+ link.link_status = ETH_LINK_UP;
link.link_duplex = ETH_LINK_FULL_DUPLEX;
switch (link_speed) {
default:
case IXGBE_LINK_SPEED_UNKNOWN:
- link.link_duplex = ETH_LINK_HALF_DUPLEX;
- link.link_speed = ETH_LINK_SPEED_100;
+ link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ link.link_speed = ETH_SPEED_NUM_100M;
break;
case IXGBE_LINK_SPEED_100_FULL:
- link.link_speed = ETH_LINK_SPEED_100;
+ link.link_speed = ETH_SPEED_NUM_100M;
break;
case IXGBE_LINK_SPEED_1GB_FULL:
- link.link_speed = ETH_LINK_SPEED_1000;
+ link.link_speed = ETH_SPEED_NUM_1G;
break;
case IXGBE_LINK_SPEED_10GB_FULL:
- link.link_speed = ETH_LINK_SPEED_10000;
+ link.link_speed = ETH_SPEED_NUM_10G;
break;
}
rte_ixgbe_dev_atomic_write_link_status(dev, &link);
@@ -5725,15 +5715,15 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
rte_ixgbe_dev_atomic_read_link_status(dev, &link);
switch (link.link_speed) {
- case ETH_LINK_SPEED_100:
+ case ETH_SPEED_NUM_100M:
incval = IXGBE_INCVAL_100;
shift = IXGBE_INCVAL_SHIFT_100;
break;
- case ETH_LINK_SPEED_1000:
+ case ETH_SPEED_NUM_1G:
incval = IXGBE_INCVAL_1GB;
shift = IXGBE_INCVAL_SHIFT_1GB;
break;
- case ETH_LINK_SPEED_10000:
+ case ETH_SPEED_NUM_10G:
default:
incval = IXGBE_INCVAL_10GB;
shift = IXGBE_INCVAL_SHIFT_10GB;
@@ -4265,8 +4265,8 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
if (priv_get_ifname(priv, &ifname) == 0)
info->if_index = if_nametoindex(ifname);
- info->speed_capa = ETH_SPEED_CAP_10G |ETH_SPEED_CAP_40G |
- ETH_SPEED_CAP_56G;
+ info->speed_capa = ETH_LINK_SPEED_10G |ETH_LINK_SPEED_40G |
+ ETH_LINK_SPEED_56G;
priv_unlock(priv);
}
@@ -4636,6 +4636,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_NO_AUTONEG);
if (memcmp(&dev_link, &dev->data->dev_link, sizeof(dev_link))) {
/* Link status changed. */
dev->data->dev_link = dev_link;
@@ -388,14 +388,16 @@ mpipe_link_update(struct rte_eth_dev *dev, int wait_to_complete)
speed = state & GXIO_MPIPE_LINK_SPEED_MASK;
+ new.link_autoneg = ~(dev->data->dev_conf.link_speeds &
+ ETH_LINK_SPEED_NO_AUTONEG);
if (speed == GXIO_MPIPE_LINK_1G) {
new.link_speed = ETH_LINK_SPEED_1000;
new.link_duplex = ETH_LINK_FULL_DUPLEX;
- new.link_status = 1;
+ new.link_status = ETH_LINK_UP;
} else if (speed == GXIO_MPIPE_LINK_10G) {
new.link_speed = ETH_LINK_SPEED_10000;
new.link_duplex = ETH_LINK_FULL_DUPLEX;
- new.link_status = 1;
+ new.link_status = ETH_LINK_UP;
}
rc = mpipe_link_compare(&old, &new);
@@ -831,7 +831,7 @@ nfp_net_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete)
link.link_duplex = ETH_LINK_FULL_DUPLEX;
/* Other cards can limit the tx and rx rate per VF */
- link.link_speed = ETH_LINK_SPEED_40G;
+ link.link_speed = ETH_SPEED_NUM_40G;
if (old.link_status != link.link_status) {
nfp_net_dev_atomic_write_link_status(dev, &link);
@@ -1072,7 +1072,7 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
dev_info->reta_size = NFP_NET_CFG_RSS_ITBL_SZ;
dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
- dev_info->speed_capa = ETH_SPEED_CAP_50G | ETH_SPEED_CAP_100G;
+ dev_info->speed_capa = ETH_LINK_SPEED_50G | ETH_LINK_SPEED_100G;
}
static uint32_t
@@ -93,9 +93,10 @@ struct pmd_internals {
static struct ether_addr eth_addr = { .addr_bytes = {0} };
static const char *drivername = "Null PMD";
static struct rte_eth_link pmd_link = {
- .link_speed = 10000,
+ .link_speed = ETH_SPEED_NUM_10G,
.link_duplex = ETH_LINK_FULL_DUPLEX,
- .link_status = 0
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_SPEED_NEG,
};
static uint16_t
@@ -125,9 +125,10 @@ static int open_single_iface(const char *iface, pcap_t **pcap);
static struct ether_addr eth_addr = { .addr_bytes = { 0, 0, 0, 0x1, 0x2, 0x3 } };
static const char *drivername = "Pcap PMD";
static struct rte_eth_link pmd_link = {
- .link_speed = 10000,
+ .link_speed = ETH_SPEED_NUM_10G,
.link_duplex = ETH_LINK_FULL_DUPLEX,
- .link_status = 0
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_SPEED_FIXED,
};
static int
@@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev)
status_up:
- dev->data->dev_link.link_status = 1;
+ dev->data->dev_link.link_status = ETH_LINK_UP;
return 0;
}
@@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
}
status_down:
- dev->data->dev_link.link_status = 0;
+ dev->data->dev_link.link_status = ETH_LINK_DOWN;
}
static int
@@ -71,9 +71,10 @@ struct pmd_internals {
static const char *drivername = "Rings PMD";
static struct rte_eth_link pmd_link = {
- .link_speed = 10000,
+ .link_speed = ETH_SPEED_NUM_10G,
.link_duplex = ETH_LINK_FULL_DUPLEX,
- .link_status = 0
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_SPEED_NEG
};
static uint16_t
@@ -1381,7 +1381,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
memset(&link, 0, sizeof(link));
virtio_dev_atomic_read_link_status(dev, &link);
old = link;
- link.link_duplex = FULL_DUPLEX;
+ link.link_duplex = ETH_LINK_FULL_DUPLEX;
link.link_speed = SPEED_10G;
if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) {
@@ -42,8 +42,6 @@
#define SPEED_100 100
#define SPEED_1000 1000
#define SPEED_10G 10000
-#define HALF_DUPLEX 1
-#define FULL_DUPLEX 2
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
@@ -736,9 +736,10 @@ vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wai
ret = VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD);
if (ret & 0x1) {
- link.link_status = 1;
+ link.link_status = ETH_LINK_UP;
link.link_duplex = ETH_LINK_FULL_DUPLEX;
- link.link_speed = ETH_LINK_SPEED_10000;
+ link.link_speed = ETH_SPEED_NUM_10G;
+ link.link_autoneg = ETH_LINK_SPEED_FIXED;
}
vmxnet3_dev_atomic_write_link_status(dev, &link);
@@ -70,9 +70,10 @@ static int virtio_idx = 0;
static const char *drivername = "xen virtio PMD";
static struct rte_eth_link pmd_link = {
- .link_speed = 10000,
+ .link_speed = ETH_SPEED_NUM_10G,
.link_duplex = ETH_LINK_FULL_DUPLEX,
- .link_status = 0
+ .link_status = ETH_LINK_DOWN,
+ .link_autoneg = ETH_LINK_SPEED_FIXED
};
static void
@@ -84,8 +84,7 @@ static const struct app_link_params link_params_default = {
.mac_addr = 0,
.conf = {
- .link_speed = 0,
- .link_duplex = 0,
+ .link_speeds = 0,
.rxmode = {
.mq_mode = ETH_MQ_RX_NONE,
@@ -865,6 +865,55 @@ rte_eth_dev_tx_queue_config(struct rte_eth_dev *dev, uint16_t nb_queues)
}
int
+rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag)
+{
+ switch (speed) {
+ case ETH_SPEED_NUM_10M:
+ *flag = (duplex) ? ETH_LINK_SPEED_10M :
+ ETH_LINK_SPEED_10M_HD;
+ break;
+ case ETH_SPEED_NUM_100M:
+ *flag = (duplex) ? ETH_LINK_SPEED_100M :
+ ETH_LINK_SPEED_100M_HD;
+ break;
+ case ETH_SPEED_NUM_1G:
+ *flag = ETH_LINK_SPEED_1G;
+ break;
+ case ETH_SPEED_NUM_2_5G:
+ *flag = ETH_LINK_SPEED_2_5G;
+ break;
+ case ETH_SPEED_NUM_5G:
+ *flag = ETH_LINK_SPEED_5G;
+ break;
+ case ETH_SPEED_NUM_10G:
+ *flag = ETH_LINK_SPEED_10G;
+ break;
+ case ETH_SPEED_NUM_20G:
+ *flag = ETH_LINK_SPEED_20G;
+ break;
+ case ETH_SPEED_NUM_25G:
+ *flag = ETH_LINK_SPEED_25G;
+ break;
+ case ETH_SPEED_NUM_40G:
+ *flag = ETH_LINK_SPEED_40G;
+ break;
+ case ETH_SPEED_NUM_50G:
+ *flag = ETH_LINK_SPEED_50G;
+ break;
+ case ETH_SPEED_NUM_56G:
+ *flag = ETH_LINK_SPEED_56G;
+ break;
+ case ETH_SPEED_NUM_100G:
+ *flag = ETH_LINK_SPEED_100G;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int
rte_eth_dev_configure(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q,
const struct rte_eth_conf *dev_conf)
{
@@ -242,26 +242,59 @@ struct rte_eth_stats {
};
/**
+ * Device supported speeds bitmap flags
+ */
+#define ETH_LINK_SPEED_AUTONEG (0 << 0) /*< Autonegociate (all speeds) */
+#define ETH_LINK_SPEED_NO_AUTONEG (1 << 0) /*< Disable autoneg (fixed speed) */
+#define ETH_LINK_SPEED_10M_HD (1 << 1) /*< 10 Mbps half-duplex */
+#define ETH_LINK_SPEED_10M (1 << 2) /*< 10 Mbps full-duplex */
+#define ETH_LINK_SPEED_100M_HD (1 << 3) /*< 100 Mbps half-duplex */
+#define ETH_LINK_SPEED_100M (1 << 4) /*< 100 Mbps full-duplex */
+#define ETH_LINK_SPEED_1G (1 << 5) /*< 1 Gbps */
+#define ETH_LINK_SPEED_2_5G (1 << 6) /*< 2.5 Gbps */
+#define ETH_LINK_SPEED_5G (1 << 7) /*< 5 Gbps */
+#define ETH_LINK_SPEED_10G (1 << 8) /*< 10 Mbps */
+#define ETH_LINK_SPEED_20G (1 << 9) /*< 20 Gbps */
+#define ETH_LINK_SPEED_25G (1 << 10) /*< 25 Gbps */
+#define ETH_LINK_SPEED_40G (1 << 11) /*< 40 Gbps */
+#define ETH_LINK_SPEED_50G (1 << 12) /*< 50 Gbps */
+#define ETH_LINK_SPEED_56G (1 << 13) /*< 56 Gbps */
+#define ETH_LINK_SPEED_100G (1 << 14) /*< 100 Gbps */
+
+/**
+ * Ethernet numeric link speeds in Mbps
+ */
+#define ETH_SPEED_NUM_NONE 0 /*< Not defined */
+#define ETH_SPEED_NUM_10M 10 /*< 10 Mbps */
+#define ETH_SPEED_NUM_100M 100 /*< 100 Mbps */
+#define ETH_SPEED_NUM_1G 1000 /*< 1 Gbps */
+#define ETH_SPEED_NUM_2_5G 2500 /*< 2.5 Gbps */
+#define ETH_SPEED_NUM_5G 5000 /*< 5 Gbps */
+#define ETH_SPEED_NUM_10G 10000 /*< 10 Mbps */
+#define ETH_SPEED_NUM_20G 20000 /*< 20 Gbps */
+#define ETH_SPEED_NUM_25G 25000 /*< 25 Gbps */
+#define ETH_SPEED_NUM_40G 40000 /*< 40 Gbps */
+#define ETH_SPEED_NUM_50G 50000 /*< 50 Gbps */
+#define ETH_SPEED_NUM_56G 56000 /*< 56 Gbps */
+#define ETH_SPEED_NUM_100G 100000 /*< 100 Gbps */
+
+/**
* A structure used to retrieve link-level information of an Ethernet port.
*/
struct rte_eth_link {
- uint16_t link_speed; /**< ETH_LINK_SPEED_[10, 100, 1000, 10000] */
- uint16_t link_duplex; /**< ETH_LINK_[HALF_DUPLEX, FULL_DUPLEX] */
- uint8_t link_status : 1; /**< 1 -> link up, 0 -> link down */
-}__attribute__((aligned(8))); /**< aligned for atomic64 read/write */
-
-#define ETH_LINK_SPEED_AUTONEG 0 /**< Auto-negotiate link speed. */
-#define ETH_LINK_SPEED_10 10 /**< 10 megabits/second. */
-#define ETH_LINK_SPEED_100 100 /**< 100 megabits/second. */
-#define ETH_LINK_SPEED_1000 1000 /**< 1 gigabits/second. */
-#define ETH_LINK_SPEED_10000 10000 /**< 10 gigabits/second. */
-#define ETH_LINK_SPEED_10G 10000 /**< alias of 10 gigabits/second. */
-#define ETH_LINK_SPEED_20G 20000 /**< 20 gigabits/second. */
-#define ETH_LINK_SPEED_40G 40000 /**< 40 gigabits/second. */
+ uint64_t link_speed; /**< Link speed (ETH_SPEED_NUM_) */
+ uint16_t link_duplex : 1; /**< 1 -> full duplex, 0 -> half duplex */
+ uint16_t link_autoneg : 1; /**< 1 -> link speed has been autoneg */
+ uint16_t link_status : 1; /**< 1 -> link up, 0 -> link down */
+} __attribute__((aligned(8))); /**< aligned for atomic64 read/write */
-#define ETH_LINK_AUTONEG_DUPLEX 0 /**< Auto-negotiate duplex. */
-#define ETH_LINK_HALF_DUPLEX 1 /**< Half-duplex connection. */
-#define ETH_LINK_FULL_DUPLEX 2 /**< Full-duplex connection. */
+/* Utility constants */
+#define ETH_LINK_HALF_DUPLEX 0 /**< Half-duplex connection. */
+#define ETH_LINK_FULL_DUPLEX 1 /**< Full-duplex connection. */
+#define ETH_LINK_SPEED_FIXED 0 /**< Link speed was not autonegociated. */
+#define ETH_LINK_SPEED_NEG 1 /**< Link speed was autonegociated. */
+#define ETH_LINK_DOWN 0 /**< Link is down. */
+#define ETH_LINK_UP 1 /**< Link is up. */
/**
* A structure used to configure the ring threshold registers of an RX/TX
@@ -760,10 +793,14 @@ struct rte_intr_conf {
* configuration settings may be needed.
*/
struct rte_eth_conf {
- uint16_t link_speed;
- /**< ETH_LINK_SPEED_10[0|00|000], or 0 for autonegotation */
- uint16_t link_duplex;
- /**< ETH_LINK_[HALF_DUPLEX|FULL_DUPLEX], or 0 for autonegotation */
+ uint32_t link_speeds; /**< bitmap of ETH_LINK_SPEED_XXX of speeds to be
+ used. ETH_LINK_SPEED_NO_AUTONEG disables link
+ autonegociation, and a unique speed shall be
+ set. Otherwise, the bitmap defines the set of
+ speeds to be advertised. If the special value
+ ETH_LINK_SPEED_AUTONEG (0) is used, all speeds
+ supported are advertised.
+ */
struct rte_eth_rxmode rxmode; /**< Port RX configuration. */
struct rte_eth_txmode txmode; /**< Port TX configuration. */
uint32_t lpbk_mode; /**< Loopback operation mode. By default the value
@@ -825,26 +862,6 @@ struct rte_eth_conf {
#define DEV_TX_OFFLOAD_QINQ_INSERT 0x00000100
/**
- * Device supported speeds
- */
-#define ETH_SPEED_CAP_NOT_PHY (0) /*< No phy media > */
-#define ETH_SPEED_CAP_10M_HD (1 << 0) /*< 10 Mbps half-duplex> */
-#define ETH_SPEED_CAP_10M_FD (1 << 1) /*< 10 Mbps full-duplex> */
-#define ETH_SPEED_CAP_100M_HD (1 << 2) /*< 100 Mbps half-duplex> */
-#define ETH_SPEED_CAP_100M_FD (1 << 3) /*< 100 Mbps full-duplex> */
-#define ETH_SPEED_CAP_1G (1 << 4) /*< 1 Gbps > */
-#define ETH_SPEED_CAP_2_5G (1 << 5) /*< 2.5 Gbps > */
-#define ETH_SPEED_CAP_5G (1 << 6) /*< 5 Gbps > */
-#define ETH_SPEED_CAP_10G (1 << 7) /*< 10 Mbps > */
-#define ETH_SPEED_CAP_20G (1 << 8) /*< 20 Gbps > */
-#define ETH_SPEED_CAP_25G (1 << 9) /*< 25 Gbps > */
-#define ETH_SPEED_CAP_40G (1 << 10) /*< 40 Gbps > */
-#define ETH_SPEED_CAP_50G (1 << 11) /*< 50 Gbps > */
-#define ETH_SPEED_CAP_56G (1 << 12) /*< 56 Gbps > */
-#define ETH_SPEED_CAP_100G (1 << 13) /*< 100 Gbps > */
-
-
-/**
* Ethernet device information
*/
struct rte_eth_dev_info {
@@ -1811,6 +1828,22 @@ struct eth_driver {
void rte_eth_driver_register(struct eth_driver *eth_drv);
/**
+ * Convert a numerical speed in Mbps to a bitmap flag that can be used in
+ * the bitmap link_speeds of the struct rte_eth_conf
+ *
+ * @param
+ * Numerical speed value in Mbps
+ * @param
+ * Boolean is duplex (only for 10/100 speeds)
+ * @param
+ * On success, the converted speed into a bitmap flag
+ * @return
+ * 0 on success, -EINVAL if the speed cannot be mapped
+ */
+extern int rte_eth_speed_to_bm_flag(uint32_t speed, int duplex,
+ uint32_t *flag);
+
+/**
* Configure an Ethernet device.
* This function must be invoked first before any other function in the
* Ethernet API. This function can also be re-invoked when a device is in the
@@ -117,3 +117,9 @@ DPDK_2.2 {
local: *;
};
+
+DPDK_2.3 {
+ global:
+
+ rte_eth_speed_to_bm_flag;
+}DPDK_2.2;