X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fixgbe%2Fixgbe_ethdev.c;h=f8a84c565fd4b7a28df19db27f5210519b3706e0;hb=1256805dd54d;hp=2a8543fd73507258cb2f0ca0b4c2e8d20b094c9a;hpb=efa8c72f1ecf7b02239a0627c482b7ba9af66f40;p=dpdk.git diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index 2a8543fd73..f8a84c565f 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -230,7 +230,8 @@ static int ixgbe_dev_interrupt_action(struct rte_eth_dev *dev); static void ixgbe_dev_interrupt_handler(void *param); static void ixgbe_dev_interrupt_delayed_handler(void *param); static void *ixgbe_dev_setup_link_thread_handler(void *param); -static void ixgbe_dev_cancel_link_thread(struct rte_eth_dev *dev); +static int ixgbe_dev_wait_setup_link_complete(struct rte_eth_dev *dev, + uint32_t timeout_ms); static int ixgbe_add_rar(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, @@ -1196,7 +1197,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) diag = ixgbe_bypass_init_hw(hw); #else diag = ixgbe_init_hw(hw); - hw->mac.autotry_restart = false; #endif /* RTE_LIBRTE_IXGBE_BYPASS */ /* @@ -1307,8 +1307,6 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) /* enable support intr */ ixgbe_enable_intr(eth_dev); - ixgbe_dev_set_link_down(eth_dev); - /* initialize filter info */ memset(filter_info, 0, sizeof(struct ixgbe_filter_info)); @@ -2545,6 +2543,8 @@ ixgbe_flow_ctrl_enable(struct rte_eth_dev *dev, struct ixgbe_hw *hw) int err; uint32_t mflcn; + ixgbe_setup_fc(hw); + err = ixgbe_fc_enable(hw); /* Not negotiated is not an error case */ @@ -2601,7 +2601,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); /* Stop the link setup handler before resetting the HW. */ - ixgbe_dev_cancel_link_thread(dev); + ixgbe_dev_wait_setup_link_complete(dev, 0); /* disable uio/vfio intr/eventfd mapping */ rte_intr_disable(intr_handle); @@ -2888,7 +2888,7 @@ ixgbe_dev_stop(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); - ixgbe_dev_cancel_link_thread(dev); + ixgbe_dev_wait_setup_link_complete(dev, 0); /* disable interrupts */ ixgbe_disable_intr(hw); @@ -4143,36 +4143,32 @@ out: return ret_val; } -/* return 1: setup complete, return 0: setup not complete, and wait timeout*/ +/* + * If @timeout_ms was 0, it means that it will not return until link complete. + * It returns 1 on complete, return 0 on timeout. + */ static int -ixgbe_dev_wait_setup_link_complete(struct rte_eth_dev *dev) +ixgbe_dev_wait_setup_link_complete(struct rte_eth_dev *dev, uint32_t timeout_ms) { -#define DELAY_INTERVAL 100 /* 100ms */ -#define MAX_TIMEOUT 90 /* 9s (90 * 100ms) in total */ +#define WARNING_TIMEOUT 9000 /* 9s in total */ struct ixgbe_adapter *ad = dev->data->dev_private; - int timeout = MAX_TIMEOUT; + uint32_t timeout = timeout_ms ? timeout_ms : WARNING_TIMEOUT; - while (rte_atomic32_read(&ad->link_thread_running) && timeout) { - msec_delay(DELAY_INTERVAL); + while (rte_atomic32_read(&ad->link_thread_running)) { + msec_delay(1); timeout--; - } - - - return !!timeout; -} - -static void -ixgbe_dev_cancel_link_thread(struct rte_eth_dev *dev) -{ - struct ixgbe_adapter *ad = dev->data->dev_private; - void *retval; - if (!ixgbe_dev_wait_setup_link_complete(dev)) { - pthread_cancel(ad->link_thread_tid); - pthread_join(ad->link_thread_tid, &retval); - rte_atomic32_clear(&ad->link_thread_running); - PMD_DRV_LOG(ERR, "Link thread not complete, cancel it!"); + if (timeout_ms) { + if (!timeout) + return 0; + } else if (!timeout) { + /* It will not return until link complete */ + timeout = WARNING_TIMEOUT; + PMD_DRV_LOG(ERR, "IXGBE link thread not complete too long time!"); + } } + + return 1; } static void * @@ -4186,6 +4182,7 @@ ixgbe_dev_setup_link_thread_handler(void *param) u32 speed; bool autoneg = false; + pthread_detach(pthread_self()); speed = hw->phy.autoneg_advertised; if (!speed) ixgbe_get_link_capabilities(hw, &speed, &autoneg); @@ -4262,6 +4259,11 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0) wait = 0; +/* BSD has no interrupt mechanism, so force NIC status synchronization. */ +#ifdef RTE_EXEC_ENV_FREEBSD + wait = 1; +#endif + if (vf) diag = ixgbevf_check_link(hw, &link_speed, &link_up, wait); else @@ -4281,9 +4283,13 @@ ixgbe_dev_link_update_share(struct rte_eth_dev *dev, if (link_up == 0) { if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) { - intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; - if (ixgbe_dev_wait_setup_link_complete(dev) && - rte_atomic32_test_and_set(&ad->link_thread_running)) { + ixgbe_dev_wait_setup_link_complete(dev, 0); + if (rte_atomic32_test_and_set(&ad->link_thread_running)) { + /* To avoid race condition between threads, set + * the IXGBE_FLAG_NEED_LINK_CONFIG flag only + * when there is no link thread running. + */ + intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG; if (rte_ctrl_thread_create(&ad->link_thread_tid, "ixgbe-link-handler", NULL, @@ -5323,7 +5329,7 @@ ixgbevf_dev_start(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); /* Stop the link setup handler before resetting the HW. */ - ixgbe_dev_cancel_link_thread(dev); + ixgbe_dev_wait_setup_link_complete(dev, 0); err = hw->mac.ops.reset_hw(hw); if (err) { @@ -5421,7 +5427,7 @@ ixgbevf_dev_stop(struct rte_eth_dev *dev) PMD_INIT_FUNC_TRACE(); - ixgbe_dev_cancel_link_thread(dev); + ixgbe_dev_wait_setup_link_complete(dev, 0); ixgbevf_intr_disable(dev);