X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fi40e%2Fi40e_ethdev.c;h=7a94663096c4e842aa1f0d7465882e7285ad53a1;hb=ca7e599d4506f3d6b89dd846c901d09d46ea593c;hp=f94ad87f374419f5b7307cbfa2eee1655a65ba69;hpb=cb326b1f5b49da60d6bb1880e35e12d36504e629;p=dpdk.git diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index f94ad87f37..7a94663096 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -1407,15 +1407,58 @@ i40e_parse_link_speeds(uint16_t link_speeds) } static int -i40e_phy_conf_link(__rte_unused struct i40e_hw *hw, - __rte_unused uint8_t abilities, - __rte_unused uint8_t force_speed) -{ - /* Skip any phy config on both 10G and 40G interfaces, as a workaround - * for the link control limitation of that all link control should be - * handled by firmware. It should follow up if link control will be - * opened to software driver in future firmware versions. - */ +i40e_phy_conf_link(struct i40e_hw *hw, + uint8_t abilities, + uint8_t force_speed) +{ + enum i40e_status_code status; + struct i40e_aq_get_phy_abilities_resp phy_ab; + struct i40e_aq_set_phy_config phy_conf; + const uint8_t mask = I40E_AQ_PHY_FLAG_PAUSE_TX | + I40E_AQ_PHY_FLAG_PAUSE_RX | + I40E_AQ_PHY_FLAG_PAUSE_RX | + I40E_AQ_PHY_FLAG_LOW_POWER; + const uint8_t advt = I40E_LINK_SPEED_40GB | + I40E_LINK_SPEED_10GB | + I40E_LINK_SPEED_1GB | + I40E_LINK_SPEED_100MB; + int ret = -ENOTSUP; + + + status = i40e_aq_get_phy_capabilities(hw, false, false, &phy_ab, + NULL); + if (status) + return ret; + + memset(&phy_conf, 0, sizeof(phy_conf)); + + /* bits 0-2 use the values from get_phy_abilities_resp */ + abilities &= ~mask; + abilities |= phy_ab.abilities & mask; + + /* update ablities and speed */ + if (abilities & I40E_AQ_PHY_AN_ENABLED) + phy_conf.link_speed = advt; + else + phy_conf.link_speed = force_speed; + + phy_conf.abilities = abilities; + + /* use get_phy_abilities_resp value for the rest */ + phy_conf.phy_type = phy_ab.phy_type; + phy_conf.eee_capability = phy_ab.eee_capability; + phy_conf.eeer = phy_ab.eeer_val; + phy_conf.low_power_ctrl = phy_ab.d3_lpan; + + PMD_DRV_LOG(DEBUG, "\tCurrent: abilities %x, link_speed %x", + phy_ab.abilities, phy_ab.link_speed); + PMD_DRV_LOG(DEBUG, "\tConfig: abilities %x, link_speed %x", + phy_conf.abilities, phy_conf.link_speed); + + status = i40e_aq_set_phy_config(hw, &phy_conf, NULL); + if (status) + return ret; + return I40E_SUCCESS; } @@ -1431,8 +1474,13 @@ i40e_apply_link_speed(struct rte_eth_dev *dev) abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK; if (!(conf->link_speeds & ETH_LINK_SPEED_FIXED)) abilities |= I40E_AQ_PHY_AN_ENABLED; - else - abilities |= I40E_AQ_PHY_LINK_ENABLED; + abilities |= I40E_AQ_PHY_LINK_ENABLED; + + /* Skip changing speed on 40G interfaces, FW does not support */ + if (i40e_is_40G_device(hw->device_id)) { + speed = I40E_LINK_SPEED_UNKNOWN; + abilities |= I40E_AQ_PHY_AN_ENABLED; + } return i40e_phy_conf_link(hw, abilities, speed); } @@ -1742,7 +1790,7 @@ i40e_dev_set_link_up(struct rte_eth_dev *dev) * Set device link down. */ static int -i40e_dev_set_link_down(__rte_unused struct rte_eth_dev *dev) +i40e_dev_set_link_down(struct rte_eth_dev *dev) { uint8_t speed = I40E_LINK_SPEED_UNKNOWN; uint8_t abilities = I40E_AQ_PHY_ENABLE_ATOMIC_LINK;