src/dpdk/drivers/net/ixgbe/ixgbe_ethdev.c
int
ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
			    int wait_to_complete, int vf)
{
	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
	struct ixgbe_adapter *ad = dev->data->dev_private;
	struct rte_eth_link link;
	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
	struct ixgbe_interrupt *intr =
		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
	bool link_up;
	int diag;
	int wait = 1;
	u32 esdp_reg;

	memset(&link, 0, sizeof(link));
	link.link_status = ETH_LINK_DOWN;
	link.link_speed = ETH_SPEED_NUM_NONE;
	link.link_duplex = ETH_LINK_HALF_DUPLEX;
	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
			ETH_LINK_SPEED_FIXED);

	hw->mac.get_link_status = true;

	if (intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG)
		return rte_eth_linkstatus_set(dev, &link);

	/* check if it needs to wait to complete, if lsc interrupt is enabled */
	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
		diag = ixgbe_check_link(hw, &link_speed, &link_up, wait);

	if (diag != 0) {
		link.link_speed = ETH_SPEED_NUM_100M;
		link.link_duplex = ETH_LINK_FULL_DUPLEX;
		return rte_eth_linkstatus_set(dev, &link);
	}

	if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
		esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
		if ((esdp_reg & IXGBE_ESDP_SDP3))
			link_up = 0;
	}

	if (link_up == 0) {
		if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
			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,
					ixgbe_dev_setup_link_thread_handler,
					dev) < 0) {
					PMD_DRV_LOG(ERR,
						"Create link thread failed!");
					rte_atomic32_clear(&ad->link_thread_running);
				}
			} else {
				PMD_DRV_LOG(ERR,
					"Other link thread is running now!");
			}
		}
		return rte_eth_linkstatus_set(dev, &link);
	}

	link.link_status = ETH_LINK_UP;
	link.link_duplex = ETH_LINK_FULL_DUPLEX;

	switch (link_speed) {
	default:
	case IXGBE_LINK_SPEED_UNKNOWN:
		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
		break;

	case IXGBE_LINK_SPEED_10_FULL:
		link.link_speed = ETH_SPEED_NUM_10M;
		break;

	case IXGBE_LINK_SPEED_100_FULL:
		link.link_speed = ETH_SPEED_NUM_100M;
		break;

	case IXGBE_LINK_SPEED_1GB_FULL:
		link.link_speed = ETH_SPEED_NUM_1G;
		break;

	case IXGBE_LINK_SPEED_2_5GB_FULL:
		link.link_speed = ETH_SPEED_NUM_2_5G;
		break;

	case IXGBE_LINK_SPEED_5GB_FULL:
		link.link_speed = ETH_SPEED_NUM_5G;
		break;

	case IXGBE_LINK_SPEED_10GB_FULL:
		link.link_speed = ETH_SPEED_NUM_10G;
		break;
	}

	return rte_eth_linkstatus_set(dev, &link);
}
/* return 0 means link status changed, -1 means not changed */
return 0 means link status changed, -1 means not changed
return 0 means link status changed - 1 means not changed
int
ixgbe_dev_link_update_share(struct rte_eth_dev *dev,
			    int wait_to_complete, int vf)
{
	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
	struct ixgbe_adapter *ad = dev->data->dev_private;
	struct rte_eth_link link;
	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
	struct ixgbe_interrupt *intr =
		IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
	bool link_up;
	int diag;
	int wait = 1;
	u32 esdp_reg;
	memset(&link, 0, sizeof(link));
	link.link_status = ETH_LINK_DOWN;
	link.link_speed = ETH_SPEED_NUM_NONE;
	link.link_duplex = ETH_LINK_HALF_DUPLEX;
	link.link_autoneg = !(dev->data->dev_conf.link_speeds &
			ETH_LINK_SPEED_FIXED);
	hw->mac.get_link_status = true;
	if (intr->flags & IXGBE_FLAG_NEED_LINK_CONFIG)
		return rte_eth_linkstatus_set(dev, &link);
	if (wait_to_complete == 0 || dev->data->dev_conf.intr_conf.lsc != 0)
		wait = 0;
#ifdef RTE_EXEC_ENV_FREEBSD
	wait = 1;
#endif
	if (vf)
		diag = ixgbevf_check_link(hw, &link_speed, &link_up, wait);
	else
		diag = ixgbe_check_link(hw, &link_speed, &link_up, wait);
	if (diag != 0) {
		link.link_speed = ETH_SPEED_NUM_100M;
		link.link_duplex = ETH_LINK_FULL_DUPLEX;
		return rte_eth_linkstatus_set(dev, &link);
	}
	if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
		esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
		if ((esdp_reg & IXGBE_ESDP_SDP3))
			link_up = 0;
	}
	if (link_up == 0) {
		if (ixgbe_get_media_type(hw) == ixgbe_media_type_fiber) {
			ixgbe_dev_wait_setup_link_complete(dev, 0);
			if (rte_atomic32_test_and_set(&ad->link_thread_running)) {
				intr->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
				if (rte_ctrl_thread_create(&ad->link_thread_tid,
					"ixgbe-link-handler",
					NULL,
					ixgbe_dev_setup_link_thread_handler,
					dev) < 0) {
					PMD_DRV_LOG(ERR,
						"Create link thread failed!");
					rte_atomic32_clear(&ad->link_thread_running);
				}
			} else {
				PMD_DRV_LOG(ERR,
					"Other link thread is running now!");
			}
		}
		return rte_eth_linkstatus_set(dev, &link);
	}
	link.link_status = ETH_LINK_UP;
	link.link_duplex = ETH_LINK_FULL_DUPLEX;
	switch (link_speed) {
	default:
	case IXGBE_LINK_SPEED_UNKNOWN:
		link.link_speed = ETH_SPEED_NUM_UNKNOWN;
		break;
	case IXGBE_LINK_SPEED_10_FULL:
		link.link_speed = ETH_SPEED_NUM_10M;
		break;
	case IXGBE_LINK_SPEED_100_FULL:
		link.link_speed = ETH_SPEED_NUM_100M;
		break;
	case IXGBE_LINK_SPEED_1GB_FULL:
		link.link_speed = ETH_SPEED_NUM_1G;
		break;
	case IXGBE_LINK_SPEED_2_5GB_FULL:
		link.link_speed = ETH_SPEED_NUM_2_5G;
		break;
	case IXGBE_LINK_SPEED_5GB_FULL:
		link.link_speed = ETH_SPEED_NUM_5G;
		break;
	case IXGBE_LINK_SPEED_10GB_FULL:
		link.link_speed = ETH_SPEED_NUM_10G;
		break;
	}
	return rte_eth_linkstatus_set(dev, &link);
}
int ixgbe_dev_link_update_share ( struct rte_eth_dev * dev , int wait_to_complete , int vf ) { struct ixgbe_hw * hw = IXGBE_DEV_PRIVATE_TO_HW ( dev -> data -> dev_private ) ; struct ixgbe_adapter * ad = dev -> data -> dev_private ; struct rte_eth_link link ; ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN ; struct ixgbe_interrupt * intr = IXGBE_DEV_PRIVATE_TO_INTR ( dev -> data -> dev_private ) ; bool link_up ; int diag ; int wait = 1 ; u32 esdp_reg ; memset ( & link , 0 , sizeof ( link ) ) ; link . link_status = ETH_LINK_DOWN ; link . link_speed = ETH_SPEED_NUM_NONE ; link . link_duplex = ETH_LINK_HALF_DUPLEX ; link . link_autoneg = ! ( dev -> data -> dev_conf . link_speeds & ETH_LINK_SPEED_FIXED ) ; hw -> mac . get_link_status = true ; if ( intr -> flags & IXGBE_FLAG_NEED_LINK_CONFIG ) return rte_eth_linkstatus_set ( dev , & link ) ; if ( wait_to_complete == 0 || dev -> data -> dev_conf . intr_conf . lsc != 0 ) wait = 0 ; #ifdef RTE_EXEC_ENV_FREEBSD wait = 1 ; #endif if ( vf ) diag = ixgbevf_check_link ( hw , & link_speed , & link_up , wait ) ; else diag = ixgbe_check_link ( hw , & link_speed , & link_up , wait ) ; if ( diag != 0 ) { link . link_speed = ETH_SPEED_NUM_100M ; link . link_duplex = ETH_LINK_FULL_DUPLEX ; return rte_eth_linkstatus_set ( dev , & link ) ; } if ( ixgbe_get_media_type ( hw ) == ixgbe_media_type_fiber ) { esdp_reg = IXGBE_READ_REG ( hw , IXGBE_ESDP ) ; if ( ( esdp_reg & IXGBE_ESDP_SDP3 ) ) link_up = 0 ; } if ( link_up == 0 ) { if ( ixgbe_get_media_type ( hw ) == ixgbe_media_type_fiber ) { ixgbe_dev_wait_setup_link_complete ( dev , 0 ) ; if ( rte_atomic32_test_and_set ( & ad -> link_thread_running ) ) { intr -> flags |= IXGBE_FLAG_NEED_LINK_CONFIG ; if ( rte_ctrl_thread_create ( & ad -> link_thread_tid , " " , NULL , ixgbe_dev_setup_link_thread_handler , dev ) < 0 ) { PMD_DRV_LOG ( ERR , " " ) ; rte_atomic32_clear ( & ad -> link_thread_running ) ; } } else { PMD_DRV_LOG ( ERR , " " ) ; } } return rte_eth_linkstatus_set ( dev , & link ) ; } link . link_status = ETH_LINK_UP ; link . link_duplex = ETH_LINK_FULL_DUPLEX ; switch ( link_speed ) { default : case IXGBE_LINK_SPEED_UNKNOWN : link . link_speed = ETH_SPEED_NUM_UNKNOWN ; break ; case IXGBE_LINK_SPEED_10_FULL : link . link_speed = ETH_SPEED_NUM_10M ; break ; case IXGBE_LINK_SPEED_100_FULL : link . link_speed = ETH_SPEED_NUM_100M ; break ; case IXGBE_LINK_SPEED_1GB_FULL : link . link_speed = ETH_SPEED_NUM_1G ; break ; case IXGBE_LINK_SPEED_2_5GB_FULL : link . link_speed = ETH_SPEED_NUM_2_5G ; break ; case IXGBE_LINK_SPEED_5GB_FULL : link . link_speed = ETH_SPEED_NUM_5G ; break ; case IXGBE_LINK_SPEED_10GB_FULL : link . link_speed = ETH_SPEED_NUM_10G ; break ; } return rte_eth_linkstatus_set ( dev , & link ) ; }
return 0 means link status changed, -1 means not changed
return 0 means link status changed - 1 means not changed
/* check if it needs to wait to complete, if lsc interrupt is enabled */ /* BSD has no interrupt mechanism, so force NIC status synchronization. */ /* To avoid race condition between threads, set
				 * the IXGBE_FLAG_NEED_LINK_CONFIG flag only
				 * when there is no link thread running.
				 */