From patchwork Sun Oct 25 21:59:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Sune X-Patchwork-Id: 7995 Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id C98745699; Sun, 25 Oct 2015 23:00:37 +0100 (CET) Received: from mail-wi0-f177.google.com (mail-wi0-f177.google.com [209.85.212.177]) by dpdk.org (Postfix) with ESMTP id A67A05A76 for ; Sun, 25 Oct 2015 23:00:33 +0100 (CET) Received: by wikq8 with SMTP id q8so140264619wik.1 for ; Sun, 25 Oct 2015 15:00:33 -0700 (PDT) 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=TWZlu+rOl8fnE7289NAfjrZmNXljXVRf+bfrB+Q/9is=; b=mzsHSyT6HICentfMfMz/XC9fVkY7j8bYUDDd3yCypllDNGeguGedGDjhqgsy7u+LFV BkMRy+1u+2xNykvqWbLFkBNGCYueneSGBsl9xY7HQUKzdyRthXgSMvtmgCAsIydSu61R y253ak3ogtrpC1B+Jrk+enLf52zdQBrdfdXLOiXhcIV/NyE4TRTSla6f9yPEDFULzR4r ON7WLu6j4mAtI2//ykvAEBQqthjAXsU6k/vlYXPt3DVkJYfiwylcU0Yp+l9OZhkl0UVj +4K8aaziFg9H1uoUHjT+ApK8+aqkvWCFT38zSnWig1SQJYusU4P8ADwnRDlvwgXtZjXp B+mw== X-Received: by 10.194.176.129 with SMTP id ci1mr16574370wjc.156.1445810433506; Sun, 25 Oct 2015 15:00:33 -0700 (PDT) Received: from localhost.localdomain (189.Red-83-47-134.dynamicIP.rima-tde.net. [83.47.134.189]) by smtp.gmail.com with ESMTPSA id ev1sm8733669wic.21.2015.10.25.15.00.32 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sun, 25 Oct 2015 15:00:32 -0700 (PDT) From: Marc Sune To: dev@dpdk.org Date: Sun, 25 Oct 2015 22:59:58 +0100 Message-Id: <1445810400-8978-4-git-send-email-marcdevel@gmail.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1445810400-8978-1-git-send-email-marcdevel@gmail.com> References: <1443993003-1059-1-git-send-email-marcdevel@gmail.com> <1445810400-8978-1-git-send-email-marcdevel@gmail.com> Subject: [dpdk-dev] [PATCH v6 3/5] 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 uint32_t to accomodate 100G speeds (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. Signed-off-by: Marc Sune --- app/test-pmd/cmdline.c | 124 +++++++++++++++-------------- app/test/virtual_pmd.c | 4 +- drivers/net/af_packet/rte_eth_af_packet.c | 5 +- drivers/net/bonding/rte_eth_bond_8023ad.c | 14 ++-- drivers/net/cxgbe/base/t4_hw.c | 8 +- drivers/net/e1000/base/e1000_80003es2lan.c | 6 +- drivers/net/e1000/base/e1000_82541.c | 8 +- drivers/net/e1000/base/e1000_82543.c | 4 +- drivers/net/e1000/base/e1000_82575.c | 11 +-- drivers/net/e1000/base/e1000_api.c | 2 +- drivers/net/e1000/base/e1000_api.h | 2 +- drivers/net/e1000/base/e1000_defines.h | 4 +- drivers/net/e1000/base/e1000_hw.h | 2 +- drivers/net/e1000/base/e1000_ich8lan.c | 4 +- drivers/net/e1000/base/e1000_mac.c | 9 ++- drivers/net/e1000/base/e1000_mac.h | 6 +- drivers/net/e1000/base/e1000_vf.c | 4 +- drivers/net/e1000/base/e1000_vf.h | 2 +- drivers/net/e1000/em_ethdev.c | 113 +++++++++++++------------- drivers/net/e1000/igb_ethdev.c | 108 +++++++++++++------------ 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 | 72 ++++++++--------- drivers/net/mlx4/mlx4.c | 2 + drivers/net/mpipe/mpipe_tilegx.c | 6 +- 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 ++++++++++++++++---------- 36 files changed, 449 insertions(+), 361 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 0f8f48f..c62f5be 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -897,14 +897,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()) { @@ -912,40 +963,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 = @@ -1000,8 +1029,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"); @@ -1011,36 +1039,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/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 bdd9628..a5d689d 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -115,9 +115,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/bonding/rte_eth_bond_8023ad.c b/drivers/net/bonding/rte_eth_bond_8023ad.c index c0f0b99..f375f95 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/e1000/base/e1000_80003es2lan.c b/drivers/net/e1000/base/e1000_80003es2lan.c index 72692d9..8ca66c4 100644 --- a/drivers/net/e1000/base/e1000_80003es2lan.c +++ b/drivers/net/e1000/base/e1000_80003es2lan.c @@ -52,7 +52,7 @@ STATIC s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, STATIC s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw); STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw); STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed, u16 *duplex); STATIC s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); STATIC s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); @@ -789,7 +789,7 @@ STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) * * Retrieve the current speed and duplex configuration. **/ -STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u32 *speed, u16 *duplex) { s32 ret_val; @@ -1236,7 +1236,7 @@ STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) STATIC s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - u16 speed; + u32 speed; u16 duplex; DEBUGFUNC("e1000_configure_on_link_up"); diff --git a/drivers/net/e1000/base/e1000_82541.c b/drivers/net/e1000/base/e1000_82541.c index 952aea2..707b317 100644 --- a/drivers/net/e1000/base/e1000_82541.c +++ b/drivers/net/e1000/base/e1000_82541.c @@ -47,7 +47,7 @@ STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw); STATIC s32 e1000_init_mac_params_82541(struct e1000_hw *hw); STATIC s32 e1000_reset_hw_82541(struct e1000_hw *hw); STATIC s32 e1000_init_hw_82541(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed, u16 *duplex); STATIC s32 e1000_phy_hw_reset_82541(struct e1000_hw *hw); STATIC s32 e1000_setup_copper_link_82541(struct e1000_hw *hw); @@ -437,7 +437,7 @@ out: * * Retrieve the current speed and duplex configuration. **/ -STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u32 *speed, u16 *duplex) { struct e1000_phy_info *phy = &hw->phy; @@ -667,8 +667,8 @@ STATIC s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, struct e1000_phy_info *phy = &hw->phy; struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; s32 ret_val; - u32 idle_errs = 0; - u16 phy_data, phy_saved_data, speed, duplex, i; + u32 idle_errs = 0, speed; + u16 phy_data, phy_saved_data, duplex, i; u16 ffe_idle_err_timeout = FFE_IDLE_ERR_COUNT_TIMEOUT_20; u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] = { IGP01E1000_PHY_AGC_PARAM_A, diff --git a/drivers/net/e1000/base/e1000_82543.c b/drivers/net/e1000/base/e1000_82543.c index 36335ba..9ef3d80 100644 --- a/drivers/net/e1000/base/e1000_82543.c +++ b/drivers/net/e1000/base/e1000_82543.c @@ -1192,9 +1192,9 @@ out: STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - u32 icr, rctl; + u32 icr, rctl, speed; s32 ret_val; - u16 speed, duplex; + u16 duplex; bool link; DEBUGFUNC("e1000_check_for_copper_link_82543"); diff --git a/drivers/net/e1000/base/e1000_82575.c b/drivers/net/e1000/base/e1000_82575.c index 25fa672..386f058 100644 --- a/drivers/net/e1000/base/e1000_82575.c +++ b/drivers/net/e1000/base/e1000_82575.c @@ -53,7 +53,7 @@ STATIC void e1000_release_nvm_82575(struct e1000_hw *hw); STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw); STATIC s32 e1000_check_for_link_media_swap(struct e1000_hw *hw); STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed, u16 *duplex); STATIC s32 e1000_phy_hw_reset_sgmii_82575(struct e1000_hw *hw); STATIC s32 e1000_read_phy_reg_sgmii_82575(struct e1000_hw *hw, u32 offset, @@ -80,7 +80,7 @@ STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e1000_hw *hw, STATIC void e1000_clear_hw_cntrs_82575(struct e1000_hw *hw); STATIC s32 e1000_acquire_swfw_sync_82575(struct e1000_hw *hw, u16 mask); STATIC s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, - u16 *speed, u16 *duplex); + u32 *speed, u16 *duplex); STATIC s32 e1000_get_phy_id_82575(struct e1000_hw *hw); STATIC void e1000_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask); STATIC bool e1000_sgmii_active_82575(struct e1000_hw *hw); @@ -1165,7 +1165,7 @@ STATIC s32 e1000_get_cfg_done_82575(struct e1000_hw *hw) * interface, use PCS to retrieve the link speed and duplex information. * Otherwise, use the generic function to get the link speed and duplex info. **/ -STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u32 *speed, u16 *duplex) { s32 ret_val; @@ -1192,7 +1192,8 @@ STATIC s32 e1000_get_link_up_info_82575(struct e1000_hw *hw, u16 *speed, STATIC s32 e1000_check_for_link_82575(struct e1000_hw *hw) { s32 ret_val; - u16 speed, duplex; + u32 speed; + u16 duplex; DEBUGFUNC("e1000_check_for_link_82575"); @@ -1316,7 +1317,7 @@ STATIC void e1000_power_up_serdes_link_82575(struct e1000_hw *hw) * duplex, then store the values in the pointers provided. **/ STATIC s32 e1000_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, - u16 *speed, u16 *duplex) + u32 *speed, u16 *duplex) { struct e1000_mac_info *mac = &hw->mac; u32 pcs; diff --git a/drivers/net/e1000/base/e1000_api.c b/drivers/net/e1000/base/e1000_api.c index a064565..08e103a 100644 --- a/drivers/net/e1000/base/e1000_api.c +++ b/drivers/net/e1000/base/e1000_api.c @@ -669,7 +669,7 @@ s32 e1000_setup_link(struct e1000_hw *hw) * variables passed in. This is a function pointer entry point called * by drivers. **/ -s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex) +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex) { if (hw->mac.ops.get_link_up_info) return hw->mac.ops.get_link_up_info(hw, speed, duplex); diff --git a/drivers/net/e1000/base/e1000_api.h b/drivers/net/e1000/base/e1000_api.h index 02b16da..39579e0 100644 --- a/drivers/net/e1000/base/e1000_api.h +++ b/drivers/net/e1000/base/e1000_api.h @@ -65,7 +65,7 @@ s32 e1000_check_for_link(struct e1000_hw *hw); s32 e1000_reset_hw(struct e1000_hw *hw); s32 e1000_init_hw(struct e1000_hw *hw); s32 e1000_setup_link(struct e1000_hw *hw); -s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex); +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *duplex); s32 e1000_disable_pcie_master(struct e1000_hw *hw); void e1000_config_collision_dist(struct e1000_hw *hw); void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index); diff --git a/drivers/net/e1000/base/e1000_defines.h b/drivers/net/e1000/base/e1000_defines.h index 278c507..20c4153 100644 --- a/drivers/net/e1000/base/e1000_defines.h +++ b/drivers/net/e1000/base/e1000_defines.h @@ -347,8 +347,8 @@ POSSIBILITY OF SUCH DAMAGE. #define SPEED_100 100 #define SPEED_1000 1000 #define SPEED_2500 2500 -#define HALF_DUPLEX 1 -#define FULL_DUPLEX 2 +#define HALF_DUPLEX 0 +#define FULL_DUPLEX 1 #define PHY_FORCE_TIME 20 diff --git a/drivers/net/e1000/base/e1000_hw.h b/drivers/net/e1000/base/e1000_hw.h index 4dd92a3..b48a759 100644 --- a/drivers/net/e1000/base/e1000_hw.h +++ b/drivers/net/e1000/base/e1000_hw.h @@ -682,7 +682,7 @@ struct e1000_mac_operations { void (*clear_vfta)(struct e1000_hw *); s32 (*get_bus_info)(struct e1000_hw *); void (*set_lan_id)(struct e1000_hw *); - s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); + s32 (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *); s32 (*led_on)(struct e1000_hw *); s32 (*led_off)(struct e1000_hw *); void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32); diff --git a/drivers/net/e1000/base/e1000_ich8lan.c b/drivers/net/e1000/base/e1000_ich8lan.c index 3b1627b..7fe9955 100644 --- a/drivers/net/e1000/base/e1000_ich8lan.c +++ b/drivers/net/e1000/base/e1000_ich8lan.c @@ -104,7 +104,7 @@ STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); STATIC s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw); STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, - u16 *speed, u16 *duplex); + u32 *speed, u16 *duplex); STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw); STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw); @@ -4561,7 +4561,7 @@ STATIC s32 e1000_setup_copper_link_pch_lpt(struct e1000_hw *hw) * information and then calls the Kumeran lock loss workaround for links at * gigabit speeds. **/ -STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u32 *speed, u16 *duplex) { s32 ret_val; diff --git a/drivers/net/e1000/base/e1000_mac.c b/drivers/net/e1000/base/e1000_mac.c index c8ec049..6703a17 100644 --- a/drivers/net/e1000/base/e1000_mac.c +++ b/drivers/net/e1000/base/e1000_mac.c @@ -106,7 +106,7 @@ void e1000_null_mac_generic(struct e1000_hw E1000_UNUSEDARG *hw) * @hw: pointer to the HW structure **/ s32 e1000_null_link_info(struct e1000_hw E1000_UNUSEDARG *hw, - u16 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d) + u32 E1000_UNUSEDARG *s, u16 E1000_UNUSEDARG *d) { DEBUGFUNC("e1000_null_link_info"); UNREFERENCED_3PARAMETER(hw, s, d); @@ -1346,7 +1346,8 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) s32 ret_val = E1000_SUCCESS; u32 pcs_status_reg, pcs_adv_reg, pcs_lp_ability_reg, pcs_ctrl_reg; u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; - u16 speed, duplex; + u32 speed; + u16 duplex; DEBUGFUNC("e1000_config_fc_after_link_up_generic"); @@ -1648,7 +1649,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * Read the status register for the current speed/duplex and store the current * speed and duplex for copper connections. **/ -s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, +s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed, u16 *duplex) { u32 status; @@ -1688,7 +1689,7 @@ s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, * for fiber/serdes links. **/ s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E1000_UNUSEDARG *hw, - u16 *speed, u16 *duplex) + u32 *speed, u16 *duplex) { DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic"); UNREFERENCED_1PARAMETER(hw); diff --git a/drivers/net/e1000/base/e1000_mac.h b/drivers/net/e1000/base/e1000_mac.h index 5a7ce4a..987df76 100644 --- a/drivers/net/e1000/base/e1000_mac.h +++ b/drivers/net/e1000/base/e1000_mac.h @@ -40,7 +40,7 @@ void e1000_init_mac_ops_generic(struct e1000_hw *hw); #endif /* E1000_REMOVED */ void e1000_null_mac_generic(struct e1000_hw *hw); s32 e1000_null_ops_generic(struct e1000_hw *hw); -s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d); +s32 e1000_null_link_info(struct e1000_hw *hw, u32 *s, u16 *d); bool e1000_null_mng_mode(struct e1000_hw *hw); void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a); void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b); @@ -61,10 +61,10 @@ s32 e1000_get_bus_info_pcie_generic(struct e1000_hw *hw); void e1000_set_lan_id_single_port(struct e1000_hw *hw); void e1000_set_lan_id_multi_port_pci(struct e1000_hw *hw); s32 e1000_get_hw_semaphore_generic(struct e1000_hw *hw); -s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u16 *speed, +s32 e1000_get_speed_and_duplex_copper_generic(struct e1000_hw *hw, u32 *speed, u16 *duplex); s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, - u16 *speed, u16 *duplex); + u32 *speed, u16 *duplex); s32 e1000_id_led_init_generic(struct e1000_hw *hw); s32 e1000_led_on_generic(struct e1000_hw *hw); s32 e1000_led_off_generic(struct e1000_hw *hw); diff --git a/drivers/net/e1000/base/e1000_vf.c b/drivers/net/e1000/base/e1000_vf.c index 778561e..2221f1c 100644 --- a/drivers/net/e1000/base/e1000_vf.c +++ b/drivers/net/e1000/base/e1000_vf.c @@ -43,7 +43,7 @@ STATIC s32 e1000_setup_link_vf(struct e1000_hw *hw); STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw); STATIC s32 e1000_init_mac_params_vf(struct e1000_hw *hw); STATIC s32 e1000_check_for_link_vf(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed, u16 *duplex); STATIC s32 e1000_init_hw_vf(struct e1000_hw *hw); STATIC s32 e1000_reset_hw_vf(struct e1000_hw *hw); @@ -220,7 +220,7 @@ STATIC s32 e1000_get_bus_info_pcie_vf(struct e1000_hw *hw) * Since we cannot read the PHY and get accurate link info, we must rely upon * the status register's data which is often stale and inaccurate. **/ -STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u16 *speed, +STATIC s32 e1000_get_link_up_info_vf(struct e1000_hw *hw, u32 *speed, u16 *duplex) { s32 status; diff --git a/drivers/net/e1000/base/e1000_vf.h b/drivers/net/e1000/base/e1000_vf.h index 6d5bd99..9d801ad 100644 --- a/drivers/net/e1000/base/e1000_vf.h +++ b/drivers/net/e1000/base/e1000_vf.h @@ -201,7 +201,7 @@ struct e1000_mac_operations { s32 (*check_for_link)(struct e1000_hw *); void (*clear_vfta)(struct e1000_hw *); s32 (*get_bus_info)(struct e1000_hw *); - s32 (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *); + s32 (*get_link_up_info)(struct e1000_hw *, u32 *, u16 *); void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32); s32 (*reset_hw)(struct e1000_hw *); s32 (*init_hw)(struct e1000_hw *); diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c index 72f792c..35ef558 100644 --- a/drivers/net/e1000/em_ethdev.c +++ b/drivers/net/e1000/em_ethdev.c @@ -493,6 +493,9 @@ eth_em_start(struct rte_eth_dev *dev) struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); int ret, mask; + uint32_t *speeds; + int num_speeds; + bool autoneg; PMD_INIT_FUNC_TRACE(); @@ -547,56 +550,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); /* check if lsc interrupt feature is enabled */ @@ -616,9 +609,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); } @@ -934,11 +926,11 @@ eth_em_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->max_rx_queues = 1; dev_info->max_tx_queues = 1; - 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 */ @@ -987,13 +979,16 @@ 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)) { + uint16_t duplex; hw->mac.ops.get_link_up_info(hw, &link.link_speed, - &link.link_duplex); - link.link_status = 1; + &duplex); + link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX : + ETH_LINK_HALF_DUPLEX; + 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 927f5d9..2bbac02 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -889,6 +889,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(); @@ -984,48 +987,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); /* check if lsc interrupt feature is enabled */ @@ -1055,9 +1056,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); } @@ -1571,11 +1571,11 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) .txq_flags = 0, }; - 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 @@ -1681,13 +1681,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete) /* Now we check if a transition has happened */ if (link_check) { + uint16_t duplex; hw->mac.ops.get_link_up_info(hw, &link.link_speed, - &link.link_duplex); - link.link_status = 1; + &duplex); + link.link_duplex = (duplex) ? ETH_LINK_FULL_DUPLEX : + ETH_LINK_HALF_DUPLEX ; + 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 ca6357c..6e05355 100644 --- a/drivers/net/fm10k/fm10k_ethdev.c +++ b/drivers/net/fm10k/fm10k_ethdev.c @@ -862,7 +862,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; } @@ -964,9 +964,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev, ETH_TXQ_FLAGS_NOOFFLOADS, }; - 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 8a5dfbf..b18e81f 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -835,27 +835,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; } @@ -924,9 +917,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; @@ -944,10 +937,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; } @@ -995,6 +986,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"); @@ -1209,7 +1207,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; @@ -1231,25 +1229,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) @@ -1687,10 +1688,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; } @@ -6195,15 +6196,15 @@ i40e_timesync_enable(struct rte_eth_dev *dev) uint32_t tsync_inc_h; 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 b694400..8d3acae 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -1635,13 +1635,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 3be84aa..f4dd1d2 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -1676,14 +1676,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; } @@ -1769,32 +1768,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; @@ -2400,15 +2389,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info) dev_info->reta_size = ETH_RSS_RETA_SIZE_128; 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 @@ -2471,9 +2461,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); @@ -2486,8 +2476,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; @@ -2500,26 +2490,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); diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index b45e21a..96fe4b6 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -4207,6 +4207,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 743feef..5875371 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/null/rte_eth_null.c b/drivers/net/null/rte_eth_null.c index e244595..7704fa6 100644 --- a/drivers/net/null/rte_eth_null.c +++ b/drivers/net/null/rte_eth_null.c @@ -79,9 +79,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 f2e4634..ea7a28f 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 0ba36d5..626c381 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 465d3cd..ecbf9f2 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1517,7 +1517,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 9026d42..424d650 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 a70be5c..6860360 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethdev.c +++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c @@ -697,9 +697,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 73e8bce..fb492ee 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 dummy 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 inline struct rte_mbuf * diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c index c9b78f9..92e6a18 100644 --- a/examples/ip_pipeline/config_parse.c +++ b/examples/ip_pipeline/config_parse.c @@ -83,8 +83,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 f593f6e..29b2960 100644 --- a/lib/librte_ether/rte_ethdev.c +++ b/lib/librte_ether/rte_ethdev.c @@ -1072,6 +1072,55 @@ rte_eth_dev_check_mq_mode(uint8_t port_id, uint16_t nb_rx_q, uint16_t nb_tx_q, } 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 951a423..54ee6f9 100644 --- a/lib/librte_ether/rte_ethdev.h +++ b/lib/librte_ether/rte_ethdev.h @@ -238,26 +238,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. */ + uint32_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 @@ -747,10 +780,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 @@ -812,26 +849,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 { @@ -1667,6 +1684,22 @@ struct eth_driver { extern 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