From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f67.google.com (mail-wm0-f67.google.com [74.125.82.67]) by dpdk.org (Postfix) with ESMTP id 06D8D9A91 for ; Sun, 14 Feb 2016 23:18:08 +0100 (CET) Received: by mail-wm0-f67.google.com with SMTP id c200so12803135wme.0 for ; Sun, 14 Feb 2016 14:18:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=uR8whXdeyPNEEnJ11VUZGOBDmaq3Qx4KO70dBBFcmWw=; b=PUBTFWl+984MWrFSE0vSSXvqB0jUG1/xnwB43Y/gCj6uqDBY+CPGqXYj8Q2/RGi1jA 27uCk/pYO5QD9ytminlddU0gGcpm8otUJ+2+jZN7W8Behnn0W+nBpHRt5fuIL1p4HUeX MBocCB6V2m/736tSLrY9azwoPw1f319giJUzCFYaVFPXWeCUHC73xJK7Eo7v3YofcABU nyQGeIQzd+VqjBh2Se9JINnKtNQMflBsMch1d3kjWBQyTHQQJPmLKpxYSlgXACYt3tRQ lG1WgohvZ3beBQ1uFg9sv96xD/ha49bowsYQ3aFwrt3LDnUrNDoF4Kfj2a98P/xspu+t wxcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=uR8whXdeyPNEEnJ11VUZGOBDmaq3Qx4KO70dBBFcmWw=; b=kZRjiR3LnredWllZ4DHo0kbPsPVAGiheSQZuG6oRptT0n4VvGfE/kb4xRWvbLy7M2h 02o/66+sMYPcw5MTbQUumQ+/eksW0b0/3+EkBFiLscTkuBbokZbdP64j8nqtCWqZueIe xhHj+XPnyhWVTx762FqgCgso1cazkPhV+XYCHmyeYcQnhmLdm26kXZ4cX4HMVh5y5pzA M7wixyc4q2ApFJEEZ9Zys7dKjSNs7bJRP6jLBNLKaws9KwOSn/tTH/cb5JFO2ArsFklC 8ZmzzgV3HSmsfPhRj84SAZEOgB8eWJOaRlLa0DQG0NBuEOixmWmvMP+Q78rjwJxpke2U t2Zw== X-Gm-Message-State: AG10YOTjTsiSzUWbHNESNn9/4jIlNJiDreaG36xllx9cPvDOZNIrWHC8e/8qfXNy3eP52w== X-Received: by 10.194.109.232 with SMTP id hv8mr12461010wjb.161.1455488287902; Sun, 14 Feb 2016 14:18:07 -0800 (PST) Received: from localhost.localdomain (215.Red-79-147-159.dynamicIP.rima-tde.net. [79.147.159.215]) by smtp.gmail.com with ESMTPSA id 198sm12771024wml.22.2016.02.14.14.18.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 14 Feb 2016 14:18:07 -0800 (PST) From: Marc Sune To: dev@dpdk.org, Wenzhuo Lu , Helin Zhang , Harish Patil , Jing Chen Date: Sun, 14 Feb 2016 23:17:38 +0100 Message-Id: <1455488259-1000-4-git-send-email-marcdevel@gmail.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1455488259-1000-1-git-send-email-marcdevel@gmail.com> References: <1454028127-10401-1-git-send-email-marcdevel@gmail.com> <1455488259-1000-1-git-send-email-marcdevel@gmail.com> Subject: [dpdk-dev] [PATCH v8 3/4] ethdev: redesign link speed config API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 14 Feb 2016 22:18:08 -0000 This patch redesigns the API to set the link speed/s configure for an ethernet port. Specifically: - it allows to define a set of advertised speeds for auto-negociation. - it allows to disable link auto-negociation (single fixed speed). - default: auto-negociate all supported speeds. Other changes: * Added utility MACROs ETH_SPEED_NUM_XXX with the numeric values of all supported link speeds, in Mbps. * Converted link_speed to uint64_t to accomodate 100G speeds and beyond (bug). * Added autoneg flag in struct rte_eth_link to indicate if link speed was a result of auto-negociation or was fixed by configuration. * Added utility function to convert numeric speeds to bitmap fields. * Added rte_eth_speed_to_bm_flag() to version map. Signed-off-by: Marc Sune --- app/test-pipeline/init.c | 2 +- app/test-pmd/cmdline.c | 124 +++++++++++++++--------------- app/test-pmd/config.c | 4 +- app/test/virtual_pmd.c | 4 +- drivers/net/af_packet/rte_eth_af_packet.c | 5 +- drivers/net/bnx2x/bnx2x_ethdev.c | 8 +- drivers/net/bonding/rte_eth_bond_8023ad.c | 14 ++-- drivers/net/cxgbe/base/t4_hw.c | 8 +- drivers/net/cxgbe/cxgbe_ethdev.c | 2 +- drivers/net/e1000/em_ethdev.c | 116 ++++++++++++++-------------- drivers/net/e1000/igb_ethdev.c | 111 +++++++++++++------------- drivers/net/fm10k/fm10k_ethdev.c | 8 +- drivers/net/i40e/i40e_ethdev.c | 73 +++++++++--------- drivers/net/i40e/i40e_ethdev_vf.c | 11 +-- drivers/net/ixgbe/ixgbe_ethdev.c | 78 ++++++++----------- drivers/net/mlx4/mlx4.c | 6 +- drivers/net/mpipe/mpipe_tilegx.c | 6 +- drivers/net/nfp/nfp_net.c | 4 +- drivers/net/null/rte_eth_null.c | 5 +- drivers/net/pcap/rte_eth_pcap.c | 9 ++- drivers/net/ring/rte_eth_ring.c | 5 +- drivers/net/virtio/virtio_ethdev.c | 2 +- drivers/net/virtio/virtio_ethdev.h | 2 - drivers/net/vmxnet3/vmxnet3_ethdev.c | 5 +- drivers/net/xenvirt/rte_eth_xenvirt.c | 5 +- examples/ip_pipeline/config_parse.c | 3 +- lib/librte_ether/rte_ethdev.c | 49 ++++++++++++ lib/librte_ether/rte_ethdev.h | 113 +++++++++++++++++---------- lib/librte_ether/rte_ether_version.map | 6 ++ 29 files changed, 443 insertions(+), 345 deletions(-) diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c index db2196b..08fb041 100644 --- a/app/test-pipeline/init.c +++ b/app/test-pipeline/init.c @@ -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"); diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 52e9f5f..57ad25f 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -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); } diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 0062484..caeb2d9 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -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; } diff --git a/app/test/virtual_pmd.c b/app/test/virtual_pmd.c index a538c8a..3c4040b 100644 --- a/app/test/virtual_pmd.c +++ b/app/test/virtual_pmd.c @@ -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); diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_packet/rte_eth_af_packet.c index 767f36b..5db1db2 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -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 diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c index b547ac3..efefae6 100644 --- a/drivers/net/bnx2x/bnx2x_ethdev.c +++ b/drivers/net/bnx2x/bnx2x_ethdev.c @@ -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 diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c index b3b30f6..3b446e1 100644 --- a/drivers/net/bonding/rte_eth_bond_8023ad.c +++ b/drivers/net/bonding/rte_eth_bond_8023ad.c @@ -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: diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c index 884d2cf..79af806 100644 --- a/drivers/net/cxgbe/base/t4_hw.c +++ b/drivers/net/cxgbe/base/t4_hw.c @@ -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); diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c index 203e119..05b954d 100644 --- a/drivers/net/cxgbe/cxgbe_ethdev.c +++ b/drivers/net/cxgbe/cxgbe_ethdev.c @@ -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) diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c index e40dc37..12c4c63 100644 --- a/drivers/net/e1000/em_ethdev.c +++ b/drivers/net/e1000/em_ethdev.c @@ -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); diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index 7eac8ea..6682df5 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -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); diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c index 2e6ec60..f44818f 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -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 diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 78a0cbd..e440dcf 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -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; diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 13c5b3d..dd8f1e2 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -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); diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 7e29c18..4fa07b6 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -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; diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index c5688a7..01c3a5c 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -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; diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_tilegx.c index 04f3c9f..ecb69b1 100644 --- a/drivers/net/mpipe/mpipe_tilegx.c +++ b/drivers/net/mpipe/mpipe_tilegx.c @@ -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); diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c index 98a957a..adde1a2 100644 --- a/drivers/net/nfp/nfp_net.c +++ b/drivers/net/nfp/nfp_net.c @@ -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 diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c index 77fc988..55e1fc8 100644 --- a/drivers/net/null/rte_eth_null.c +++ b/drivers/net/null/rte_eth_null.c @@ -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 diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_pcap.c index f9230eb..650b521 100644 --- a/drivers/net/pcap/rte_eth_pcap.c +++ b/drivers/net/pcap/rte_eth_pcap.c @@ -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 diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_ring.c index d92b088..043175a 100644 --- a/drivers/net/ring/rte_eth_ring.c +++ b/drivers/net/ring/rte_eth_ring.c @@ -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 diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c index caa970c..12e71af 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -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)) { diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h index fed9571..66423a0 100644 --- a/drivers/net/virtio/virtio_ethdev.h +++ b/drivers/net/virtio/virtio_ethdev.h @@ -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 diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c index c363bf6..2bb6ee9 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c @@ -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); diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c index 3f31806..0fcf5d3 100644 --- a/drivers/net/xenvirt/rte_eth_xenvirt.c +++ b/drivers/net/xenvirt/rte_eth_xenvirt.c @@ -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 diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c index 1bedbe4..c581d41 100644 --- a/examples/ip_pipeline/config_parse.c +++ b/examples/ip_pipeline/config_parse.c @@ -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, diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c index 756b234..7b0214d 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -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) { diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h index 83ddbb7..8661521 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -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 diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map index d8db24d..2c14ad7 100644 --- a/lib/librte_ether/rte_ether_version.map +++ b/lib/librte_ether/rte_ether_version.map @@ -117,3 +117,9 @@ DPDK_2.2 { local: *; }; + +DPDK_2.3 { + global: + + rte_eth_speed_to_bm_flag; +}DPDK_2.2; -- 2.1.4