From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Ananyev, Konstantin" Subject: Re: [PATCH v7 3/5] ethdev: redesign link speed config API Date: Fri, 29 Jan 2016 09:24:12 +0000 Message-ID: <2601191342CEEE43887BDE71AB97725836B00086@irsmsx105.ger.corp.intel.com> References: <1445810400-8978-1-git-send-email-marcdevel@gmail.com> <1454028127-10401-1-git-send-email-marcdevel@gmail.com> <1454028127-10401-4-git-send-email-marcdevel@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable To: Marc Sune , "dev@dpdk.org" , "Lu, Wenzhuo" , "Zhang, Helin" , Harish Patil , "Chen, Jing D" Return-path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id AEC85C5F6 for ; Fri, 29 Jan 2016 10:24:18 +0100 (CET) In-Reply-To: <1454028127-10401-4-git-send-email-marcdevel@gmail.com> Content-Language: en-US List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Hi Marc, > -----Original Message----- > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Marc Sune > Sent: Friday, January 29, 2016 12:42 AM > To: dev@dpdk.org; Lu, Wenzhuo; Zhang, Helin; Harish Patil; Chen, Jing D > Subject: [dpdk-dev] [PATCH v7 3/5] ethdev: redesign link speed config API >=20 > This patch redesigns the API to set the link speed/s configure > for an ethernet port. Specifically: >=20 > - 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. >=20 > Other changes: >=20 > * 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. Can you avoid modifications in the e1000/base code? We do not modify (and maintain) that part on our own. Instead we take it straight from Intel ND. =20 So if you feel like these changes are really necessary - please submit a pa= tch to ND first, and if your changes will be applied, will pick it up from them= .=20 Thanks Konstantin >=20 > 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(-) >=20 > 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; > }; >=20 > +static int > +parse_and_check_speed_duplex(char *value1, char *value2, uint32_t *link_= speed) > +{ > + > + int duplex; > + > + if (!strcmp(value2, "half")) { > + duplex =3D 0; > + } else if (!strcmp(value2, "full")) { > + duplex =3D 1; > + } else if (!strcmp(value2, "auto")) { > + duplex =3D 1; > + } else { > + printf("Unknown parameter\n"); > + return -1; > + } > + > + if (!strcmp(value1, "10")) { > + *link_speed =3D (duplex) ? ETH_LINK_SPEED_10M : > + ETH_LINK_SPEED_10M_HD; > + } else if (!strcmp(value1, "100")) { > + *link_speed =3D (duplex) ? ETH_LINK_SPEED_100M : > + ETH_LINK_SPEED_100M_HD; > + } else if (!strcmp(value1, "1000")) { > + if (!duplex) > + goto invalid_speed_param; > + *link_speed =3D ETH_LINK_SPEED_1G; > + } else if (!strcmp(value1, "10000")) { > + if (!duplex) > + goto invalid_speed_param; > + *link_speed =3D ETH_LINK_SPEED_10G; > + } else if (!strcmp(value1, "40000")) { > + if (!duplex) > + goto invalid_speed_param; > + *link_speed =3D ETH_LINK_SPEED_40G; > + } else if (!strcmp(value1, "auto")) { > + if (!duplex) > + goto invalid_speed_param; > + *link_speed =3D 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 =3D parsed_result; > - uint16_t link_speed =3D ETH_LINK_SPEED_AUTONEG; > - uint16_t link_duplex =3D 0; > + uint32_t link_speed; > portid_t pid; >=20 > if (!all_ports_stopped()) { > @@ -971,40 +1022,18 @@ cmd_config_speed_all_parsed(void *parsed_result, > return; > } >=20 > - if (!strcmp(res->value1, "10")) > - link_speed =3D ETH_LINK_SPEED_10; > - else if (!strcmp(res->value1, "100")) > - link_speed =3D ETH_LINK_SPEED_100; > - else if (!strcmp(res->value1, "1000")) > - link_speed =3D ETH_LINK_SPEED_1000; > - else if (!strcmp(res->value1, "10000")) > - link_speed =3D ETH_LINK_SPEED_10G; > - else if (!strcmp(res->value1, "40000")) > - link_speed =3D ETH_LINK_SPEED_40G; > - else if (!strcmp(res->value1, "auto")) > - link_speed =3D 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 =3D ETH_LINK_HALF_DUPLEX; > - else if (!strcmp(res->value2, "full")) > - link_duplex =3D ETH_LINK_FULL_DUPLEX; > - else if (!strcmp(res->value2, "auto")) > - link_duplex =3D ETH_LINK_AUTONEG_DUPLEX; > - else { > - printf("Unknown parameter\n"); > - return; > - } >=20 > FOREACH_PORT(pid, ports) { > - ports[pid].dev_conf.link_speed =3D link_speed; > - ports[pid].dev_conf.link_duplex =3D link_duplex; > + ports[pid].dev_conf.link_speeds =3D link_speed; > } >=20 > cmd_reconfig_device_queue(RTE_PORT_ALL, 1, 1); > + > + return; > } >=20 > cmdline_parse_token_string_t cmd_config_speed_all_port =3D > @@ -1059,8 +1088,7 @@ cmd_config_speed_specific_parsed(void *parsed_resul= t, > __attribute__((unused)) void *data) > { > struct cmd_config_speed_specific *res =3D parsed_result; > - uint16_t link_speed =3D ETH_LINK_SPEED_AUTONEG; > - uint16_t link_duplex =3D 0; > + uint32_t link_speed; >=20 > if (!all_ports_stopped()) { > printf("Please stop all ports first\n"); > @@ -1070,36 +1098,12 @@ cmd_config_speed_specific_parsed(void *parsed_res= ult, > if (port_id_is_invalid(res->id, ENABLED_WARN)) > return; >=20 > - if (!strcmp(res->value1, "10")) > - link_speed =3D ETH_LINK_SPEED_10; > - else if (!strcmp(res->value1, "100")) > - link_speed =3D ETH_LINK_SPEED_100; > - else if (!strcmp(res->value1, "1000")) > - link_speed =3D ETH_LINK_SPEED_1000; > - else if (!strcmp(res->value1, "10000")) > - link_speed =3D ETH_LINK_SPEED_10000; > - else if (!strcmp(res->value1, "40000")) > - link_speed =3D ETH_LINK_SPEED_40G; > - else if (!strcmp(res->value1, "auto")) > - link_speed =3D 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 =3D ETH_LINK_HALF_DUPLEX; > - else if (!strcmp(res->value2, "full")) > - link_duplex =3D ETH_LINK_FULL_DUPLEX; > - else if (!strcmp(res->value2, "auto")) > - link_duplex =3D ETH_LINK_AUTONEG_DUPLEX; > - else { > - printf("Unknown parameter\n"); > - return; > - } >=20 > - ports[res->id].dev_conf.link_speed =3D link_speed; > - ports[res->id].dev_conf.link_duplex =3D link_duplex; > + ports[res->id].dev_conf.link_speeds =3D link_speed; >=20 > 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, >=20 > TAILQ_INIT(&(eth_dev->link_intr_cbs)); >=20 > - eth_dev->data->dev_link.link_status =3D 0; > - eth_dev->data->dev_link.link_speed =3D ETH_LINK_SPEED_10000; > + eth_dev->data->dev_link.link_status =3D ETH_LINK_DOWN; > + eth_dev->data->dev_link.link_speed =3D ETH_SPEED_NUM_10G; > eth_dev->data->dev_link.link_duplex =3D ETH_LINK_FULL_DUPLEX; >=20 > eth_dev->data->mac_addrs =3D rte_zmalloc(name, ETHER_ADDR_LEN, 0); > diff --git a/drivers/net/af_packet/rte_eth_af_packet.c b/drivers/net/af_p= acket/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[] =3D { > static const char *drivername =3D "AF_PACKET PMD"; >=20 > static struct rte_eth_link pmd_link =3D { > - .link_speed =3D 10000, > + .link_speed =3D ETH_SPEED_NUM_10G, > .link_duplex =3D ETH_LINK_FULL_DUPLEX, > - .link_status =3D 0 > + .link_status =3D ETH_LINK_DOWN, > + .link_autoneg =3D ETH_LINK_SPEED_NEG > }; >=20 > static uint16_t > diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.c b/drivers/net/bond= ing/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; >=20 > switch (speed) { > - case ETH_LINK_SPEED_AUTONEG: > + case ETH_SPEED_NUM_NONE: > key_speed =3D 0x00; > break; > - case ETH_LINK_SPEED_10: > + case ETH_SPEED_NUM_10M: > key_speed =3D BOND_LINK_SPEED_KEY_10M; > break; > - case ETH_LINK_SPEED_100: > + case ETH_SPEED_NUM_100M: > key_speed =3D BOND_LINK_SPEED_KEY_100M; > break; > - case ETH_LINK_SPEED_1000: > + case ETH_SPEED_NUM_1G: > key_speed =3D BOND_LINK_SPEED_KEY_1000M; > break; > - case ETH_LINK_SPEED_10G: > + case ETH_SPEED_NUM_10G: > key_speed =3D BOND_LINK_SPEED_KEY_10G; > break; > - case ETH_LINK_SPEED_20G: > + case ETH_SPEED_NUM_20G: > key_speed =3D BOND_LINK_SPEED_KEY_20G; > break; > - case ETH_LINK_SPEED_40G: > + case ETH_SPEED_NUM_40G: > key_speed =3D BOND_LINK_SPEED_KEY_40G; > break; > default: > diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_h= w.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 |=3D PAUSE_TX; > if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) > - speed =3D ETH_LINK_SPEED_100; > + speed =3D ETH_SPEED_NUM_100M; > else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) > - speed =3D ETH_LINK_SPEED_1000; > + speed =3D ETH_SPEED_NUM_1G; > else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) > - speed =3D ETH_LINK_SPEED_10000; > + speed =3D ETH_SPEED_NUM_10G; > else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) > - speed =3D ETH_LINK_SPEED_40G; > + speed =3D ETH_SPEED_NUM_40G; >=20 > for_each_port(adap, i) { > pi =3D adap2pinfo(adap, i); > diff --git a/drivers/net/e1000/base/e1000_80003es2lan.c b/drivers/net/e10= 00/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(stru= ct e1000_hw *hw) > STATIC s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw) > { > s32 ret_val =3D E1000_SUCCESS; > - u16 speed; > + u32 speed; > u16 duplex; >=20 > DEBUGFUNC("e1000_configure_on_link_up"); > diff --git a/drivers/net/e1000/base/e1000_82541.c b/drivers/net/e1000/bas= e/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 =3D &hw->phy; > @@ -667,8 +667,8 @@ STATIC s32 e1000_config_dsp_after_link_change_82541(s= truct e1000_hw *hw, > struct e1000_phy_info *phy =3D &hw->phy; > struct e1000_dev_spec_82541 *dev_spec =3D &hw->dev_spec._82541; > s32 ret_val; > - u32 idle_errs =3D 0; > - u16 phy_data, phy_saved_data, speed, duplex, i; > + u32 idle_errs =3D 0, speed; > + u16 phy_data, phy_saved_data, duplex, i; > u16 ffe_idle_err_timeout =3D FFE_IDLE_ERR_COUNT_TIMEOUT_20; > u16 dsp_reg_array[IGP01E1000_PHY_CHANNEL_NUM] =3D { > IGP01E1000_PHY_AGC_PARAM_A, > diff --git a/drivers/net/e1000/base/e1000_82543.c b/drivers/net/e1000/bas= e/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 =3D &hw->mac; > - u32 icr, rctl; > + u32 icr, rctl, speed; > s32 ret_val; > - u16 speed, duplex; > + u16 duplex; > bool link; >=20 > DEBUGFUNC("e1000_check_for_copper_link_82543"); > diff --git a/drivers/net/e1000/base/e1000_82575.c b/drivers/net/e1000/bas= e/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 offs= et, > @@ -80,7 +80,7 @@ STATIC s32 e1000_write_phy_reg_sgmii_82575(struct e100= 0_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 e100= 0_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; >=20 > DEBUGFUNC("e1000_check_for_link_82575"); >=20 > @@ -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 =3D &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 *dup= lex) > +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *dup= lex) > { > 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 *dup= lex); > +s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u32 *speed, u16 *dup= lex); > 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/b= ase/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 >=20 > #define PHY_FORCE_TIME 20 >=20 > diff --git a/drivers/net/e1000/base/e1000_hw.h b/drivers/net/e1000/base/e= 1000_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/b= ase/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(stru= ct e1000_hw *hw) > */ > if (((hw->mac.type =3D=3D e1000_pch2lan) || > (hw->mac.type =3D=3D e1000_pch_lpt)) && link) { > - u16 speed, duplex; > + u16 duplex; > + u32 speed; >=20 > e1000_get_speed_and_duplex_copper_generic(hw, &speed, &duplex); > tipg_reg =3D E1000_READ_REG(hw, E1000_TIPG); > @@ -4623,7 +4624,7 @@ STATIC s32 e1000_setup_copper_link_pch_lpt(struct e= 1000_hw *hw) > * information and then calls the Kumeran lock loss workaround for link= s at > * gigabit speeds. > **/ > -STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *spee= d, > +STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u32 *spee= d, > 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_UNU= SEDARG *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 e1= 000_hw *hw) > s32 ret_val =3D 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; >=20 > DEBUGFUNC("e1000_config_fc_after_link_up_generic"); >=20 > @@ -1650,7 +1651,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1= 000_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(struc= t e1000_hw *hw, u16 *speed, > * for fiber/serdes links. > **/ > s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw E100= 0_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/e= 1000_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 rel= y 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/e= 1000_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 =3D &dev->pci_dev->intr_handle; > int ret, mask; > uint32_t intr_vector =3D 0; > + uint32_t *speeds; > + int num_speeds; > + bool autoneg; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > @@ -583,56 +586,46 @@ eth_em_start(struct rte_eth_dev *dev) > E1000_WRITE_REG(hw, E1000_ITR, UINT16_MAX); >=20 > /* Setup link speed and duplex */ > - switch (dev->data->dev_conf.link_speed) { > - case ETH_LINK_SPEED_AUTONEG: > - if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_AUTONEG_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_SPEED_DUPLEX; > - else if (dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_HALF_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_HALF_DUPLEX; > - else if (dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_FULL_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_FULL_DUPLEX; > - else > - goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_10: > - if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_AUTONEG_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_10_SPEED; > - else if (dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_HALF_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_10_HALF; > - else if (dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_FULL_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_10_FULL; > - else > - goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_100: > - if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_AUTONEG_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_100_SPEED; > - else if (dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_HALF_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_100_HALF; > - else if (dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_FULL_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_100_FULL; > - else > + speeds =3D &dev->data->dev_conf.link_speeds; > + if (*speeds =3D=3D ETH_LINK_SPEED_AUTONEG) { > + hw->phy.autoneg_advertised =3D E1000_ALL_SPEED_DUPLEX; > + } else { > + num_speeds =3D 0; > + autoneg =3D ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG); > + > + /* Reset */ > + hw->phy.autoneg_advertised =3D 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 =3D -1; > goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_1000: > - if ((dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_AUTONEG_DUPLEX) || > - (dev->data->dev_conf.link_duplex =3D=3D > - ETH_LINK_FULL_DUPLEX)) > - hw->phy.autoneg_advertised =3D ADVERTISE_1000_FULL; > - else > + } > + if (*speeds & ETH_LINK_SPEED_10M_HD) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_10_HALF; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_10M) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_10_FULL; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_100M_HD) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_100_HALF; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_100M) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_100_FULL; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_1G) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_1000_FULL; > + num_speeds++; > + } > + if (num_speeds =3D=3D 0 || (!autoneg && (num_speeds > 2))) > goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_10000: > - default: > - goto error_invalid_config; > } > + > e1000_setup_link(hw); >=20 > if (rte_intr_allow_others(intr_handle)) { > @@ -665,9 +658,8 @@ eth_em_start(struct rte_eth_dev *dev) > return (0); >=20 > 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 =3D EM_TXD_ALIGN, > }; >=20 > - dev_info->speed_capa =3D 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 =3D ETH_LINK_SPEED_10M_HD | > + ETH_LINK_SPEED_10M | > + ETH_LINK_SPEED_100M_HD | > + ETH_LINK_SPEED_100M | > + ETH_LINK_SPEED_1G; > } >=20 > /* return 0 means link status changed, -1 means not changed */ > @@ -1077,13 +1069,16 @@ eth_em_link_update(struct rte_eth_dev *dev, int w= ait_to_complete) >=20 > /* Now we check if a transition has happened */ > if (link_check && (link.link_status =3D=3D 0)) { > + uint16_t duplex; > hw->mac.ops.get_link_up_info(hw, &link.link_speed, > - &link.link_duplex); > - link.link_status =3D 1; > + &duplex); > + link.link_duplex =3D (duplex) ? ETH_LINK_FULL_DUPLEX : > + ETH_LINK_HALF_DUPLEX; > + link.link_status =3D ETH_LINK_UP; > } else if (!link_check && (link.link_status =3D=3D 1)) { > link.link_speed =3D 0; > - link.link_duplex =3D 0; > - link.link_status =3D 0; > + link.link_duplex =3D ETH_LINK_HALF_DUPLEX; > + link.link_status =3D ETH_LINK_DOWN; > } > rte_em_dev_atomic_write_link_status(dev, &link); >=20 > diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethde= v.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 =3D 0; > uint32_t ctrl_ext; > + uint32_t *speeds; > + int num_speeds; > + bool autoneg; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > @@ -1219,48 +1222,46 @@ eth_igb_start(struct rte_eth_dev *dev) > } >=20 > /* Setup link speed and duplex */ > - switch (dev->data->dev_conf.link_speed) { > - case ETH_LINK_SPEED_AUTONEG: > - if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_AUTONEG_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_SPEED_DUPLEX; > - else if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_HALF_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_HALF_DUPLEX; > - else if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_FULL_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_FULL_DUPLEX; > - else > - goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_10: > - if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_AUTONEG_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_10_SPEED; > - else if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_HALF_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_10_HALF; > - else if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_FULL_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_10_FULL; > - else > - goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_100: > - if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_AUTONEG_DUPLEX) > - hw->phy.autoneg_advertised =3D E1000_ALL_100_SPEED; > - else if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_HALF_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_100_HALF; > - else if (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_FULL_DUPLEX) > - hw->phy.autoneg_advertised =3D ADVERTISE_100_FULL; > - else > + speeds =3D &dev->data->dev_conf.link_speeds; > + if (*speeds =3D=3D ETH_LINK_SPEED_AUTONEG) { > + hw->phy.autoneg_advertised =3D E1000_ALL_SPEED_DUPLEX; > + } else { > + num_speeds =3D 0; > + autoneg =3D ~(*speeds & ETH_LINK_SPEED_NO_AUTONEG); > + > + /* Reset */ > + hw->phy.autoneg_advertised =3D 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 =3D -1; > goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_1000: > - if ((dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_AUTONEG_DUPLEX) |= | > - (dev->data->dev_conf.link_duplex =3D=3D ETH_LINK_FULL_DUPLEX)) > - hw->phy.autoneg_advertised =3D ADVERTISE_1000_FULL; > - else > + } > + if (*speeds & ETH_LINK_SPEED_10M_HD) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_10_HALF; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_10M) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_10_FULL; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_100M_HD) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_100_HALF; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_100M) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_100_FULL; > + num_speeds++; > + } > + if (*speeds & ETH_LINK_SPEED_1G) { > + hw->phy.autoneg_advertised |=3D ADVERTISE_1000_FULL; > + num_speeds++; > + } > + if (num_speeds =3D=3D 0 || (!autoneg && (num_speeds > 2))) > goto error_invalid_config; > - break; > - case ETH_LINK_SPEED_10000: > - default: > - goto error_invalid_config; > } > + > e1000_setup_link(hw); >=20 > if (rte_intr_allow_others(intr_handle)) { > @@ -1292,9 +1293,8 @@ eth_igb_start(struct rte_eth_dev *dev) > return (0); >=20 > 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 =3D rx_desc_lim; > dev_info->tx_desc_lim =3D tx_desc_lim; >=20 > - dev_info->speed_capa =3D 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 =3D ETH_LINK_SPEED_10M_HD | > + ETH_LINK_SPEED_10M | > + ETH_LINK_SPEED_100M_HD | > + ETH_LINK_SPEED_100M | > + ETH_LINK_SPEED_1G; > } >=20 > static void > @@ -2023,13 +2023,19 @@ eth_igb_link_update(struct rte_eth_dev *dev, int = wait_to_complete) >=20 > /* 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 =3D 1; > + &duplex); > + link.link_duplex =3D (duplex) ? ETH_LINK_FULL_DUPLEX : > + ETH_LINK_HALF_DUPLEX ; > + link.link_status =3D ETH_LINK_UP; > + link.link_autoneg =3D ~(dev->data->dev_conf.link_speeds & > + ETH_LINK_SPEED_NO_AUTONEG); > } else if (!link_check) { > link.link_speed =3D 0; > - link.link_duplex =3D 0; > - link.link_status =3D 0; > + link.link_duplex =3D ETH_LINK_HALF_DUPLEX; > + link.link_status =3D ETH_LINK_DOWN; > + link.link_autoneg =3D ETH_LINK_SPEED_FIXED; > } > rte_igb_dev_atomic_write_link_status(dev, &link); >=20 > diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_e= thdev.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 =3D 0; > dev->data->dev_link.link_duplex =3D ETH_LINK_FULL_DUPLEX; > - dev->data->dev_link.link_status =3D 1; > + dev->data->dev_link.link_status =3D ETH_LINK_UP; >=20 > return 0; > } > @@ -1334,9 +1334,9 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev, > .nb_align =3D FM10K_MULT_TX_DESC, > }; >=20 > - dev_info->speed_capa =3D 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 =3D 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; > } >=20 > static int > diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethde= v.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= ) > } >=20 > 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 =3D I40E_LINK_SPEED_UNKNOWN; >=20 > - switch (eth_link_speed) { > - case ETH_LINK_SPEED_40G: > - link_speed =3D I40E_LINK_SPEED_40GB; > - break; > - case ETH_LINK_SPEED_20G: > - link_speed =3D I40E_LINK_SPEED_20GB; > - break; > - case ETH_LINK_SPEED_10G: > - link_speed =3D I40E_LINK_SPEED_10GB; > - break; > - case ETH_LINK_SPEED_1000: > - link_speed =3D I40E_LINK_SPEED_1GB; > - break; > - case ETH_LINK_SPEED_100: > - link_speed =3D I40E_LINK_SPEED_100MB; > - break; > - } > + if (link_speeds & ETH_LINK_SPEED_40G) > + link_speed |=3D I40E_LINK_SPEED_40GB; > + if (link_speeds & ETH_LINK_SPEED_20G) > + link_speed |=3D I40E_LINK_SPEED_20GB; > + if (link_speeds & ETH_LINK_SPEED_10G) > + link_speed |=3D I40E_LINK_SPEED_10GB; > + if (link_speeds & ETH_LINK_SPEED_1G) > + link_speed |=3D I40E_LINK_SPEED_1GB; > + if (link_speeds & ETH_LINK_SPEED_100M) > + link_speed |=3D I40E_LINK_SPEED_100MB; >=20 > return link_speed; > } > @@ -1372,9 +1365,9 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) > struct i40e_hw *hw =3D I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); > struct rte_eth_conf *conf =3D &dev->data->dev_conf; >=20 > - speed =3D i40e_parse_link_speed(conf->link_speed); > + speed =3D i40e_parse_link_speeds(conf->link_speeds); > abilities |=3D I40E_AQ_PHY_ENABLE_ATOMIC_LINK; > - if (conf->link_speed =3D=3D ETH_LINK_SPEED_AUTONEG) > + if (conf->link_speeds & ETH_LINK_SPEED_AUTONEG) > abilities |=3D I40E_AQ_PHY_AN_ENABLED; > else > abilities |=3D I40E_AQ_PHY_LINK_ENABLED; > @@ -1394,10 +1387,8 @@ i40e_dev_start(struct rte_eth_dev *dev) >=20 > hw->adapter_stopped =3D 0; >=20 > - if ((dev->data->dev_conf.link_duplex !=3D ETH_LINK_AUTONEG_DUPLEX) && > - (dev->data->dev_conf.link_duplex !=3D 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) > } >=20 > /* 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 =3D i40e_apply_link_speed(dev); > if (I40E_SUCCESS !=3D 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 =3D i40e_aq_get_link_info(hw, false, &link_status, NULL); > if (status !=3D I40E_SUCCESS) { > - link.link_speed =3D ETH_LINK_SPEED_100; > + link.link_speed =3D ETH_SPEED_NUM_100M; > link.link_duplex =3D 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 =3D ETH_LINK_SPEED_100; > + link.link_speed =3D ETH_SPEED_NUM_100M; > break; > case I40E_LINK_SPEED_1GB: > - link.link_speed =3D ETH_LINK_SPEED_1000; > + link.link_speed =3D ETH_SPEED_NUM_1G; > break; > case I40E_LINK_SPEED_10GB: > - link.link_speed =3D ETH_LINK_SPEED_10G; > + link.link_speed =3D ETH_SPEED_NUM_10G; > break; > case I40E_LINK_SPEED_20GB: > - link.link_speed =3D ETH_LINK_SPEED_20G; > + link.link_speed =3D ETH_SPEED_NUM_20G; > break; > case I40E_LINK_SPEED_40GB: > - link.link_speed =3D ETH_LINK_SPEED_40G; > + link.link_speed =3D ETH_SPEED_NUM_40G; > break; > default: > - link.link_speed =3D ETH_LINK_SPEED_100; > + link.link_speed =3D ETH_SPEED_NUM_100M; > break; > } >=20 > + link.link_autoneg =3D ~(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 =3D=3D old.link_status) > @@ -2308,10 +2309,10 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct= rte_eth_dev_info *dev_info) >=20 > if (i40e_is_40G_device(hw->device_id)) > /* For XL710 */ > - dev_info->speed_capa =3D ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G; > + dev_info->speed_capa =3D ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G; > else > /* For X710 */ > - dev_info->speed_capa =3D ETH_SPEED_CAP_10G | ETH_SPEED_CAP_40G; > + dev_info->speed_capa =3D ETH_LINK_SPEED_10G | ETH_LINK_SPEED_40G; >=20 > } >=20 > @@ -7835,15 +7836,15 @@ i40e_start_timecounters(struct rte_eth_dev *dev) > rte_i40e_dev_atomic_read_link_status(dev, &link); >=20 > switch (link.link_speed) { > - case ETH_LINK_SPEED_40G: > + case ETH_SPEED_NUM_40G: > tsync_inc_l =3D I40E_PTP_40GB_INCVAL & 0xFFFFFFFF; > tsync_inc_h =3D I40E_PTP_40GB_INCVAL >> 32; > break; > - case ETH_LINK_SPEED_10G: > + case ETH_SPEED_NUM_10G: > tsync_inc_l =3D I40E_PTP_10GB_INCVAL & 0xFFFFFFFF; > tsync_inc_h =3D I40E_PTP_10GB_INCVAL >> 32; > break; > - case ETH_LINK_SPEED_1000: > + case ETH_SPEED_NUM_1G: > tsync_inc_l =3D I40E_PTP_1GB_INCVAL & 0xFFFFFFFF; > tsync_inc_h =3D I40E_PTP_1GB_INCVAL >> 32; > break; > diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_et= hdev_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 =3D=3D I40E_DPDK_VERSION_MAJOR) > + if (vf->version_major =3D=3D 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 =3D ETH_LINK_AUTONEG_DUPLEX; > - new_link.link_speed =3D ETH_LINK_SPEED_10000; > - new_link.link_status =3D 1; > + new_link.link_speed =3D ETH_SPEED_NUM_10G; > + new_link.link_duplex =3D ETH_LINK_FULL_DUPLEX; > + new_link.link_autoneg =3D ETH_LINK_SPEED_NEG; > + new_link.link_status =3D ETH_LINK_UP; > } > i40evf_dev_atomic_write_link_status(dev, &new_link); >=20 > diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_e= thdev.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 =3D 0; > int status; > uint16_t vf, idx; > + uint32_t *link_speeds; >=20 > PMD_INIT_FUNC_TRACE(); >=20 > /* IXGBE devices don't support half duplex */ > - if ((dev->data->dev_conf.link_duplex !=3D ETH_LINK_AUTONEG_DUPLEX) && > - (dev->data->dev_conf.link_duplex !=3D 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; >=20 > - switch(dev->data->dev_conf.link_speed) { > - case ETH_LINK_SPEED_AUTONEG: > - speed =3D (hw->mac.type !=3D 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 =3D IXGBE_LINK_SPEED_100_FULL; > - break; > - case ETH_LINK_SPEED_1000: > - speed =3D IXGBE_LINK_SPEED_1GB_FULL; > - break; > - case ETH_LINK_SPEED_10000: > - speed =3D 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 =3D &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; > } >=20 > + speed =3D 0x0; > + > + if (*link_speeds & ETH_LINK_SPEED_10G) > + speed |=3D IXGBE_LINK_SPEED_10GB_FULL; > + if (*link_speeds & ETH_LINK_SPEED_1G) > + speed |=3D IXGBE_LINK_SPEED_1GB_FULL; > + if (*link_speeds & ETH_LINK_SPEED_100M) > + speed |=3D IXGBE_LINK_SPEED_100_FULL; > + > err =3D ixgbe_setup_link(hw, speed, link_up); > if (err) > goto error; > @@ -2828,15 +2817,16 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struc= t rte_eth_dev_info *dev_info) > dev_info->reta_size =3D ixgbe_reta_size_get(hw->mac.type); > dev_info->flow_type_rss_offloads =3D IXGBE_RSS_OFFLOAD_ALL; >=20 > - dev_info->speed_capa =3D ETH_SPEED_CAP_1G | ETH_SPEED_CAP_10G; > + dev_info->speed_capa =3D ETH_LINK_SPEED_1G | ETH_LINK_SPEED_10G; >=20 > if (hw->mac.type =3D=3D ixgbe_mac_X540 || > hw->mac.type =3D=3D ixgbe_mac_X540_vf || > hw->mac.type =3D=3D ixgbe_mac_X550 || > - hw->mac.type =3D=3D ixgbe_mac_X550_vf) > + hw->mac.type =3D=3D ixgbe_mac_X550_vf) { >=20 > - dev_info->speed_capa |=3D ETH_SPEED_CAP_100M_FD /*| > - ETH_SPEED_CAP_100M_HD*/; > + dev_info->speed_capa |=3D ETH_LINK_SPEED_100M /*| > + ETH_LINK_SPEED_100M_HD*/; > + } > } >=20 > static void > @@ -2903,9 +2893,9 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int = wait_to_complete) > int link_up; > int diag; >=20 > - link.link_status =3D 0; > + link.link_status =3D ETH_LINK_DOWN; > link.link_speed =3D 0; > - link.link_duplex =3D 0; > + link.link_duplex =3D ETH_LINK_HALF_DUPLEX; > memset(&old, 0, sizeof(old)); > rte_ixgbe_dev_atomic_read_link_status(dev, &old); >=20 > @@ -2918,8 +2908,8 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, int = wait_to_complete) > diag =3D ixgbe_check_link(hw, &link_speed, &link_up, 1); >=20 > if (diag !=3D 0) { > - link.link_speed =3D ETH_LINK_SPEED_100; > - link.link_duplex =3D ETH_LINK_HALF_DUPLEX; > + link.link_speed =3D ETH_SPEED_NUM_100M; > + link.link_duplex =3D ETH_LINK_FULL_DUPLEX; > rte_ixgbe_dev_atomic_write_link_status(dev, &link); > if (link.link_status =3D=3D old.link_status) > return -1; > @@ -2932,26 +2922,26 @@ ixgbe_dev_link_update(struct rte_eth_dev *dev, in= t wait_to_complete) > return -1; > return 0; > } > - link.link_status =3D 1; > + link.link_status =3D ETH_LINK_UP; > link.link_duplex =3D ETH_LINK_FULL_DUPLEX; >=20 > switch (link_speed) { > default: > case IXGBE_LINK_SPEED_UNKNOWN: > - link.link_duplex =3D ETH_LINK_HALF_DUPLEX; > - link.link_speed =3D ETH_LINK_SPEED_100; > + link.link_duplex =3D ETH_LINK_FULL_DUPLEX; > + link.link_speed =3D ETH_SPEED_NUM_100M; > break; >=20 > case IXGBE_LINK_SPEED_100_FULL: > - link.link_speed =3D ETH_LINK_SPEED_100; > + link.link_speed =3D ETH_SPEED_NUM_100M; > break; >=20 > case IXGBE_LINK_SPEED_1GB_FULL: > - link.link_speed =3D ETH_LINK_SPEED_1000; > + link.link_speed =3D ETH_SPEED_NUM_1G; > break; >=20 > case IXGBE_LINK_SPEED_10GB_FULL: > - link.link_speed =3D ETH_LINK_SPEED_10000; > + link.link_speed =3D 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); >=20 > switch (link.link_speed) { > - case ETH_LINK_SPEED_100: > + case ETH_SPEED_NUM_100M: > incval =3D IXGBE_INCVAL_100; > shift =3D IXGBE_INCVAL_SHIFT_100; > break; > - case ETH_LINK_SPEED_1000: > + case ETH_SPEED_NUM_1G: > incval =3D IXGBE_INCVAL_1GB; > shift =3D IXGBE_INCVAL_SHIFT_1GB; > break; > - case ETH_LINK_SPEED_10000: > + case ETH_SPEED_NUM_10G: > default: > incval =3D IXGBE_INCVAL_10GB; > shift =3D 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 =3D link_speed; > dev_link.link_duplex =3D ((edata.duplex =3D=3D DUPLEX_HALF) ? > ETH_LINK_HALF_DUPLEX : ETH_LINK_FULL_DUPLEX); > + dev_link.link_autoneg =3D ~(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 =3D dev_link; > diff --git a/drivers/net/mpipe/mpipe_tilegx.c b/drivers/net/mpipe/mpipe_t= ilegx.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) >=20 > speed =3D state & GXIO_MPIPE_LINK_SPEED_MASK; >=20 > + new.link_autoneg =3D ~(dev->data->dev_conf.link_speeds & > + ETH_LINK_SPEED_NO_AUTONEG); > if (speed =3D=3D GXIO_MPIPE_LINK_1G) { > new.link_speed =3D ETH_LINK_SPEED_1000; > new.link_duplex =3D ETH_LINK_FULL_DUPLEX; > - new.link_status =3D 1; > + new.link_status =3D ETH_LINK_UP; > } else if (speed =3D=3D GXIO_MPIPE_LINK_10G) { > new.link_speed =3D ETH_LINK_SPEED_10000; > new.link_duplex =3D ETH_LINK_FULL_DUPLEX; > - new.link_status =3D 1; > + new.link_status =3D ETH_LINK_UP; > } >=20 > rc =3D mpipe_link_compare(&old, &new); > diff --git a/drivers/net/null/rte_eth_null.c b/drivers/net/null/rte_eth_n= ull.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 =3D { .addr_bytes =3D {0} }; > static const char *drivername =3D "Null PMD"; > static struct rte_eth_link pmd_link =3D { > - .link_speed =3D 10000, > + .link_speed =3D ETH_SPEED_NUM_10G, > .link_duplex =3D ETH_LINK_FULL_DUPLEX, > - .link_status =3D 0 > + .link_status =3D ETH_LINK_DOWN, > + .link_autoneg =3D ETH_LINK_SPEED_NEG, > }; >=20 > static uint16_t > diff --git a/drivers/net/pcap/rte_eth_pcap.c b/drivers/net/pcap/rte_eth_p= cap.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 =3D { .addr_bytes =3D { 0, 0, 0, 0x1, = 0x2, 0x3 } }; > static const char *drivername =3D "Pcap PMD"; > static struct rte_eth_link pmd_link =3D { > - .link_speed =3D 10000, > + .link_speed =3D ETH_SPEED_NUM_10G, > .link_duplex =3D ETH_LINK_FULL_DUPLEX, > - .link_status =3D 0 > + .link_status =3D ETH_LINK_DOWN, > + .link_autoneg =3D ETH_LINK_SPEED_FIXED, > }; >=20 > static int > @@ -430,7 +431,7 @@ eth_dev_start(struct rte_eth_dev *dev) >=20 > status_up: >=20 > - dev->data->dev_link.link_status =3D 1; > + dev->data->dev_link.link_status =3D ETH_LINK_UP; > return 0; > } >=20 > @@ -481,7 +482,7 @@ eth_dev_stop(struct rte_eth_dev *dev) > } >=20 > status_down: > - dev->data->dev_link.link_status =3D 0; > + dev->data->dev_link.link_status =3D ETH_LINK_DOWN; > } >=20 > static int > diff --git a/drivers/net/ring/rte_eth_ring.c b/drivers/net/ring/rte_eth_r= ing.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 { >=20 > static const char *drivername =3D "Rings PMD"; > static struct rte_eth_link pmd_link =3D { > - .link_speed =3D 10000, > + .link_speed =3D ETH_SPEED_NUM_10G, > .link_duplex =3D ETH_LINK_FULL_DUPLEX, > - .link_status =3D 0 > + .link_status =3D ETH_LINK_DOWN, > + .link_autoneg =3D ETH_LINK_SPEED_NEG > }; >=20 > static uint16_t > diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virt= io_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, __r= te_unused int wait_to_complet > memset(&link, 0, sizeof(link)); > virtio_dev_atomic_read_link_status(dev, &link); > old =3D link; > - link.link_duplex =3D FULL_DUPLEX; > + link.link_duplex =3D ETH_LINK_FULL_DUPLEX; > link.link_speed =3D SPEED_10G; >=20 > if (vtpci_with_feature(hw, VIRTIO_NET_F_STATUS)) { > diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virt= io_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 >=20 > #ifndef PAGE_SIZE > #define PAGE_SIZE 4096 > diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/v= mxnet3_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, __a= ttribute__((unused)) int wai > ret =3D VMXNET3_READ_BAR1_REG(hw, VMXNET3_REG_CMD); >=20 > if (ret & 0x1) { > - link.link_status =3D 1; > + link.link_status =3D ETH_LINK_UP; > link.link_duplex =3D ETH_LINK_FULL_DUPLEX; > - link.link_speed =3D ETH_LINK_SPEED_10000; > + link.link_speed =3D ETH_SPEED_NUM_10G; > + link.link_autoneg =3D ETH_LINK_SPEED_FIXED; > } >=20 > 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 =3D 0; > static const char *drivername =3D "xen virtio PMD"; >=20 > static struct rte_eth_link pmd_link =3D { > - .link_speed =3D 10000, > + .link_speed =3D ETH_SPEED_NUM_10G, > .link_duplex =3D ETH_LINK_FULL_DUPLEX, > - .link_status =3D 0 > + .link_status =3D ETH_LINK_DOWN, > + .link_autoneg =3D ETH_LINK_SPEED_FIXED > }; >=20 > static void > diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/c= onfig_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= =3D { > .mac_addr =3D 0, >=20 > .conf =3D { > - .link_speed =3D 0, > - .link_duplex =3D 0, > + .link_speeds =3D 0, > .rxmode =3D { > .mq_mode =3D ETH_MQ_RX_NONE, >=20 > 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) > } >=20 > int > +rte_eth_speed_to_bm_flag(uint32_t speed, int duplex, uint32_t *flag) > +{ > + switch (speed) { > + case ETH_SPEED_NUM_10M: > + *flag =3D (duplex) ? ETH_LINK_SPEED_10M : > + ETH_LINK_SPEED_10M_HD; > + break; > + case ETH_SPEED_NUM_100M: > + *flag =3D (duplex) ? ETH_LINK_SPEED_100M : > + ETH_LINK_SPEED_100M_HD; > + break; > + case ETH_SPEED_NUM_1G: > + *flag =3D ETH_LINK_SPEED_1G; > + break; > + case ETH_SPEED_NUM_2_5G: > + *flag =3D ETH_LINK_SPEED_2_5G; > + break; > + case ETH_SPEED_NUM_5G: > + *flag =3D ETH_LINK_SPEED_5G; > + break; > + case ETH_SPEED_NUM_10G: > + *flag =3D ETH_LINK_SPEED_10G; > + break; > + case ETH_SPEED_NUM_20G: > + *flag =3D ETH_LINK_SPEED_20G; > + break; > + case ETH_SPEED_NUM_25G: > + *flag =3D ETH_LINK_SPEED_25G; > + break; > + case ETH_SPEED_NUM_40G: > + *flag =3D ETH_LINK_SPEED_40G; > + break; > + case ETH_SPEED_NUM_50G: > + *flag =3D ETH_LINK_SPEED_50G; > + break; > + case ETH_SPEED_NUM_56G: > + *flag =3D ETH_LINK_SPEED_56G; > + break; > + case ETH_SPEED_NUM_100G: > + *flag =3D 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 { > }; >=20 > /** > + * 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 s= peed) */ > +#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 po= rt. > */ > 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= */ >=20 > -#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. */ >=20 > /** > * A structure used to configure the ring threshold registers of an RX/T= X > @@ -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 >=20 > /** > - * 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); >=20 > /** > + * Convert a numerical speed in Mbps to a bitmap flag that can be used i= n > + * 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 i= n the > -- > 2.1.4