On 12/16, Lunyuan Cui wrote: >In FreeBSD environment, nic_uio drivers do not support interrupts, >rte_intr_callback_register() will fail to register interrupts. >We can not make link status to change from down to up by interrupt >callback. So we need to wait for the controller to acquire link >when ports start. Through multiple tests, 5s should be enough. > >Fixes: b9bd0f09fa15 ("ethdev: fix link status query") >Cc: sta...@dpdk.org > >Signed-off-by: Lunyuan Cui <lunyuanx....@intel.com> >--- > >v3 changes: >* Hide ifdef inside the function > >v2 changes: >* Put waiting into a separate function to keep start() code clean. >--- > drivers/net/ixgbe/ixgbe_ethdev.c | 36 ++++++++++++++++++++++++++++++++ > 1 file changed, 36 insertions(+) > >diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c >b/drivers/net/ixgbe/ixgbe_ethdev.c >index 2c6fd0f13..d9b0c5b02 100644 >--- a/drivers/net/ixgbe/ixgbe_ethdev.c >+++ b/drivers/net/ixgbe/ixgbe_ethdev.c >@@ -378,6 +378,7 @@ static int ixgbe_dev_udp_tunnel_port_del(struct >rte_eth_dev *dev, > struct rte_eth_udp_tunnel *udp_tunnel); > static int ixgbe_filter_restore(struct rte_eth_dev *dev); > static void ixgbe_l2_tunnel_conf(struct rte_eth_dev *dev); >+static int ixgbe_wait_for_link_up(struct ixgbe_hw *hw); > > /* > * Define VF Stats MACRO for Non "cleared on read" register >@@ -2801,6 +2802,11 @@ ixgbe_dev_start(struct rte_eth_dev *dev) > "please call hierarchy_commit() " > "before starting the port"); > >+ /* wait for the controller to acquire link */ >+ err = ixgbe_wait_for_link_up(hw); >+ if (err) >+ goto error; >+ > /* > * Update link status right before return, because it may > * start link configuration process in a separate thread. >@@ -4114,6 +4120,36 @@ ixgbe_dev_setup_link_alarm_handler(void *param) > intr->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG; > } > >+/* >+ * In freebsd environment, nic_uio drivers do not support interrupts, >+ * rte_intr_callback_register() will fail to register interrupts. >+ * We can not make link status to change from down to up by interrupt >+ * callback. So we need to wait for the controller to acquire link >+ * when ports start. >+ * It returns 0 on link up. >+ */ >+static int >+ixgbe_wait_for_link_up(struct ixgbe_hw *hw) >+{ >+#ifdef RTE_EXEC_ENV_FREEBSD >+ const int nb_iter = 25; >+#else >+ const int nb_iter = 0; >+#endif >+ int err, i, link_up = 0; >+ uint32_t speed = 0; >+ >+ for (i = 0; i < nb_iter; i++) { >+ err = ixgbe_check_link(hw, &speed, &link_up, 0); >+ if (err) >+ return err; >+ if (link_up) >+ return 0; >+ msec_delay(200); >+ } >+ return 0; >+} >+ > /* return 0 means link status changed, -1 means not changed */ > int > ixgbe_dev_link_update_share(struct rte_eth_dev *dev, >-- >2.17.1 >
Acked-by: Xiaolong Ye <xiaolong...@intel.com> Applied to dpdk-next-net-intel, Thanks.