src/dpdk/drivers/net/e1000/igb_ethdev.c
static int
eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
{
	struct e1000_hw *hw =
		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
	struct rte_eth_link link;
	int link_check, count;

	link_check = 0;
	hw->mac.get_link_status = 1;

	/* possible wait-to-complete in up to 9 seconds */
	for (count = 0; count < IGB_LINK_UPDATE_CHECK_TIMEOUT; count ++) {
		/* Read the real link status */
		switch (hw->phy.media_type) {
		case e1000_media_type_copper:
			/* Do the work to read phy */
			e1000_check_for_link(hw);
			link_check = !hw->mac.get_link_status;
			break;

		case e1000_media_type_fiber:
			e1000_check_for_link(hw);
			link_check = (E1000_READ_REG(hw, E1000_STATUS) &
				      E1000_STATUS_LU);
			break;

		case e1000_media_type_internal_serdes:
			e1000_check_for_link(hw);
			link_check = hw->mac.serdes_has_link;
			break;

		/* VF device is type_unknown */
		case e1000_media_type_unknown:
			eth_igbvf_link_update(hw);
			link_check = !hw->mac.get_link_status;
			break;

		default:
			break;
		}
		if (link_check || wait_to_complete == 0)
			break;
		rte_delay_ms(IGB_LINK_UPDATE_CHECK_INTERVAL);
	}
	memset(&link, 0, sizeof(link));

	/* Now we check if a transition has happened */
	if (link_check) {
		uint16_t duplex, speed;
		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
		link.link_duplex = (duplex == FULL_DUPLEX) ?
				ETH_LINK_FULL_DUPLEX :
				ETH_LINK_HALF_DUPLEX;
		link.link_speed = speed;
		link.link_status = ETH_LINK_UP;
		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
				ETH_LINK_SPEED_FIXED);
	} else if (!link_check) {
		link.link_speed = 0;
		link.link_duplex = ETH_LINK_HALF_DUPLEX;
		link.link_status = ETH_LINK_DOWN;
		link.link_autoneg = ETH_LINK_FIXED;
	}

	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
static int
eth_igb_link_update(struct rte_eth_dev *dev, int wait_to_complete)
{
	struct e1000_hw *hw =
		E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
	struct rte_eth_link link;
	int link_check, count;
	link_check = 0;
	hw->mac.get_link_status = 1;
	for (count = 0; count < IGB_LINK_UPDATE_CHECK_TIMEOUT; count ++) {
		switch (hw->phy.media_type) {
		case e1000_media_type_copper:
			e1000_check_for_link(hw);
			link_check = !hw->mac.get_link_status;
			break;
		case e1000_media_type_fiber:
			e1000_check_for_link(hw);
			link_check = (E1000_READ_REG(hw, E1000_STATUS) &
				      E1000_STATUS_LU);
			break;
		case e1000_media_type_internal_serdes:
			e1000_check_for_link(hw);
			link_check = hw->mac.serdes_has_link;
			break;
		case e1000_media_type_unknown:
			eth_igbvf_link_update(hw);
			link_check = !hw->mac.get_link_status;
			break;
		default:
			break;
		}
		if (link_check || wait_to_complete == 0)
			break;
		rte_delay_ms(IGB_LINK_UPDATE_CHECK_INTERVAL);
	}
	memset(&link, 0, sizeof(link));
	if (link_check) {
		uint16_t duplex, speed;
		hw->mac.ops.get_link_up_info(hw, &speed, &duplex);
		link.link_duplex = (duplex == FULL_DUPLEX) ?
				ETH_LINK_FULL_DUPLEX :
				ETH_LINK_HALF_DUPLEX;
		link.link_speed = speed;
		link.link_status = ETH_LINK_UP;
		link.link_autoneg = !(dev->data->dev_conf.link_speeds &
				ETH_LINK_SPEED_FIXED);
	} else if (!link_check) {
		link.link_speed = 0;
		link.link_duplex = ETH_LINK_HALF_DUPLEX;
		link.link_status = ETH_LINK_DOWN;
		link.link_autoneg = ETH_LINK_FIXED;
	}
	return rte_eth_linkstatus_set(dev, &link);
}
static int eth_igb_link_update ( struct rte_eth_dev * dev , int wait_to_complete ) { struct e1000_hw * hw = E1000_DEV_PRIVATE_TO_HW ( dev -> data -> dev_private ) ; struct rte_eth_link link ; int link_check , count ; link_check = 0 ; hw -> mac . get_link_status = 1 ; for ( count = 0 ; count < IGB_LINK_UPDATE_CHECK_TIMEOUT ; count ++ ) { switch ( hw -> phy . media_type ) { case e1000_media_type_copper : e1000_check_for_link ( hw ) ; link_check = ! hw -> mac . get_link_status ; break ; case e1000_media_type_fiber : e1000_check_for_link ( hw ) ; link_check = ( E1000_READ_REG ( hw , E1000_STATUS ) & E1000_STATUS_LU ) ; break ; case e1000_media_type_internal_serdes : e1000_check_for_link ( hw ) ; link_check = hw -> mac . serdes_has_link ; break ; case e1000_media_type_unknown : eth_igbvf_link_update ( hw ) ; link_check = ! hw -> mac . get_link_status ; break ; default : break ; } if ( link_check || wait_to_complete == 0 ) break ; rte_delay_ms ( IGB_LINK_UPDATE_CHECK_INTERVAL ) ; } memset ( & link , 0 , sizeof ( link ) ) ; if ( link_check ) { uint16_t duplex , speed ; hw -> mac . ops . get_link_up_info ( hw , & speed , & duplex ) ; link . link_duplex = ( duplex == FULL_DUPLEX ) ? ETH_LINK_FULL_DUPLEX : ETH_LINK_HALF_DUPLEX ; link . link_speed = speed ; link . link_status = ETH_LINK_UP ; link . link_autoneg = ! ( dev -> data -> dev_conf . link_speeds & ETH_LINK_SPEED_FIXED ) ; } else if ( ! link_check ) { link . link_speed = 0 ; link . link_duplex = ETH_LINK_HALF_DUPLEX ; link . link_status = ETH_LINK_DOWN ; link . link_autoneg = ETH_LINK_FIXED ; } 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
/* possible wait-to-complete in up to 9 seconds */ /* Read the real link status */ /* Do the work to read phy */ /* VF device is type_unknown */ /* Now we check if a transition has happened */