Skip to content

Commit c3d184c

Browse files
agerasymanguy11
authored andcommitted
ice: ethtool: advertise 1000M speeds properly
In current implementation ice_update_phy_type enables all link modes for selected speed. This approach doesn't work for 1000M speeds, because both copper (1000baseT) and optical (1000baseX) standards cannot be enabled at once. Fix this, by adding the function `ice_set_phy_type_from_speed()` for 1000M speeds. Fixes: 48cb27f ("ice: Implement handlers for ethtool PHY/link operations") Signed-off-by: Anatolii Gerasymenko <[email protected]> Tested-by: Gurucharan <[email protected]> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <[email protected]>
1 parent 3578dc9 commit c3d184c

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

drivers/net/ethernet/intel/ice/ice_ethtool.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2189,6 +2189,42 @@ ice_setup_autoneg(struct ice_port_info *p, struct ethtool_link_ksettings *ks,
21892189
return err;
21902190
}
21912191

2192+
/**
2193+
* ice_set_phy_type_from_speed - set phy_types based on speeds
2194+
* and advertised modes
2195+
* @ks: ethtool link ksettings struct
2196+
* @phy_type_low: pointer to the lower part of phy_type
2197+
* @phy_type_high: pointer to the higher part of phy_type
2198+
* @adv_link_speed: targeted link speeds bitmap
2199+
*/
2200+
static void
2201+
ice_set_phy_type_from_speed(const struct ethtool_link_ksettings *ks,
2202+
u64 *phy_type_low, u64 *phy_type_high,
2203+
u16 adv_link_speed)
2204+
{
2205+
/* Handle 1000M speed in a special way because ice_update_phy_type
2206+
* enables all link modes, but having mixed copper and optical
2207+
* standards is not supported.
2208+
*/
2209+
adv_link_speed &= ~ICE_AQ_LINK_SPEED_1000MB;
2210+
2211+
if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2212+
1000baseT_Full))
2213+
*phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_T |
2214+
ICE_PHY_TYPE_LOW_1G_SGMII;
2215+
2216+
if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2217+
1000baseKX_Full))
2218+
*phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_KX;
2219+
2220+
if (ethtool_link_ksettings_test_link_mode(ks, advertising,
2221+
1000baseX_Full))
2222+
*phy_type_low |= ICE_PHY_TYPE_LOW_1000BASE_SX |
2223+
ICE_PHY_TYPE_LOW_1000BASE_LX;
2224+
2225+
ice_update_phy_type(phy_type_low, phy_type_high, adv_link_speed);
2226+
}
2227+
21922228
/**
21932229
* ice_set_link_ksettings - Set Speed and Duplex
21942230
* @netdev: network interface device structure
@@ -2320,7 +2356,8 @@ ice_set_link_ksettings(struct net_device *netdev,
23202356
adv_link_speed = curr_link_speed;
23212357

23222358
/* Convert the advertise link speeds to their corresponded PHY_TYPE */
2323-
ice_update_phy_type(&phy_type_low, &phy_type_high, adv_link_speed);
2359+
ice_set_phy_type_from_speed(ks, &phy_type_low, &phy_type_high,
2360+
adv_link_speed);
23242361

23252362
if (!autoneg_changed && adv_link_speed == curr_link_speed) {
23262363
netdev_info(netdev, "Nothing changed, exiting without setting anything.\n");

0 commit comments

Comments
 (0)