From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-io0-f171.google.com (mail-io0-f171.google.com [209.85.223.171]) by dpdk.org (Postfix) with ESMTP id DA0825686 for ; Sun, 25 Oct 2015 23:03:54 +0100 (CET) Received: by ioll68 with SMTP id l68so170122036iol.3 for ; Sun, 25 Oct 2015 15:03:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=0afS7bMTMiU3aCxfyFskbksx102kPHuQ28NpW/2g0Xw=; b=tPXP09Hg+ohpoCwySK/NQltKBcd7xCmqw75lcZCq2/RoBIXSLt40J4M03lJzD1tbrV gO5VVm98eg2z258p0Pqc7zQO/ktvmQhoIV0m1aaKWIic13Dzk389XgoQ085oEWP5CTQv 5kC8l5dxjMTy64TlB8vTyNWMal/Qa5aGwS98xzy2kfbekI3eKTFHcOqwvr0RnZrrphP/ Kta9mtg1CULlHFS6BkZ4QSQ5xkfzEKB0bTwt0STJSPONzN8FPCNHupwEiKHDNVnveZAP gXWisADB76Rv1caLgxyqgatm1XzGulysGWOJYkreEroRSGxvXbKDzoPW4TxYrHr6KSwG 5szA== MIME-Version: 1.0 X-Received: by 10.107.15.166 with SMTP id 38mr31663905iop.66.1445810634269; Sun, 25 Oct 2015 15:03:54 -0700 (PDT) Received: by 10.79.109.202 with HTTP; Sun, 25 Oct 2015 15:03:54 -0700 (PDT) In-Reply-To: <1445810400-8978-4-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> <1445810400-8978-4-git-send-email-marcdevel@gmail.com> Date: Sun, 25 Oct 2015 23:03:54 +0100 Message-ID: From: Marc Sune To: dev@dpdk.org Content-Type: text/plain; charset=UTF-8 X-Content-Filtered-By: Mailman/MimeDel 2.1.15 Subject: Re: [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: , X-List-Received-Date: Sun, 25 Oct 2015 22:03:55 -0000 While testing this patch with some XL710, it seems even with current HEAD, setting link speed into dev_conf to 10G does not work, it always takes autoneg with all speeds. Besides, this patch in particular should be tested for the rest of drivers which I don't have HW for. Regards marc 2015-10-25 22:59 GMT+01:00 Marc Sune : > 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 > -- > 2.1.4 > >