From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f68.google.com (mail-wm0-f68.google.com [74.125.82.68]) by dpdk.org (Postfix) with ESMTP id 302F7C4EE for ; Fri, 29 Jan 2016 01:42:37 +0100 (CET) Received: by mail-wm0-f68.google.com with SMTP id p63so6921274wmp.1 for ; Thu, 28 Jan 2016 16:42:37 -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=M/xkkAk+LGmdcgGxQLbx/osbul+In2/vFrMGuE2wTE0=; b=KSWuMFpLUKSOk6id33ZSU5xr1SKu5z8uAg3MTDeXWp3dkyRV87KdnBrlS9yhxTOZRK snMv5Q4AU06MnrQ/K45Gbj1SYelGpEeiDhe3/Rua5FnyQsJGHaOTIJPNEDniqBQNfTOs mOZaxIgSA/VA3yEYGboCHJJukCbzrqbkCFD2WmrQDNbGGe8oK3rmo8IonU6PRycb4FzB SsxBxwpiQi+Dk2UCNMZPPv87m79vH17XMIMQimHaS1M8Pe22HrtHlPCaRuUcT4rKcUE+ htAh6K1M97+ygbJSmA2Y4a8cmltQytF94IUDDOHoQ0w1WgJf13O2mzmig74l4FLrroUx pulQ== 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=M/xkkAk+LGmdcgGxQLbx/osbul+In2/vFrMGuE2wTE0=; b=I2ZjHZrVLwcQdyDOIQgyZjuIS/9fZb+PHnNwKtaNq9D0g6WtusEKxVMrMFBkUYbPbh 0czFSSTBILITE3jnwme6xgy24mGyu8bzxV79YksBrpfojRxYEzgNgX7csE0hTE3HECuh q1mSeTvyrbCxJFcAdaj3waPGI4Ch2WJU/u+T/TjALoaN+MMtMNFTGKCWb3D7pRfGvmzH m+4OA99royvu+M2SqDoyUo5wk5G8ZVNFJgpHegWGvz3vHA0WGysYmvhRSavSWeGcz1KF vLo3XvkCDiUfLz8vE5Jur3ijrF0Dhl9npGasl025KIz8USarVIdohye5ipLWb+hwuv5O m7Vw== X-Gm-Message-State: AG10YOTN1bod7L+P9RZfoy7Kw155Y8W/9PF+OSW9a97UpDVRQwbYFwUIEtakHwCAcZg5jQ== X-Received: by 10.28.53.193 with SMTP id c184mr5741797wma.4.1454028157036; Thu, 28 Jan 2016 16:42:37 -0800 (PST) Received: from localhost.localdomain (251.Red-79-159-160.dynamicIP.rima-tde.net. [79.159.160.251]) by smtp.gmail.com with ESMTPSA id c26sm4078518wmi.24.2016.01.28.16.42.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 28 Jan 2016 16:42:36 -0800 (PST) From: Marc Sune To: dev@dpdk.org, Wenzhuo Lu , Helin Zhang , Harish Patil , Jing Chen Date: Fri, 29 Jan 2016 01:42:05 +0100 Message-Id: <1454028127-10401-4-git-send-email-marcdevel@gmail.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1454028127-10401-1-git-send-email-marcdevel@gmail.com> References: <1445810400-8978-1-git-send-email-marcdevel@gmail.com> <1454028127-10401-1-git-send-email-marcdevel@gmail.com> Subject: [dpdk-dev] [PATCH v7 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: , X-List-Received-Date: Fri, 29 Jan 2016 00:42:37 -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 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 | 7 +- 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 | 78 ++++++++---------- 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, 454 insertions(+), 365 deletions(-) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index 6d28c1b..00571bc 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/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/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/e1000/base/e1000_80003es2lan.c b/drivers/net/e1000/base/e1000_80003es2lan.c index 5ac925e..ae11cac 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; @@ -1247,7 +1247,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 9cdb91c..73f9234 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 fc96199..4402f63 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 723885d..f8d61e4 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); @@ -1167,7 +1167,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; @@ -1194,7 +1194,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"); @@ -1325,7 +1326,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 bbfcae8..3a066d5 100644 --- a/drivers/net/e1000/base/e1000_api.c +++ b/drivers/net/e1000/base/e1000_api.c @@ -673,7 +673,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 0bc471d..7327750 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); int 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 69aa1f2..692845d 100644 --- a/drivers/net/e1000/base/e1000_defines.h +++ b/drivers/net/e1000/base/e1000_defines.h @@ -348,8 +348,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 e4e4f76..30e7f3b 100644 --- a/drivers/net/e1000/base/e1000_hw.h +++ b/drivers/net/e1000/base/e1000_hw.h @@ -686,7 +686,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 89d07e9..a6e01c7 100644 --- a/drivers/net/e1000/base/e1000_ich8lan.c +++ b/drivers/net/e1000/base/e1000_ich8lan.c @@ -108,7 +108,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); @@ -1458,7 +1458,8 @@ STATIC s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) */ if (((hw->mac.type == e1000_pch2lan) || (hw->mac.type == e1000_pch_lpt)) && link) { - u16 speed, duplex; + u16 duplex; + u32 speed; e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex); tipg_reg = E1000_READ_REG(hw, E1000_TIPG); @@ -4623,7 +4624,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 a0f3a99..c66421c 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); @@ -1348,7 +1348,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"); @@ -1650,7 +1651,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; @@ -1690,7 +1691,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 96a260c..fef862f 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 7845b48..c7fc80f 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 d6216de..f7b5ea8 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 fd48bbf..a041710 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,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 9c8dffa..c1c41b3 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,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 aeb2962..702eb97 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 d242973..34bc2c9 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 14d2a50..f06f828 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 4e3ab3d..14a03e1 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 1f3ed59..4dbc8a9 100644 --- a/drivers/net/mlx4/mlx4.c +++ b/drivers/net/mlx4/mlx4.c @@ -4637,6 +4637,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 35134ba..f42c1d4 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 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 d928339..83a2ffe 100644 --- a/drivers/net/virtio/virtio_ethdev.c +++ b/drivers/net/virtio/virtio_ethdev.c @@ -1631,7 +1631,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 ae2d47d..8598815 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 dbc1599..9b32de5 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. */ + 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 @@ -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 -- 2.1.4