forked from mirrors/linux
		
	net: ethernet: Convert phydev advertize and supported from u32 to link mode
There are a few MAC/PHYs combinations which now support > 1Gbps. These may need to make use of link modes with bits > 31. Thus their supported PHY features or advertised features cannot be implemented using the current bitmap in a u32. Convert to using a linkmode bitmap, which can support all the currently devices link modes, and is future proof as more modes are added. Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									899a3cbbf7
								
							
						
					
					
						commit
						3c1bcc8614
					
				
					 39 changed files with 535 additions and 329 deletions
				
			
		|  | @ -658,7 +658,8 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int port, | ||||||
| 			if (phydev->asym_pause) | 			if (phydev->asym_pause) | ||||||
| 				rmt_adv |= LPA_PAUSE_ASYM; | 				rmt_adv |= LPA_PAUSE_ASYM; | ||||||
| 
 | 
 | ||||||
| 			lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising); | 			lcl_adv = linkmode_adv_to_lcl_adv_t( | ||||||
|  | 				phydev->advertising); | ||||||
| 			flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | 			flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||||||
| 
 | 
 | ||||||
| 			if (flowctrl & FLOW_CTRL_TX) | 			if (flowctrl & FLOW_CTRL_TX) | ||||||
|  |  | ||||||
|  | @ -1283,7 +1283,7 @@ static int greth_mdio_probe(struct net_device *dev) | ||||||
| 	else | 	else | ||||||
| 		phy_set_max_speed(phy, SPEED_100); | 		phy_set_max_speed(phy, SPEED_100); | ||||||
| 
 | 
 | ||||||
| 	phy->advertising = phy->supported; | 	linkmode_copy(phy->advertising, phy->supported); | ||||||
| 
 | 
 | ||||||
| 	greth->link = 0; | 	greth->link = 0; | ||||||
| 	greth->speed = 0; | 	greth->speed = 0; | ||||||
|  |  | ||||||
|  | @ -857,6 +857,7 @@ static void xgbe_phy_free_phy_device(struct xgbe_prv_data *pdata) | ||||||
| 
 | 
 | ||||||
| static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) | static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; | ||||||
| 	struct xgbe_phy_data *phy_data = pdata->phy_data; | 	struct xgbe_phy_data *phy_data = pdata->phy_data; | ||||||
| 	unsigned int phy_id = phy_data->phydev->phy_id; | 	unsigned int phy_id = phy_data->phydev->phy_id; | ||||||
| 
 | 
 | ||||||
|  | @ -878,9 +879,15 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) | ||||||
| 	phy_write(phy_data->phydev, 0x04, 0x0d01); | 	phy_write(phy_data->phydev, 0x04, 0x0d01); | ||||||
| 	phy_write(phy_data->phydev, 0x00, 0x9140); | 	phy_write(phy_data->phydev, 0x00, 0x9140); | ||||||
| 
 | 
 | ||||||
| 	phy_data->phydev->supported = PHY_10BT_FEATURES | | 	linkmode_set_bit_array(phy_10_100_features_array, | ||||||
| 				      PHY_100BT_FEATURES | | 			       ARRAY_SIZE(phy_10_100_features_array), | ||||||
| 				      PHY_1000BT_FEATURES; | 			       supported); | ||||||
|  | 	linkmode_set_bit_array(phy_gbit_features_array, | ||||||
|  | 			       ARRAY_SIZE(phy_gbit_features_array), | ||||||
|  | 			       supported); | ||||||
|  | 
 | ||||||
|  | 	linkmode_copy(phy_data->phydev->supported, supported); | ||||||
|  | 
 | ||||||
| 	phy_support_asym_pause(phy_data->phydev); | 	phy_support_asym_pause(phy_data->phydev); | ||||||
| 
 | 
 | ||||||
| 	netif_dbg(pdata, drv, pdata->netdev, | 	netif_dbg(pdata, drv, pdata->netdev, | ||||||
|  | @ -891,6 +898,7 @@ static bool xgbe_phy_finisar_phy_quirks(struct xgbe_prv_data *pdata) | ||||||
| 
 | 
 | ||||||
| static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) | static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; | ||||||
| 	struct xgbe_phy_data *phy_data = pdata->phy_data; | 	struct xgbe_phy_data *phy_data = pdata->phy_data; | ||||||
| 	struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; | 	struct xgbe_sfp_eeprom *sfp_eeprom = &phy_data->sfp_eeprom; | ||||||
| 	unsigned int phy_id = phy_data->phydev->phy_id; | 	unsigned int phy_id = phy_data->phydev->phy_id; | ||||||
|  | @ -951,9 +959,13 @@ static bool xgbe_phy_belfuse_phy_quirks(struct xgbe_prv_data *pdata) | ||||||
| 	reg = phy_read(phy_data->phydev, 0x00); | 	reg = phy_read(phy_data->phydev, 0x00); | ||||||
| 	phy_write(phy_data->phydev, 0x00, reg & ~0x00800); | 	phy_write(phy_data->phydev, 0x00, reg & ~0x00800); | ||||||
| 
 | 
 | ||||||
| 	phy_data->phydev->supported = (PHY_10BT_FEATURES | | 	linkmode_set_bit_array(phy_10_100_features_array, | ||||||
| 				       PHY_100BT_FEATURES | | 			       ARRAY_SIZE(phy_10_100_features_array), | ||||||
| 				       PHY_1000BT_FEATURES); | 			       supported); | ||||||
|  | 	linkmode_set_bit_array(phy_gbit_features_array, | ||||||
|  | 			       ARRAY_SIZE(phy_gbit_features_array), | ||||||
|  | 			       supported); | ||||||
|  | 	linkmode_copy(phy_data->phydev->supported, supported); | ||||||
| 	phy_support_asym_pause(phy_data->phydev); | 	phy_support_asym_pause(phy_data->phydev); | ||||||
| 
 | 
 | ||||||
| 	netif_dbg(pdata, drv, pdata->netdev, | 	netif_dbg(pdata, drv, pdata->netdev, | ||||||
|  | @ -976,7 +988,6 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata) | ||||||
| 	struct ethtool_link_ksettings *lks = &pdata->phy.lks; | 	struct ethtool_link_ksettings *lks = &pdata->phy.lks; | ||||||
| 	struct xgbe_phy_data *phy_data = pdata->phy_data; | 	struct xgbe_phy_data *phy_data = pdata->phy_data; | ||||||
| 	struct phy_device *phydev; | 	struct phy_device *phydev; | ||||||
| 	u32 advertising; |  | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	/* If we already have a PHY, just return */ | 	/* If we already have a PHY, just return */ | ||||||
|  | @ -1036,9 +1047,8 @@ static int xgbe_phy_find_phy_device(struct xgbe_prv_data *pdata) | ||||||
| 
 | 
 | ||||||
| 	xgbe_phy_external_phy_quirks(pdata); | 	xgbe_phy_external_phy_quirks(pdata); | ||||||
| 
 | 
 | ||||||
| 	ethtool_convert_link_mode_to_legacy_u32(&advertising, | 	linkmode_and(phydev->advertising, phydev->advertising, | ||||||
| 						lks->link_modes.advertising); | 		     lks->link_modes.advertising); | ||||||
| 	phydev->advertising &= advertising; |  | ||||||
| 
 | 
 | ||||||
| 	phy_start_aneg(phy_data->phydev); | 	phy_start_aneg(phy_data->phydev); | ||||||
| 
 | 
 | ||||||
|  | @ -1497,7 +1507,7 @@ static void xgbe_phy_phydev_flowctrl(struct xgbe_prv_data *pdata) | ||||||
| 	if (!phy_data->phydev) | 	if (!phy_data->phydev) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	lcl_adv = ethtool_adv_to_lcl_adv_t(phy_data->phydev->advertising); | 	lcl_adv = linkmode_adv_to_lcl_adv_t(phy_data->phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	if (phy_data->phydev->pause) { | 	if (phy_data->phydev->pause) { | ||||||
| 		XGBE_SET_LP_ADV(lks, Pause); | 		XGBE_SET_LP_ADV(lks, Pause); | ||||||
|  | @ -1815,7 +1825,6 @@ static int xgbe_phy_an_config(struct xgbe_prv_data *pdata) | ||||||
| { | { | ||||||
| 	struct ethtool_link_ksettings *lks = &pdata->phy.lks; | 	struct ethtool_link_ksettings *lks = &pdata->phy.lks; | ||||||
| 	struct xgbe_phy_data *phy_data = pdata->phy_data; | 	struct xgbe_phy_data *phy_data = pdata->phy_data; | ||||||
| 	u32 advertising; |  | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	ret = xgbe_phy_find_phy_device(pdata); | 	ret = xgbe_phy_find_phy_device(pdata); | ||||||
|  | @ -1825,12 +1834,10 @@ static int xgbe_phy_an_config(struct xgbe_prv_data *pdata) | ||||||
| 	if (!phy_data->phydev) | 	if (!phy_data->phydev) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	ethtool_convert_link_mode_to_legacy_u32(&advertising, |  | ||||||
| 						lks->link_modes.advertising); |  | ||||||
| 
 |  | ||||||
| 	phy_data->phydev->autoneg = pdata->phy.autoneg; | 	phy_data->phydev->autoneg = pdata->phy.autoneg; | ||||||
| 	phy_data->phydev->advertising = phy_data->phydev->supported & | 	linkmode_and(phy_data->phydev->advertising, | ||||||
| 					advertising; | 		     phy_data->phydev->supported, | ||||||
|  | 		     lks->link_modes.advertising); | ||||||
| 
 | 
 | ||||||
| 	if (pdata->phy.autoneg != AUTONEG_ENABLE) { | 	if (pdata->phy.autoneg != AUTONEG_ENABLE) { | ||||||
| 		phy_data->phydev->speed = pdata->phy.speed; | 		phy_data->phydev->speed = pdata->phy.speed; | ||||||
|  |  | ||||||
|  | @ -109,6 +109,7 @@ void xge_mdio_remove(struct net_device *ndev) | ||||||
| 
 | 
 | ||||||
| int xge_mdio_config(struct net_device *ndev) | int xge_mdio_config(struct net_device *ndev) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
| 	struct xge_pdata *pdata = netdev_priv(ndev); | 	struct xge_pdata *pdata = netdev_priv(ndev); | ||||||
| 	struct device *dev = &pdata->pdev->dev; | 	struct device *dev = &pdata->pdev->dev; | ||||||
| 	struct mii_bus *mdio_bus; | 	struct mii_bus *mdio_bus; | ||||||
|  | @ -148,16 +149,17 @@ int xge_mdio_config(struct net_device *ndev) | ||||||
| 		goto err; | 		goto err; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	phydev->supported &= ~(SUPPORTED_10baseT_Half | | 	linkmode_set_bit_array(phy_10_100_features_array, | ||||||
| 			       SUPPORTED_10baseT_Full | | 			       ARRAY_SIZE(phy_10_100_features_array), | ||||||
| 			       SUPPORTED_100baseT_Half | | 			       mask); | ||||||
| 			       SUPPORTED_100baseT_Full | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, mask); | ||||||
| 			       SUPPORTED_1000baseT_Half | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_AUI_BIT, mask); | ||||||
| 			       SUPPORTED_AUI | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, mask); | ||||||
| 			       SUPPORTED_MII | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, mask); | ||||||
| 			       SUPPORTED_FIBRE | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_BNC_BIT, mask); | ||||||
| 			       SUPPORTED_BNC); | 
 | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_andnot(phydev->supported, phydev->supported, mask); | ||||||
|  | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 	pdata->phy_speed = SPEED_UNKNOWN; | 	pdata->phy_speed = SPEED_UNKNOWN; | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -432,7 +432,8 @@ static int arc_emac_open(struct net_device *ndev) | ||||||
| 	phy_dev->autoneg = AUTONEG_ENABLE; | 	phy_dev->autoneg = AUTONEG_ENABLE; | ||||||
| 	phy_dev->speed = 0; | 	phy_dev->speed = 0; | ||||||
| 	phy_dev->duplex = 0; | 	phy_dev->duplex = 0; | ||||||
| 	phy_dev->advertising &= phy_dev->supported; | 	linkmode_and(phy_dev->advertising, phy_dev->advertising, | ||||||
|  | 		     phy_dev->supported); | ||||||
| 
 | 
 | ||||||
| 	priv->last_rx_bd = 0; | 	priv->last_rx_bd = 0; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2248,6 +2248,7 @@ static void b44_adjust_link(struct net_device *dev) | ||||||
| 
 | 
 | ||||||
| static int b44_register_phy_one(struct b44 *bp) | static int b44_register_phy_one(struct b44 *bp) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
| 	struct mii_bus *mii_bus; | 	struct mii_bus *mii_bus; | ||||||
| 	struct ssb_device *sdev = bp->sdev; | 	struct ssb_device *sdev = bp->sdev; | ||||||
| 	struct phy_device *phydev; | 	struct phy_device *phydev; | ||||||
|  | @ -2303,11 +2304,12 @@ static int b44_register_phy_one(struct b44 *bp) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* mask with MAC supported features */ | 	/* mask with MAC supported features */ | ||||||
| 	phydev->supported &= (SUPPORTED_100baseT_Half | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); | ||||||
| 			      SUPPORTED_100baseT_Full | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask); | ||||||
| 			      SUPPORTED_Autoneg | | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask); | ||||||
| 			      SUPPORTED_MII); | 	linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, mask); | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_and(phydev->supported, phydev->supported, mask); | ||||||
|  | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	bp->old_link = 0; | 	bp->old_link = 0; | ||||||
| 	bp->phy_addr = phydev->mdio.addr; | 	bp->phy_addr = phydev->mdio.addr; | ||||||
|  |  | ||||||
|  | @ -226,7 +226,8 @@ int bcmgenet_mii_config(struct net_device *dev, bool init) | ||||||
| 		 * capabilities, use that knowledge to also configure the | 		 * capabilities, use that knowledge to also configure the | ||||||
| 		 * Reverse MII interface correctly. | 		 * Reverse MII interface correctly. | ||||||
| 		 */ | 		 */ | ||||||
| 		if (dev->phydev->supported & PHY_1000BT_FEATURES) | 		if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				      dev->phydev->supported)) | ||||||
| 			port_ctrl = PORT_MODE_EXT_RVMII_50; | 			port_ctrl = PORT_MODE_EXT_RVMII_50; | ||||||
| 		else | 		else | ||||||
| 			port_ctrl = PORT_MODE_EXT_RVMII_25; | 			port_ctrl = PORT_MODE_EXT_RVMII_25; | ||||||
|  | @ -317,7 +318,7 @@ int bcmgenet_mii_probe(struct net_device *dev) | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	/* The internal PHY has its link interrupts routed to the
 | 	/* The internal PHY has its link interrupts routed to the
 | ||||||
| 	 * Ethernet MAC ISRs. On GENETv5 there is a hardware issue | 	 * Ethernet MAC ISRs. On GENETv5 there is a hardware issue | ||||||
|  |  | ||||||
|  | @ -2157,7 +2157,8 @@ static void tg3_phy_start(struct tg3 *tp) | ||||||
| 		phydev->speed = tp->link_config.speed; | 		phydev->speed = tp->link_config.speed; | ||||||
| 		phydev->duplex = tp->link_config.duplex; | 		phydev->duplex = tp->link_config.duplex; | ||||||
| 		phydev->autoneg = tp->link_config.autoneg; | 		phydev->autoneg = tp->link_config.autoneg; | ||||||
| 		phydev->advertising = tp->link_config.advertising; | 		ethtool_convert_legacy_u32_to_link_mode( | ||||||
|  | 			phydev->advertising, tp->link_config.advertising); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	phy_start(phydev); | 	phy_start(phydev); | ||||||
|  | @ -4057,8 +4058,9 @@ static int tg3_power_down_prepare(struct tg3 *tp) | ||||||
| 		do_low_power = false; | 		do_low_power = false; | ||||||
| 		if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) && | 		if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) && | ||||||
| 		    !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { | 		    !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) { | ||||||
|  | 			__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising) = { 0, }; | ||||||
| 			struct phy_device *phydev; | 			struct phy_device *phydev; | ||||||
| 			u32 phyid, advertising; | 			u32 phyid; | ||||||
| 
 | 
 | ||||||
| 			phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr); | 			phydev = mdiobus_get_phy(tp->mdio_bus, tp->phy_addr); | ||||||
| 
 | 
 | ||||||
|  | @ -4067,25 +4069,33 @@ static int tg3_power_down_prepare(struct tg3 *tp) | ||||||
| 			tp->link_config.speed = phydev->speed; | 			tp->link_config.speed = phydev->speed; | ||||||
| 			tp->link_config.duplex = phydev->duplex; | 			tp->link_config.duplex = phydev->duplex; | ||||||
| 			tp->link_config.autoneg = phydev->autoneg; | 			tp->link_config.autoneg = phydev->autoneg; | ||||||
| 			tp->link_config.advertising = phydev->advertising; | 			ethtool_convert_link_mode_to_legacy_u32( | ||||||
|  | 				&tp->link_config.advertising, | ||||||
|  | 				phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 			advertising = ADVERTISED_TP | | 			linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, advertising); | ||||||
| 				      ADVERTISED_Pause | | 			linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
| 				      ADVERTISED_Autoneg | | 					 advertising); | ||||||
| 				      ADVERTISED_10baseT_Half; | 			linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | 					 advertising); | ||||||
|  | 			linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, | ||||||
|  | 					 advertising); | ||||||
| 
 | 
 | ||||||
| 			if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) { | 			if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) { | ||||||
| 				if (tg3_flag(tp, WOL_SPEED_100MB)) | 				if (tg3_flag(tp, WOL_SPEED_100MB)) { | ||||||
| 					advertising |= | 					linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||||||
| 						ADVERTISED_100baseT_Half | | 							 advertising); | ||||||
| 						ADVERTISED_100baseT_Full | | 					linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
| 						ADVERTISED_10baseT_Full; | 							 advertising); | ||||||
| 				else | 					linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||||||
| 					advertising |= ADVERTISED_10baseT_Full; | 							 advertising); | ||||||
|  | 				} else { | ||||||
|  | 					linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||||||
|  | 							 advertising); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			phydev->advertising = advertising; | 			linkmode_copy(phydev->advertising, advertising); | ||||||
| 
 |  | ||||||
| 			phy_start_aneg(phydev); | 			phy_start_aneg(phydev); | ||||||
| 
 | 
 | ||||||
| 			phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask; | 			phyid = phydev->drv->phy_id & phydev->drv->phy_id_mask; | ||||||
|  |  | ||||||
|  | @ -1080,8 +1080,11 @@ static int octeon_mgmt_open(struct net_device *netdev) | ||||||
| 	/* Set the mode of the interface, RGMII/MII. */ | 	/* Set the mode of the interface, RGMII/MII. */ | ||||||
| 	if (OCTEON_IS_MODEL(OCTEON_CN6XXX) && netdev->phydev) { | 	if (OCTEON_IS_MODEL(OCTEON_CN6XXX) && netdev->phydev) { | ||||||
| 		union cvmx_agl_prtx_ctl agl_prtx_ctl; | 		union cvmx_agl_prtx_ctl agl_prtx_ctl; | ||||||
| 		int rgmii_mode = (netdev->phydev->supported & | 		int rgmii_mode = | ||||||
| 				  (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)) != 0; | 			(linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
|  | 					   netdev->phydev->supported) | | ||||||
|  | 			 linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 					   netdev->phydev->supported)) != 0; | ||||||
| 
 | 
 | ||||||
| 		agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl); | 		agl_prtx_ctl.u64 = cvmx_read_csr(p->agl_prt_ctl); | ||||||
| 		agl_prtx_ctl.s.mode = rgmii_mode ? 0 : 1; | 		agl_prtx_ctl.s.mode = rgmii_mode ? 0 : 1; | ||||||
|  |  | ||||||
|  | @ -2475,6 +2475,7 @@ static void dpaa_adjust_link(struct net_device *net_dev) | ||||||
| 
 | 
 | ||||||
| static int dpaa_phy_init(struct net_device *net_dev) | static int dpaa_phy_init(struct net_device *net_dev) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
| 	struct mac_device *mac_dev; | 	struct mac_device *mac_dev; | ||||||
| 	struct phy_device *phy_dev; | 	struct phy_device *phy_dev; | ||||||
| 	struct dpaa_priv *priv; | 	struct dpaa_priv *priv; | ||||||
|  | @ -2491,7 +2492,9 @@ static int dpaa_phy_init(struct net_device *net_dev) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Remove any features not supported by the controller */ | 	/* Remove any features not supported by the controller */ | ||||||
| 	phy_dev->supported &= mac_dev->if_support; | 	ethtool_convert_legacy_u32_to_link_mode(mask, mac_dev->if_support); | ||||||
|  | 	linkmode_and(phy_dev->supported, phy_dev->supported, mask); | ||||||
|  | 
 | ||||||
| 	phy_support_asym_pause(phy_dev); | 	phy_support_asym_pause(phy_dev); | ||||||
| 
 | 
 | ||||||
| 	mac_dev->phy_dev = phy_dev; | 	mac_dev->phy_dev = phy_dev; | ||||||
|  |  | ||||||
|  | @ -393,7 +393,7 @@ void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause, | ||||||
| 	 */ | 	 */ | ||||||
| 
 | 
 | ||||||
| 	/* get local capabilities */ | 	/* get local capabilities */ | ||||||
| 	lcl_adv = ethtool_adv_to_lcl_adv_t(phy_dev->advertising); | 	lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising); | ||||||
| 
 | 
 | ||||||
| 	/* get link partner capabilities */ | 	/* get link partner capabilities */ | ||||||
| 	rmt_adv = 0; | 	rmt_adv = 0; | ||||||
|  |  | ||||||
|  | @ -1784,14 +1784,20 @@ static phy_interface_t gfar_get_interface(struct net_device *dev) | ||||||
|  */ |  */ | ||||||
| static int init_phy(struct net_device *dev) | static int init_phy(struct net_device *dev) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
| 	struct gfar_private *priv = netdev_priv(dev); | 	struct gfar_private *priv = netdev_priv(dev); | ||||||
| 	uint gigabit_support = |  | ||||||
| 		priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ? |  | ||||||
| 		GFAR_SUPPORTED_GBIT : 0; |  | ||||||
| 	phy_interface_t interface; | 	phy_interface_t interface; | ||||||
| 	struct phy_device *phydev; | 	struct phy_device *phydev; | ||||||
| 	struct ethtool_eee edata; | 	struct ethtool_eee edata; | ||||||
| 
 | 
 | ||||||
|  | 	linkmode_set_bit_array(phy_10_100_features_array, | ||||||
|  | 			       ARRAY_SIZE(phy_10_100_features_array), | ||||||
|  | 			       mask); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_MII_BIT, mask); | ||||||
|  | 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT) | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mask); | ||||||
|  | 
 | ||||||
| 	priv->oldlink = 0; | 	priv->oldlink = 0; | ||||||
| 	priv->oldspeed = 0; | 	priv->oldspeed = 0; | ||||||
| 	priv->oldduplex = -1; | 	priv->oldduplex = -1; | ||||||
|  | @ -1809,8 +1815,8 @@ static int init_phy(struct net_device *dev) | ||||||
| 		gfar_configure_serdes(dev); | 		gfar_configure_serdes(dev); | ||||||
| 
 | 
 | ||||||
| 	/* Remove any features not supported by the controller */ | 	/* Remove any features not supported by the controller */ | ||||||
| 	phydev->supported &= (GFAR_SUPPORTED | gigabit_support); | 	linkmode_and(phydev->supported, phydev->supported, mask); | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	/* Add support for flow control */ | 	/* Add support for flow control */ | ||||||
| 	phy_support_asym_pause(phydev); | 	phy_support_asym_pause(phydev); | ||||||
|  | @ -3656,7 +3662,7 @@ static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv) | ||||||
| 		if (phydev->asym_pause) | 		if (phydev->asym_pause) | ||||||
| 			rmt_adv |= LPA_PAUSE_ASYM; | 			rmt_adv |= LPA_PAUSE_ASYM; | ||||||
| 
 | 
 | ||||||
| 		lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising); | 		lcl_adv = linkmode_adv_to_lcl_adv_t(phydev->advertising); | ||||||
| 		flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | 		flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||||||
| 		if (flowctrl & FLOW_CTRL_TX) | 		if (flowctrl & FLOW_CTRL_TX) | ||||||
| 			val |= MACCFG1_TX_FLOW; | 			val |= MACCFG1_TX_FLOW; | ||||||
|  |  | ||||||
|  | @ -1742,12 +1742,7 @@ static int init_phy(struct net_device *dev) | ||||||
| 	if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII) | 	if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII) | ||||||
| 		uec_configure_serdes(dev); | 		uec_configure_serdes(dev); | ||||||
| 
 | 
 | ||||||
| 	phy_set_max_speed(phydev, SPEED_100); | 	phy_set_max_speed(phydev, priv->max_speed); | ||||||
| 
 |  | ||||||
| 	if (priv->max_speed == SPEED_1000) |  | ||||||
| 		phydev->supported |= ADVERTISED_1000baseT_Full; |  | ||||||
| 
 |  | ||||||
| 	phydev->advertising = phydev->supported; |  | ||||||
| 
 | 
 | ||||||
| 	priv->phydev = phydev; | 	priv->phydev = phydev; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1163,6 +1163,7 @@ static void hns_nic_adjust_link(struct net_device *ndev) | ||||||
|  */ |  */ | ||||||
| int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h) | int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; | ||||||
| 	struct phy_device *phy_dev = h->phy_dev; | 	struct phy_device *phy_dev = h->phy_dev; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
|  | @ -1180,8 +1181,9 @@ int hns_nic_init_phy(struct net_device *ndev, struct hnae_handle *h) | ||||||
| 	if (unlikely(ret)) | 	if (unlikely(ret)) | ||||||
| 		return -ENODEV; | 		return -ENODEV; | ||||||
| 
 | 
 | ||||||
| 	phy_dev->supported &= h->if_support; | 	ethtool_convert_legacy_u32_to_link_mode(supported, h->if_support); | ||||||
| 	phy_dev->advertising = phy_dev->supported; | 	linkmode_and(phy_dev->supported, phy_dev->supported, supported); | ||||||
|  | 	linkmode_copy(phy_dev->advertising, phy_dev->supported); | ||||||
| 
 | 
 | ||||||
| 	if (h->phy_if == PHY_INTERFACE_MODE_XGMII) | 	if (h->phy_if == PHY_INTERFACE_MODE_XGMII) | ||||||
| 		phy_dev->autoneg = false; | 		phy_dev->autoneg = false; | ||||||
|  |  | ||||||
|  | @ -6582,7 +6582,7 @@ int hclge_cfg_flowctrl(struct hclge_dev *hdev) | ||||||
| 	if (!phydev->link || !phydev->autoneg) | 	if (!phydev->link || !phydev->autoneg) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	local_advertising = ethtool_adv_to_lcl_adv_t(phydev->advertising); | 	local_advertising = linkmode_adv_to_lcl_adv_t(phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	if (phydev->pause) | 	if (phydev->pause) | ||||||
| 		remote_advertising = LPA_PAUSE_CAP; | 		remote_advertising = LPA_PAUSE_CAP; | ||||||
|  |  | ||||||
|  | @ -195,12 +195,13 @@ int hclge_mac_connect_phy(struct hclge_dev *hdev) | ||||||
| { | { | ||||||
| 	struct net_device *netdev = hdev->vport[0].nic.netdev; | 	struct net_device *netdev = hdev->vport[0].nic.netdev; | ||||||
| 	struct phy_device *phydev = hdev->hw.mac.phydev; | 	struct phy_device *phydev = hdev->hw.mac.phydev; | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	if (!phydev) | 	if (!phydev) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	phydev->supported &= ~SUPPORTED_FIBRE; | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	ret = phy_connect_direct(netdev, phydev, | 	ret = phy_connect_direct(netdev, phydev, | ||||||
| 				 hclge_mac_adjust_link, | 				 hclge_mac_adjust_link, | ||||||
|  | @ -210,7 +211,15 @@ int hclge_mac_connect_phy(struct hclge_dev *hdev) | ||||||
| 		return ret; | 		return ret; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	phydev->supported &= HCLGE_PHY_SUPPORTED_FEATURES; | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, mask); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_TP_BIT, mask); | ||||||
|  | 	linkmode_set_bit_array(phy_10_100_features_array, | ||||||
|  | 			       ARRAY_SIZE(phy_10_100_features_array), | ||||||
|  | 			       mask); | ||||||
|  | 	linkmode_set_bit_array(phy_gbit_features_array, | ||||||
|  | 			       ARRAY_SIZE(phy_gbit_features_array), | ||||||
|  | 			       mask); | ||||||
|  | 	linkmode_and(phydev->supported, phydev->supported, mask); | ||||||
| 	phy_support_asym_pause(phydev); | 	phy_support_asym_pause(phydev); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -2455,7 +2455,8 @@ static void emac_adjust_link(struct net_device *ndev) | ||||||
| 	dev->phy.duplex = phy->duplex; | 	dev->phy.duplex = phy->duplex; | ||||||
| 	dev->phy.pause = phy->pause; | 	dev->phy.pause = phy->pause; | ||||||
| 	dev->phy.asym_pause = phy->asym_pause; | 	dev->phy.asym_pause = phy->asym_pause; | ||||||
| 	dev->phy.advertising = phy->advertising; | 	ethtool_convert_link_mode_to_legacy_u32(&dev->phy.advertising, | ||||||
|  | 						phy->advertising); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int emac_mii_bus_read(struct mii_bus *bus, int addr, int regnum) | static int emac_mii_bus_read(struct mii_bus *bus, int addr, int regnum) | ||||||
|  | @ -2490,7 +2491,8 @@ static int emac_mdio_phy_start_aneg(struct mii_phy *phy, | ||||||
| 	phy_dev->autoneg = phy->autoneg; | 	phy_dev->autoneg = phy->autoneg; | ||||||
| 	phy_dev->speed = phy->speed; | 	phy_dev->speed = phy->speed; | ||||||
| 	phy_dev->duplex = phy->duplex; | 	phy_dev->duplex = phy->duplex; | ||||||
| 	phy_dev->advertising = phy->advertising; | 	ethtool_convert_legacy_u32_to_link_mode(phy_dev->advertising, | ||||||
|  | 						phy->advertising); | ||||||
| 	return phy_start_aneg(phy_dev); | 	return phy_start_aneg(phy_dev); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -2624,7 +2626,8 @@ static int emac_dt_phy_connect(struct emac_instance *dev, | ||||||
| 	dev->phy.def->phy_id_mask = dev->phy_dev->drv->phy_id_mask; | 	dev->phy.def->phy_id_mask = dev->phy_dev->drv->phy_id_mask; | ||||||
| 	dev->phy.def->name = dev->phy_dev->drv->name; | 	dev->phy.def->name = dev->phy_dev->drv->name; | ||||||
| 	dev->phy.def->ops = &emac_dt_mdio_phy_ops; | 	dev->phy.def->ops = &emac_dt_mdio_phy_ops; | ||||||
| 	dev->phy.features = dev->phy_dev->supported; | 	ethtool_convert_link_mode_to_legacy_u32(&dev->phy.features, | ||||||
|  | 						dev->phy_dev->supported); | ||||||
| 	dev->phy.address = dev->phy_dev->mdio.addr; | 	dev->phy.address = dev->phy_dev->mdio.addr; | ||||||
| 	dev->phy.mode = dev->phy_dev->interface; | 	dev->phy.mode = dev->phy_dev->interface; | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -1499,23 +1499,16 @@ mv643xx_eth_get_link_ksettings_phy(struct mv643xx_eth_private *mp, | ||||||
| 				   struct ethtool_link_ksettings *cmd) | 				   struct ethtool_link_ksettings *cmd) | ||||||
| { | { | ||||||
| 	struct net_device *dev = mp->dev; | 	struct net_device *dev = mp->dev; | ||||||
| 	u32 supported, advertising; |  | ||||||
| 
 | 
 | ||||||
| 	phy_ethtool_ksettings_get(dev->phydev, cmd); | 	phy_ethtool_ksettings_get(dev->phydev, cmd); | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * The MAC does not support 1000baseT_Half. | 	 * The MAC does not support 1000baseT_Half. | ||||||
| 	 */ | 	 */ | ||||||
| 	ethtool_convert_link_mode_to_legacy_u32(&supported, | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
| 						cmd->link_modes.supported); | 			   cmd->link_modes.supported); | ||||||
| 	ethtool_convert_link_mode_to_legacy_u32(&advertising, | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
| 						cmd->link_modes.advertising); | 			   cmd->link_modes.advertising); | ||||||
| 	supported &= ~SUPPORTED_1000baseT_Half; |  | ||||||
| 	advertising &= ~ADVERTISED_1000baseT_Half; |  | ||||||
| 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, |  | ||||||
| 						supported); |  | ||||||
| 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, |  | ||||||
| 						advertising); |  | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -3031,10 +3024,12 @@ static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex) | ||||||
| 		phy->autoneg = AUTONEG_ENABLE; | 		phy->autoneg = AUTONEG_ENABLE; | ||||||
| 		phy->speed = 0; | 		phy->speed = 0; | ||||||
| 		phy->duplex = 0; | 		phy->duplex = 0; | ||||||
| 		phy->advertising = phy->supported | ADVERTISED_Autoneg; | 		linkmode_copy(phy->advertising, phy->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | 				 phy->advertising); | ||||||
| 	} else { | 	} else { | ||||||
| 		phy->autoneg = AUTONEG_DISABLE; | 		phy->autoneg = AUTONEG_DISABLE; | ||||||
| 		phy->advertising = 0; | 		linkmode_zero(phy->advertising); | ||||||
| 		phy->speed = speed; | 		phy->speed = speed; | ||||||
| 		phy->duplex = duplex; | 		phy->duplex = duplex; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -243,7 +243,7 @@ static void mtk_phy_link_adjust(struct net_device *dev) | ||||||
| 		if (dev->phydev->asym_pause) | 		if (dev->phydev->asym_pause) | ||||||
| 			rmt_adv |= LPA_PAUSE_ASYM; | 			rmt_adv |= LPA_PAUSE_ASYM; | ||||||
| 
 | 
 | ||||||
| 		lcl_adv = ethtool_adv_to_lcl_adv_t(dev->phydev->advertising); | 		lcl_adv = linkmode_adv_to_lcl_adv_t(dev->phydev->advertising); | ||||||
| 		flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | 		flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||||||
| 
 | 
 | ||||||
| 		if (flowctrl & FLOW_CTRL_TX) | 		if (flowctrl & FLOW_CTRL_TX) | ||||||
|  | @ -353,8 +353,9 @@ static int mtk_phy_connect(struct net_device *dev) | ||||||
| 
 | 
 | ||||||
| 	phy_set_max_speed(dev->phydev, SPEED_1000); | 	phy_set_max_speed(dev->phydev, SPEED_1000); | ||||||
| 	phy_support_asym_pause(dev->phydev); | 	phy_support_asym_pause(dev->phydev); | ||||||
| 	dev->phydev->advertising = dev->phydev->supported | | 	linkmode_copy(dev->phydev->advertising, dev->phydev->supported); | ||||||
| 				    ADVERTISED_Autoneg; | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | 			 dev->phydev->advertising); | ||||||
| 	phy_start_aneg(dev->phydev); | 	phy_start_aneg(dev->phydev); | ||||||
| 
 | 
 | ||||||
| 	of_node_put(np); | 	of_node_put(np); | ||||||
|  |  | ||||||
|  | @ -783,8 +783,6 @@ static int lpc_mii_probe(struct net_device *ndev) | ||||||
| 
 | 
 | ||||||
| 	phy_set_max_speed(phydev, SPEED_100); | 	phy_set_max_speed(phydev, SPEED_100); | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising = phydev->supported; |  | ||||||
| 
 |  | ||||||
| 	pldat->link = 0; | 	pldat->link = 0; | ||||||
| 	pldat->speed = 0; | 	pldat->speed = 0; | ||||||
| 	pldat->duplex = -1; | 	pldat->duplex = -1; | ||||||
|  |  | ||||||
|  | @ -6584,7 +6584,7 @@ static int r8169_phy_connect(struct rtl8169_private *tp) | ||||||
| 		phy_set_max_speed(phydev, SPEED_100); | 		phy_set_max_speed(phydev, SPEED_100); | ||||||
| 
 | 
 | ||||||
| 	/* Ensure to advertise everything, incl. pause */ | 	/* Ensure to advertise everything, incl. pause */ | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	phy_attached_info(phydev); | 	phy_attached_info(phydev); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1117,7 +1117,7 @@ static void ave_phy_adjust_link(struct net_device *ndev) | ||||||
| 		if (phydev->asym_pause) | 		if (phydev->asym_pause) | ||||||
| 			rmt_adv |= LPA_PAUSE_ASYM; | 			rmt_adv |= LPA_PAUSE_ASYM; | ||||||
| 
 | 
 | ||||||
| 		lcl_adv = ethtool_adv_to_lcl_adv_t(phydev->advertising); | 		lcl_adv = linkmode_adv_to_lcl_adv_t(phydev->advertising); | ||||||
| 		cap = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | 		cap = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||||||
| 		if (cap & FLOW_CTRL_TX) | 		if (cap & FLOW_CTRL_TX) | ||||||
| 			txcr |= AVE_TXCR_FLOCTR; | 			txcr |= AVE_TXCR_FLOCTR; | ||||||
|  |  | ||||||
|  | @ -458,8 +458,10 @@ stmmac_get_pauseparam(struct net_device *netdev, | ||||||
| 		if (!adv_lp.pause) | 		if (!adv_lp.pause) | ||||||
| 			return; | 			return; | ||||||
| 	} else { | 	} else { | ||||||
| 		if (!(netdev->phydev->supported & SUPPORTED_Pause) || | 		if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
| 		    !(netdev->phydev->supported & SUPPORTED_Asym_Pause)) | 				       netdev->phydev->supported) || | ||||||
|  | 		    linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				      netdev->phydev->supported)) | ||||||
| 			return; | 			return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -487,8 +489,10 @@ stmmac_set_pauseparam(struct net_device *netdev, | ||||||
| 		if (!adv_lp.pause) | 		if (!adv_lp.pause) | ||||||
| 			return -EOPNOTSUPP; | 			return -EOPNOTSUPP; | ||||||
| 	} else { | 	} else { | ||||||
| 		if (!(phy->supported & SUPPORTED_Pause) || | 		if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
| 		    !(phy->supported & SUPPORTED_Asym_Pause)) | 				       phy->supported) || | ||||||
|  | 		    linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				      phy->supported)) | ||||||
| 			return -EOPNOTSUPP; | 			return -EOPNOTSUPP; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -607,9 +607,9 @@ static void tc_handle_link_change(struct net_device *dev) | ||||||
| 
 | 
 | ||||||
| static int tc_mii_probe(struct net_device *dev) | static int tc_mii_probe(struct net_device *dev) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
| 	struct tc35815_local *lp = netdev_priv(dev); | 	struct tc35815_local *lp = netdev_priv(dev); | ||||||
| 	struct phy_device *phydev; | 	struct phy_device *phydev; | ||||||
| 	u32 dropmask; |  | ||||||
| 
 | 
 | ||||||
| 	phydev = phy_find_first(lp->mii_bus); | 	phydev = phy_find_first(lp->mii_bus); | ||||||
| 	if (!phydev) { | 	if (!phydev) { | ||||||
|  | @ -630,17 +630,22 @@ static int tc_mii_probe(struct net_device *dev) | ||||||
| 
 | 
 | ||||||
| 	/* mask with MAC supported features */ | 	/* mask with MAC supported features */ | ||||||
| 	phy_set_max_speed(phydev, SPEED_100); | 	phy_set_max_speed(phydev, SPEED_100); | ||||||
| 	dropmask = 0; | 	if (options.speed == 10) { | ||||||
| 	if (options.speed == 10) | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); | ||||||
| 		dropmask |= SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask); | ||||||
| 	else if (options.speed == 100) | 	} else if (options.speed == 100) { | ||||||
| 		dropmask |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mask); | ||||||
| 	if (options.duplex == 1) | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, mask); | ||||||
| 		dropmask |= SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Full; | 	} | ||||||
| 	else if (options.duplex == 2) | 	if (options.duplex == 1) { | ||||||
| 		dropmask |= SUPPORTED_10baseT_Half | SUPPORTED_100baseT_Half; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, mask); | ||||||
| 	phydev->supported &= ~dropmask; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask); | ||||||
| 	phydev->advertising = phydev->supported; | 	} else if (options.duplex == 2) { | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, mask); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); | ||||||
|  | 	} | ||||||
|  | 	linkmode_and(phydev->supported, phydev->supported, mask); | ||||||
|  | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	lp->link = 0; | 	lp->link = 0; | ||||||
| 	lp->speed = 0; | 	lp->speed = 0; | ||||||
|  |  | ||||||
|  | @ -25,15 +25,10 @@ | ||||||
| #define PHY_ID_AQR107	0x03a1b4e0 | #define PHY_ID_AQR107	0x03a1b4e0 | ||||||
| #define PHY_ID_AQR405	0x03a1b4b0 | #define PHY_ID_AQR405	0x03a1b4b0 | ||||||
| 
 | 
 | ||||||
| #define PHY_AQUANTIA_FEATURES	(SUPPORTED_10000baseT_Full | \ |  | ||||||
| 				 SUPPORTED_1000baseT_Full | \ |  | ||||||
| 				 SUPPORTED_100baseT_Full | \ |  | ||||||
| 				 PHY_DEFAULT_FEATURES) |  | ||||||
| 
 |  | ||||||
| static int aquantia_config_aneg(struct phy_device *phydev) | static int aquantia_config_aneg(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	phydev->supported = PHY_AQUANTIA_FEATURES; | 	linkmode_copy(phydev->supported, phy_10gbit_features); | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -43,7 +43,7 @@ static int bcm63xx_config_init(struct phy_device *phydev) | ||||||
| 	int reg, err; | 	int reg, err; | ||||||
| 
 | 
 | ||||||
| 	/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */ | 	/* ASYM_PAUSE bit is marked RO in datasheet, so don't cheat */ | ||||||
| 	phydev->supported |= SUPPORTED_Pause; | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	reg = phy_read(phydev, MII_BCM63XX_IR); | 	reg = phy_read(phydev, MII_BCM63XX_IR); | ||||||
| 	if (reg < 0) | 	if (reg < 0) | ||||||
|  |  | ||||||
|  | @ -86,8 +86,12 @@ static int bcm87xx_of_reg_init(struct phy_device *phydev) | ||||||
| 
 | 
 | ||||||
| static int bcm87xx_config_init(struct phy_device *phydev) | static int bcm87xx_config_init(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	phydev->supported = SUPPORTED_10000baseR_FEC; | 	linkmode_zero(phydev->supported); | ||||||
| 	phydev->advertising = ADVERTISED_10000baseR_FEC; | 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, | ||||||
|  | 			 phydev->supported); | ||||||
|  | 	linkmode_zero(phydev->advertising); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, | ||||||
|  | 			 phydev->advertising); | ||||||
| 	phydev->state = PHY_NOLINK; | 	phydev->state = PHY_NOLINK; | ||||||
| 	phydev->autoneg = AUTONEG_DISABLE; | 	phydev->autoneg = AUTONEG_DISABLE; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -223,14 +223,23 @@ struct phy_device *fixed_phy_register(unsigned int irq, | ||||||
| 
 | 
 | ||||||
| 	switch (status->speed) { | 	switch (status->speed) { | ||||||
| 	case SPEED_1000: | 	case SPEED_1000: | ||||||
| 		phy->supported = PHY_1000BT_FEATURES; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
| 		break; | 				 phy->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				 phy->supported); | ||||||
|  | 		/* fall through */ | ||||||
| 	case SPEED_100: | 	case SPEED_100: | ||||||
| 		phy->supported = PHY_100BT_FEATURES; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||||||
| 		break; | 				 phy->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
|  | 				 phy->supported); | ||||||
|  | 		/* fall through */ | ||||||
| 	case SPEED_10: | 	case SPEED_10: | ||||||
| 	default: | 	default: | ||||||
| 		phy->supported = PHY_10BT_FEATURES; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, | ||||||
|  | 				 phy->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||||||
|  | 				 phy->supported); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ret = phy_device_register(phy); | 	ret = phy_device_register(phy); | ||||||
|  |  | ||||||
|  | @ -491,25 +491,26 @@ static int m88e1318_config_aneg(struct phy_device *phydev) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * ethtool_adv_to_fiber_adv_t |  * linkmode_adv_to_fiber_adv_t | ||||||
|  * @ethadv: the ethtool advertisement settings |  * @advertise: the linkmode advertisement settings | ||||||
|  * |  * | ||||||
|  * A small helper function that translates ethtool advertisement |  * A small helper function that translates linkmode advertisement | ||||||
|  * settings to phy autonegotiation advertisements for the |  * settings to phy autonegotiation advertisements for the MII_ADV | ||||||
|  * MII_ADV register for fiber link. |  * register for fiber link. | ||||||
|  */ |  */ | ||||||
| static inline u32 ethtool_adv_to_fiber_adv_t(u32 ethadv) | static inline u32 linkmode_adv_to_fiber_adv_t(unsigned long *advertise) | ||||||
| { | { | ||||||
| 	u32 result = 0; | 	u32 result = 0; | ||||||
| 
 | 
 | ||||||
| 	if (ethadv & ADVERTISED_1000baseT_Half) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertise)) | ||||||
| 		result |= ADVERTISE_FIBER_1000HALF; | 		result |= ADVERTISE_FIBER_1000HALF; | ||||||
| 	if (ethadv & ADVERTISED_1000baseT_Full) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertise)) | ||||||
| 		result |= ADVERTISE_FIBER_1000FULL; | 		result |= ADVERTISE_FIBER_1000FULL; | ||||||
| 
 | 
 | ||||||
| 	if ((ethadv & ADVERTISE_PAUSE_ASYM) && (ethadv & ADVERTISE_PAUSE_CAP)) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertise) && | ||||||
|  | 	    linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise)) | ||||||
| 		result |= LPA_PAUSE_ASYM_FIBER; | 		result |= LPA_PAUSE_ASYM_FIBER; | ||||||
| 	else if (ethadv & ADVERTISE_PAUSE_CAP) | 	else if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertise)) | ||||||
| 		result |= (ADVERTISE_PAUSE_FIBER | 		result |= (ADVERTISE_PAUSE_FIBER | ||||||
| 			   & (~ADVERTISE_PAUSE_ASYM_FIBER)); | 			   & (~ADVERTISE_PAUSE_ASYM_FIBER)); | ||||||
| 
 | 
 | ||||||
|  | @ -530,14 +531,13 @@ static int marvell_config_aneg_fiber(struct phy_device *phydev) | ||||||
| 	int changed = 0; | 	int changed = 0; | ||||||
| 	int err; | 	int err; | ||||||
| 	int adv, oldadv; | 	int adv, oldadv; | ||||||
| 	u32 advertise; |  | ||||||
| 
 | 
 | ||||||
| 	if (phydev->autoneg != AUTONEG_ENABLE) | 	if (phydev->autoneg != AUTONEG_ENABLE) | ||||||
| 		return genphy_setup_forced(phydev); | 		return genphy_setup_forced(phydev); | ||||||
| 
 | 
 | ||||||
| 	/* Only allow advertising what this PHY supports */ | 	/* Only allow advertising what this PHY supports */ | ||||||
| 	phydev->advertising &= phydev->supported; | 	linkmode_and(phydev->advertising, phydev->advertising, | ||||||
| 	advertise = phydev->advertising; | 		     phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	/* Setup fiber advertisement */ | 	/* Setup fiber advertisement */ | ||||||
| 	adv = phy_read(phydev, MII_ADVERTISE); | 	adv = phy_read(phydev, MII_ADVERTISE); | ||||||
|  | @ -547,7 +547,7 @@ static int marvell_config_aneg_fiber(struct phy_device *phydev) | ||||||
| 	oldadv = adv; | 	oldadv = adv; | ||||||
| 	adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL | 	adv &= ~(ADVERTISE_FIBER_1000HALF | ADVERTISE_FIBER_1000FULL | ||||||
| 		| LPA_PAUSE_FIBER); | 		| LPA_PAUSE_FIBER); | ||||||
| 	adv |= ethtool_adv_to_fiber_adv_t(advertise); | 	adv |= linkmode_adv_to_fiber_adv_t(phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	if (adv != oldadv) { | 	if (adv != oldadv) { | ||||||
| 		err = phy_write(phydev, MII_ADVERTISE, adv); | 		err = phy_write(phydev, MII_ADVERTISE, adv); | ||||||
|  | @ -879,8 +879,14 @@ static int m88e1510_config_init(struct phy_device *phydev) | ||||||
| 		 * so disable Pause support. | 		 * so disable Pause support. | ||||||
| 		 */ | 		 */ | ||||||
| 		pause = SUPPORTED_Pause | SUPPORTED_Asym_Pause; | 		pause = SUPPORTED_Pause | SUPPORTED_Asym_Pause; | ||||||
| 		phydev->supported &= ~pause; | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
| 		phydev->advertising &= ~pause; | 				   phydev->supported); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 				   phydev->supported); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return m88e1318_config_init(phydev); | 	return m88e1318_config_init(phydev); | ||||||
|  | @ -1235,7 +1241,8 @@ static int marvell_read_status(struct phy_device *phydev) | ||||||
| 	int err; | 	int err; | ||||||
| 
 | 
 | ||||||
| 	/* Check the fiber mode first */ | 	/* Check the fiber mode first */ | ||||||
| 	if (phydev->supported & SUPPORTED_FIBRE && | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, | ||||||
|  | 			      phydev->supported) && | ||||||
| 	    phydev->interface != PHY_INTERFACE_MODE_SGMII) { | 	    phydev->interface != PHY_INTERFACE_MODE_SGMII) { | ||||||
| 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); | 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); | ||||||
| 		if (err < 0) | 		if (err < 0) | ||||||
|  | @ -1278,7 +1285,8 @@ static int marvell_suspend(struct phy_device *phydev) | ||||||
| 	int err; | 	int err; | ||||||
| 
 | 
 | ||||||
| 	/* Suspend the fiber mode first */ | 	/* Suspend the fiber mode first */ | ||||||
| 	if (!(phydev->supported & SUPPORTED_FIBRE)) { | 	if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, | ||||||
|  | 			       phydev->supported)) { | ||||||
| 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); | 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); | ||||||
| 		if (err < 0) | 		if (err < 0) | ||||||
| 			goto error; | 			goto error; | ||||||
|  | @ -1312,7 +1320,8 @@ static int marvell_resume(struct phy_device *phydev) | ||||||
| 	int err; | 	int err; | ||||||
| 
 | 
 | ||||||
| 	/* Resume the fiber mode first */ | 	/* Resume the fiber mode first */ | ||||||
| 	if (!(phydev->supported & SUPPORTED_FIBRE)) { | 	if (!linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, | ||||||
|  | 			       phydev->supported)) { | ||||||
| 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); | 		err = marvell_set_page(phydev, MII_MARVELL_FIBER_PAGE); | ||||||
| 		if (err < 0) | 		if (err < 0) | ||||||
| 			goto error; | 			goto error; | ||||||
|  | @ -1463,7 +1472,8 @@ static int m88e1318_set_wol(struct phy_device *phydev, | ||||||
| 
 | 
 | ||||||
| static int marvell_get_sset_count(struct phy_device *phydev) | static int marvell_get_sset_count(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	if (phydev->supported & SUPPORTED_FIBRE) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, | ||||||
|  | 			      phydev->supported)) | ||||||
| 		return ARRAY_SIZE(marvell_hw_stats); | 		return ARRAY_SIZE(marvell_hw_stats); | ||||||
| 	else | 	else | ||||||
| 		return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS; | 		return ARRAY_SIZE(marvell_hw_stats) - NB_FIBER_STATS; | ||||||
|  |  | ||||||
|  | @ -252,7 +252,6 @@ static int mv3310_resume(struct phy_device *phydev) | ||||||
| static int mv3310_config_init(struct phy_device *phydev) | static int mv3310_config_init(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, }; | ||||||
| 	u32 mask; |  | ||||||
| 	int val; | 	int val; | ||||||
| 
 | 
 | ||||||
| 	/* Check that the PHY interface type is compatible */ | 	/* Check that the PHY interface type is compatible */ | ||||||
|  | @ -336,13 +335,9 @@ static int mv3310_config_init(struct phy_device *phydev) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (!ethtool_convert_link_mode_to_legacy_u32(&mask, supported)) | 	linkmode_copy(phydev->supported, supported); | ||||||
| 		phydev_warn(phydev, | 	linkmode_and(phydev->advertising, phydev->advertising, | ||||||
| 			    "PHY supports (%*pb) more modes than phylib supports, some modes not supported.\n", | 		     phydev->supported); | ||||||
| 			    __ETHTOOL_LINK_MODE_MASK_NBITS, supported); |  | ||||||
| 
 |  | ||||||
| 	phydev->supported &= mask; |  | ||||||
| 	phydev->advertising &= phydev->supported; |  | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -350,7 +345,7 @@ static int mv3310_config_init(struct phy_device *phydev) | ||||||
| static int mv3310_config_aneg(struct phy_device *phydev) | static int mv3310_config_aneg(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	bool changed = false; | 	bool changed = false; | ||||||
| 	u32 advertising; | 	u16 reg; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	/* We don't support manual MDI control */ | 	/* We don't support manual MDI control */ | ||||||
|  | @ -364,31 +359,35 @@ static int mv3310_config_aneg(struct phy_device *phydev) | ||||||
| 		return genphy_c45_an_disable_aneg(phydev); | 		return genphy_c45_an_disable_aneg(phydev); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising &= phydev->supported; | 	linkmode_and(phydev->advertising, phydev->advertising, | ||||||
| 	advertising = phydev->advertising; | 		     phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, | 	ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE, | ||||||
| 			    ADVERTISE_ALL | ADVERTISE_100BASE4 | | 			    ADVERTISE_ALL | ADVERTISE_100BASE4 | | ||||||
| 			    ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM, | 			    ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM, | ||||||
| 			    ethtool_adv_to_mii_adv_t(advertising)); | 			    linkmode_adv_to_mii_adv_t(phydev->advertising)); | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 		return ret; | 		return ret; | ||||||
| 	if (ret > 0) | 	if (ret > 0) | ||||||
| 		changed = true; | 		changed = true; | ||||||
| 
 | 
 | ||||||
|  | 	reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); | ||||||
| 	ret = mv3310_modify(phydev, MDIO_MMD_AN, MV_AN_CTRL1000, | 	ret = mv3310_modify(phydev, MDIO_MMD_AN, MV_AN_CTRL1000, | ||||||
| 			    ADVERTISE_1000FULL | ADVERTISE_1000HALF, | 			    ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg); | ||||||
| 			    ethtool_adv_to_mii_ctrl1000_t(advertising)); |  | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 		return ret; | 		return ret; | ||||||
| 	if (ret > 0) | 	if (ret > 0) | ||||||
| 		changed = true; | 		changed = true; | ||||||
| 
 | 
 | ||||||
| 	/* 10G control register */ | 	/* 10G control register */ | ||||||
|  | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | ||||||
|  | 			      phydev->advertising)) | ||||||
|  | 		reg = MDIO_AN_10GBT_CTRL_ADV10G; | ||||||
|  | 	else | ||||||
|  | 		reg = 0; | ||||||
|  | 
 | ||||||
| 	ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, | 	ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, | ||||||
| 			    MDIO_AN_10GBT_CTRL_ADV10G, | 			    MDIO_AN_10GBT_CTRL_ADV10G, reg); | ||||||
| 			    advertising & ADVERTISED_10000baseT_Full ? |  | ||||||
| 				MDIO_AN_10GBT_CTRL_ADV10G : 0); |  | ||||||
| 	if (ret < 0) | 	if (ret < 0) | ||||||
| 		return ret; | 		return ret; | ||||||
| 	if (ret > 0) | 	if (ret > 0) | ||||||
|  |  | ||||||
|  | @ -311,17 +311,22 @@ static int kszphy_config_init(struct phy_device *phydev) | ||||||
| 
 | 
 | ||||||
| static int ksz8041_config_init(struct phy_device *phydev) | static int ksz8041_config_init(struct phy_device *phydev) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, }; | ||||||
|  | 
 | ||||||
| 	struct device_node *of_node = phydev->mdio.dev.of_node; | 	struct device_node *of_node = phydev->mdio.dev.of_node; | ||||||
| 
 | 
 | ||||||
| 	/* Limit supported and advertised modes in fiber mode */ | 	/* Limit supported and advertised modes in fiber mode */ | ||||||
| 	if (of_property_read_bool(of_node, "micrel,fiber-mode")) { | 	if (of_property_read_bool(of_node, "micrel,fiber-mode")) { | ||||||
| 		phydev->dev_flags |= MICREL_PHY_FXEN; | 		phydev->dev_flags |= MICREL_PHY_FXEN; | ||||||
| 		phydev->supported &= SUPPORTED_100baseT_Full | | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, mask); | ||||||
| 				     SUPPORTED_100baseT_Half; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, mask); | ||||||
| 		phydev->supported |= SUPPORTED_FIBRE; | 
 | ||||||
| 		phydev->advertising &= ADVERTISED_100baseT_Full | | 		linkmode_and(phydev->supported, phydev->supported, mask); | ||||||
| 				       ADVERTISED_100baseT_Half; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, | ||||||
| 		phydev->advertising |= ADVERTISED_FIBRE; | 				 phydev->supported); | ||||||
|  | 		linkmode_and(phydev->advertising, phydev->advertising, mask); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, | ||||||
|  | 				 phydev->advertising); | ||||||
| 		phydev->autoneg = AUTONEG_DISABLE; | 		phydev->autoneg = AUTONEG_DISABLE; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -304,8 +304,11 @@ EXPORT_SYMBOL_GPL(gen10g_no_soft_reset); | ||||||
| int gen10g_config_init(struct phy_device *phydev) | int gen10g_config_init(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	/* Temporarily just say we support everything */ | 	/* Temporarily just say we support everything */ | ||||||
| 	phydev->supported = SUPPORTED_10000baseT_Full; | 	linkmode_zero(phydev->supported); | ||||||
| 	phydev->advertising = SUPPORTED_10000baseT_Full; | 
 | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | ||||||
|  | 			 phydev->supported); | ||||||
|  | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -129,7 +129,6 @@ static const struct phy_setting settings[] = { | ||||||
|  * @speed: speed to match |  * @speed: speed to match | ||||||
|  * @duplex: duplex to match |  * @duplex: duplex to match | ||||||
|  * @mask: allowed link modes |  * @mask: allowed link modes | ||||||
|  * @maxbit: bit size of link modes |  | ||||||
|  * @exact: an exact match is required |  * @exact: an exact match is required | ||||||
|  * |  * | ||||||
|  * Search the settings array for a setting that matches the speed and |  * Search the settings array for a setting that matches the speed and | ||||||
|  | @ -143,14 +142,14 @@ static const struct phy_setting settings[] = { | ||||||
|  * they all fail, %NULL will be returned. |  * they all fail, %NULL will be returned. | ||||||
|  */ |  */ | ||||||
| const struct phy_setting * | const struct phy_setting * | ||||||
| phy_lookup_setting(int speed, int duplex, const unsigned long *mask, | phy_lookup_setting(int speed, int duplex, const unsigned long *mask, bool exact) | ||||||
| 		   size_t maxbit, bool exact) |  | ||||||
| { | { | ||||||
| 	const struct phy_setting *p, *match = NULL, *last = NULL; | 	const struct phy_setting *p, *match = NULL, *last = NULL; | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) { | 	for (i = 0, p = settings; i < ARRAY_SIZE(settings); i++, p++) { | ||||||
| 		if (p->bit < maxbit && test_bit(p->bit, mask)) { | 		if (p->bit < __ETHTOOL_LINK_MODE_MASK_NBITS && | ||||||
|  | 		    test_bit(p->bit, mask)) { | ||||||
| 			last = p; | 			last = p; | ||||||
| 			if (p->speed == speed && p->duplex == duplex) { | 			if (p->speed == speed && p->duplex == duplex) { | ||||||
| 				/* Exact match for speed and duplex */ | 				/* Exact match for speed and duplex */ | ||||||
|  | @ -175,13 +174,13 @@ phy_lookup_setting(int speed, int duplex, const unsigned long *mask, | ||||||
| EXPORT_SYMBOL_GPL(phy_lookup_setting); | EXPORT_SYMBOL_GPL(phy_lookup_setting); | ||||||
| 
 | 
 | ||||||
| size_t phy_speeds(unsigned int *speeds, size_t size, | size_t phy_speeds(unsigned int *speeds, size_t size, | ||||||
| 		  unsigned long *mask, size_t maxbit) | 		  unsigned long *mask) | ||||||
| { | { | ||||||
| 	size_t count; | 	size_t count; | ||||||
| 	int i; | 	int i; | ||||||
| 
 | 
 | ||||||
| 	for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++) | 	for (i = 0, count = 0; i < ARRAY_SIZE(settings) && count < size; i++) | ||||||
| 		if (settings[i].bit < maxbit && | 		if (settings[i].bit < __ETHTOOL_LINK_MODE_MASK_NBITS && | ||||||
| 		    test_bit(settings[i].bit, mask) && | 		    test_bit(settings[i].bit, mask) && | ||||||
| 		    (count == 0 || speeds[count - 1] != settings[i].speed)) | 		    (count == 0 || speeds[count - 1] != settings[i].speed)) | ||||||
| 			speeds[count++] = settings[i].speed; | 			speeds[count++] = settings[i].speed; | ||||||
|  | @ -199,27 +198,38 @@ size_t phy_speeds(unsigned int *speeds, size_t size, | ||||||
|  */ |  */ | ||||||
| void phy_resolve_aneg_linkmode(struct phy_device *phydev) | void phy_resolve_aneg_linkmode(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	u32 common = phydev->lp_advertising & phydev->advertising; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(common); | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(lp); | ||||||
| 
 | 
 | ||||||
| 	if (common & ADVERTISED_10000baseT_Full) { | 	ethtool_convert_legacy_u32_to_link_mode(lp, phydev->lp_advertising); | ||||||
|  | 
 | ||||||
|  | 	linkmode_and(common, lp, phydev->advertising); | ||||||
|  | 
 | ||||||
|  | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, common)) { | ||||||
| 		phydev->speed = SPEED_10000; | 		phydev->speed = SPEED_10000; | ||||||
| 		phydev->duplex = DUPLEX_FULL; | 		phydev->duplex = DUPLEX_FULL; | ||||||
| 	} else if (common & ADVERTISED_1000baseT_Full) { | 	} else if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				     common)) { | ||||||
| 		phydev->speed = SPEED_1000; | 		phydev->speed = SPEED_1000; | ||||||
| 		phydev->duplex = DUPLEX_FULL; | 		phydev->duplex = DUPLEX_FULL; | ||||||
| 	} else if (common & ADVERTISED_1000baseT_Half) { | 	} else if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
|  | 				     common)) { | ||||||
| 		phydev->speed = SPEED_1000; | 		phydev->speed = SPEED_1000; | ||||||
| 		phydev->duplex = DUPLEX_HALF; | 		phydev->duplex = DUPLEX_HALF; | ||||||
| 	} else if (common & ADVERTISED_100baseT_Full) { | 	} else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
|  | 				     common)) { | ||||||
| 		phydev->speed = SPEED_100; | 		phydev->speed = SPEED_100; | ||||||
| 		phydev->duplex = DUPLEX_FULL; | 		phydev->duplex = DUPLEX_FULL; | ||||||
| 	} else if (common & ADVERTISED_100baseT_Half) { | 	} else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||||||
|  | 				     common)) { | ||||||
| 		phydev->speed = SPEED_100; | 		phydev->speed = SPEED_100; | ||||||
| 		phydev->duplex = DUPLEX_HALF; | 		phydev->duplex = DUPLEX_HALF; | ||||||
| 	} else if (common & ADVERTISED_10baseT_Full) { | 	} else if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||||||
|  | 				     common)) { | ||||||
| 		phydev->speed = SPEED_10; | 		phydev->speed = SPEED_10; | ||||||
| 		phydev->duplex = DUPLEX_FULL; | 		phydev->duplex = DUPLEX_FULL; | ||||||
| 	} else if (common & ADVERTISED_10baseT_Half) { | 	} else if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, | ||||||
|  | 				     common)) { | ||||||
| 		phydev->speed = SPEED_10; | 		phydev->speed = SPEED_10; | ||||||
| 		phydev->duplex = DUPLEX_HALF; | 		phydev->duplex = DUPLEX_HALF; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -179,11 +179,9 @@ EXPORT_SYMBOL(phy_aneg_done); | ||||||
|  * settings were found. |  * settings were found. | ||||||
|  */ |  */ | ||||||
| static const struct phy_setting * | static const struct phy_setting * | ||||||
| phy_find_valid(int speed, int duplex, u32 supported) | phy_find_valid(int speed, int duplex, unsigned long *supported) | ||||||
| { | { | ||||||
| 	unsigned long mask = supported; | 	return phy_lookup_setting(speed, duplex, supported, false); | ||||||
| 
 |  | ||||||
| 	return phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, false); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -200,9 +198,7 @@ unsigned int phy_supported_speeds(struct phy_device *phy, | ||||||
| 				  unsigned int *speeds, | 				  unsigned int *speeds, | ||||||
| 				  unsigned int size) | 				  unsigned int size) | ||||||
| { | { | ||||||
| 	unsigned long supported = phy->supported; | 	return phy_speeds(speeds, size, phy->supported); | ||||||
| 
 |  | ||||||
| 	return phy_speeds(speeds, size, &supported, BITS_PER_LONG); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -214,11 +210,10 @@ unsigned int phy_supported_speeds(struct phy_device *phy, | ||||||
|  * |  * | ||||||
|  * Description: Returns true if there is a valid setting, false otherwise. |  * Description: Returns true if there is a valid setting, false otherwise. | ||||||
|  */ |  */ | ||||||
| static inline bool phy_check_valid(int speed, int duplex, u32 features) | static inline bool phy_check_valid(int speed, int duplex, | ||||||
|  | 				   unsigned long *features) | ||||||
| { | { | ||||||
| 	unsigned long mask = features; | 	return !!phy_lookup_setting(speed, duplex, features, true); | ||||||
| 
 |  | ||||||
| 	return !!phy_lookup_setting(speed, duplex, &mask, BITS_PER_LONG, true); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -232,13 +227,13 @@ static inline bool phy_check_valid(int speed, int duplex, u32 features) | ||||||
| static void phy_sanitize_settings(struct phy_device *phydev) | static void phy_sanitize_settings(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	const struct phy_setting *setting; | 	const struct phy_setting *setting; | ||||||
| 	u32 features = phydev->supported; |  | ||||||
| 
 | 
 | ||||||
| 	/* Sanitize settings based on PHY capabilities */ | 	/* Sanitize settings based on PHY capabilities */ | ||||||
| 	if ((features & SUPPORTED_Autoneg) == 0) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported)) | ||||||
| 		phydev->autoneg = AUTONEG_DISABLE; | 		phydev->autoneg = AUTONEG_DISABLE; | ||||||
| 
 | 
 | ||||||
| 	setting = phy_find_valid(phydev->speed, phydev->duplex, features); | 	setting = phy_find_valid(phydev->speed, phydev->duplex, | ||||||
|  | 				 phydev->supported); | ||||||
| 	if (setting) { | 	if (setting) { | ||||||
| 		phydev->speed = setting->speed; | 		phydev->speed = setting->speed; | ||||||
| 		phydev->duplex = setting->duplex; | 		phydev->duplex = setting->duplex; | ||||||
|  | @ -264,13 +259,15 @@ static void phy_sanitize_settings(struct phy_device *phydev) | ||||||
|  */ |  */ | ||||||
| int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) | int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); | ||||||
| 	u32 speed = ethtool_cmd_speed(cmd); | 	u32 speed = ethtool_cmd_speed(cmd); | ||||||
| 
 | 
 | ||||||
| 	if (cmd->phy_address != phydev->mdio.addr) | 	if (cmd->phy_address != phydev->mdio.addr) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 
 | 
 | ||||||
| 	/* We make sure that we don't pass unsupported values in to the PHY */ | 	/* We make sure that we don't pass unsupported values in to the PHY */ | ||||||
| 	cmd->advertising &= phydev->supported; | 	ethtool_convert_legacy_u32_to_link_mode(advertising, cmd->advertising); | ||||||
|  | 	linkmode_and(advertising, advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	/* Verify the settings we care about. */ | 	/* Verify the settings we care about. */ | ||||||
| 	if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) | 	if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) | ||||||
|  | @ -291,12 +288,14 @@ int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) | ||||||
| 
 | 
 | ||||||
| 	phydev->speed = speed; | 	phydev->speed = speed; | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising = cmd->advertising; | 	linkmode_copy(phydev->advertising, advertising); | ||||||
| 
 | 
 | ||||||
| 	if (AUTONEG_ENABLE == cmd->autoneg) | 	if (AUTONEG_ENABLE == cmd->autoneg) | ||||||
| 		phydev->advertising |= ADVERTISED_Autoneg; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | 				 phydev->advertising); | ||||||
| 	else | 	else | ||||||
| 		phydev->advertising &= ~ADVERTISED_Autoneg; | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	phydev->duplex = cmd->duplex; | 	phydev->duplex = cmd->duplex; | ||||||
| 
 | 
 | ||||||
|  | @ -312,19 +311,18 @@ EXPORT_SYMBOL(phy_ethtool_sset); | ||||||
| int phy_ethtool_ksettings_set(struct phy_device *phydev, | int phy_ethtool_ksettings_set(struct phy_device *phydev, | ||||||
| 			      const struct ethtool_link_ksettings *cmd) | 			      const struct ethtool_link_ksettings *cmd) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); | ||||||
| 	u8 autoneg = cmd->base.autoneg; | 	u8 autoneg = cmd->base.autoneg; | ||||||
| 	u8 duplex = cmd->base.duplex; | 	u8 duplex = cmd->base.duplex; | ||||||
| 	u32 speed = cmd->base.speed; | 	u32 speed = cmd->base.speed; | ||||||
| 	u32 advertising; |  | ||||||
| 
 | 
 | ||||||
| 	if (cmd->base.phy_address != phydev->mdio.addr) | 	if (cmd->base.phy_address != phydev->mdio.addr) | ||||||
| 		return -EINVAL; | 		return -EINVAL; | ||||||
| 
 | 
 | ||||||
| 	ethtool_convert_link_mode_to_legacy_u32(&advertising, | 	linkmode_copy(advertising, cmd->link_modes.advertising); | ||||||
| 						cmd->link_modes.advertising); |  | ||||||
| 
 | 
 | ||||||
| 	/* We make sure that we don't pass unsupported values in to the PHY */ | 	/* We make sure that we don't pass unsupported values in to the PHY */ | ||||||
| 	advertising &= phydev->supported; | 	linkmode_and(advertising, advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	/* Verify the settings we care about. */ | 	/* Verify the settings we care about. */ | ||||||
| 	if (autoneg != AUTONEG_ENABLE && autoneg != AUTONEG_DISABLE) | 	if (autoneg != AUTONEG_ENABLE && autoneg != AUTONEG_DISABLE) | ||||||
|  | @ -345,12 +343,14 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev, | ||||||
| 
 | 
 | ||||||
| 	phydev->speed = speed; | 	phydev->speed = speed; | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising = advertising; | 	linkmode_copy(phydev->advertising, advertising); | ||||||
| 
 | 
 | ||||||
| 	if (autoneg == AUTONEG_ENABLE) | 	if (autoneg == AUTONEG_ENABLE) | ||||||
| 		phydev->advertising |= ADVERTISED_Autoneg; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | 				 phydev->advertising); | ||||||
| 	else | 	else | ||||||
| 		phydev->advertising &= ~ADVERTISED_Autoneg; | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	phydev->duplex = duplex; | 	phydev->duplex = duplex; | ||||||
| 
 | 
 | ||||||
|  | @ -366,11 +366,8 @@ EXPORT_SYMBOL(phy_ethtool_ksettings_set); | ||||||
| void phy_ethtool_ksettings_get(struct phy_device *phydev, | void phy_ethtool_ksettings_get(struct phy_device *phydev, | ||||||
| 			       struct ethtool_link_ksettings *cmd) | 			       struct ethtool_link_ksettings *cmd) | ||||||
| { | { | ||||||
| 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported, | 	linkmode_copy(cmd->link_modes.supported, phydev->supported); | ||||||
| 						phydev->supported); | 	linkmode_copy(cmd->link_modes.advertising, phydev->advertising); | ||||||
| 
 |  | ||||||
| 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising, |  | ||||||
| 						phydev->advertising); |  | ||||||
| 
 | 
 | ||||||
| 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising, | 	ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.lp_advertising, | ||||||
| 						phydev->lp_advertising); | 						phydev->lp_advertising); | ||||||
|  | @ -442,7 +439,8 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| 			case MII_ADVERTISE: | 			case MII_ADVERTISE: | ||||||
| 				phydev->advertising = mii_adv_to_ethtool_adv_t(val); | 				mii_adv_to_linkmode_adv_t(phydev->advertising, | ||||||
|  | 							  val); | ||||||
| 				change_autoneg = true; | 				change_autoneg = true; | ||||||
| 				break; | 				break; | ||||||
| 			default: | 			default: | ||||||
|  | @ -604,20 +602,38 @@ static int phy_poll_aneg_done(struct phy_device *phydev) | ||||||
|  */ |  */ | ||||||
| int phy_speed_down(struct phy_device *phydev, bool sync) | int phy_speed_down(struct phy_device *phydev, bool sync) | ||||||
| { | { | ||||||
| 	u32 adv = phydev->lp_advertising & phydev->supported; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old); | ||||||
| 	u32 adv_old = phydev->advertising; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(adv); | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	if (phydev->autoneg != AUTONEG_ENABLE) | 	if (phydev->autoneg != AUTONEG_ENABLE) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	if (adv & PHY_10BT_FEATURES) | 	linkmode_copy(adv_old, phydev->advertising); | ||||||
| 		phydev->advertising &= ~(PHY_100BT_FEATURES | | 	ethtool_convert_legacy_u32_to_link_mode(adv, phydev->lp_advertising); | ||||||
| 					 PHY_1000BT_FEATURES); | 	linkmode_and(adv, adv, phydev->supported); | ||||||
| 	else if (adv & PHY_100BT_FEATURES) |  | ||||||
| 		phydev->advertising &= ~PHY_1000BT_FEATURES; |  | ||||||
| 
 | 
 | ||||||
| 	if (phydev->advertising == adv_old) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, adv) || | ||||||
|  | 	    linkmode_test_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, adv)) { | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
|  | 	} else if (linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||||||
|  | 				     adv) || | ||||||
|  | 		   linkmode_test_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
|  | 				     adv)) { | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				   phydev->advertising); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (linkmode_equal(phydev->advertising, adv_old)) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	ret = phy_config_aneg(phydev); | 	ret = phy_config_aneg(phydev); | ||||||
|  | @ -636,15 +652,30 @@ EXPORT_SYMBOL_GPL(phy_speed_down); | ||||||
|  */ |  */ | ||||||
| int phy_speed_up(struct phy_device *phydev) | int phy_speed_up(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	u32 mask = PHY_10BT_FEATURES | PHY_100BT_FEATURES | PHY_1000BT_FEATURES; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(all_speeds) = { 0, }; | ||||||
| 	u32 adv_old = phydev->advertising; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(not_speeds); | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported); | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(adv_old); | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(speeds); | ||||||
|  | 
 | ||||||
|  | 	linkmode_copy(adv_old, phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	if (phydev->autoneg != AUTONEG_ENABLE) | 	if (phydev->autoneg != AUTONEG_ENABLE) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising = (adv_old & ~mask) | (phydev->supported & mask); | 	linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, all_speeds); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, all_speeds); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, all_speeds); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, all_speeds); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, all_speeds); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, all_speeds); | ||||||
| 
 | 
 | ||||||
| 	if (phydev->advertising == adv_old) | 	linkmode_andnot(not_speeds, adv_old, all_speeds); | ||||||
|  | 	linkmode_copy(supported, phydev->supported); | ||||||
|  | 	linkmode_and(speeds, supported, all_speeds); | ||||||
|  | 	linkmode_or(phydev->advertising, not_speeds, speeds); | ||||||
|  | 
 | ||||||
|  | 	if (linkmode_equal(phydev->advertising, adv_old)) | ||||||
| 		return 0; | 		return 0; | ||||||
| 
 | 
 | ||||||
| 	return phy_config_aneg(phydev); | 	return phy_config_aneg(phydev); | ||||||
|  | @ -973,6 +1004,30 @@ void phy_mac_interrupt(struct phy_device *phydev) | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(phy_mac_interrupt); | EXPORT_SYMBOL(phy_mac_interrupt); | ||||||
| 
 | 
 | ||||||
|  | static void mmd_eee_adv_to_linkmode(unsigned long *advertising, u16 eee_adv) | ||||||
|  | { | ||||||
|  | 	linkmode_zero(advertising); | ||||||
|  | 
 | ||||||
|  | 	if (eee_adv & MDIO_EEE_100TX) | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
|  | 				 advertising); | ||||||
|  | 	if (eee_adv & MDIO_EEE_1000T) | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				 advertising); | ||||||
|  | 	if (eee_adv & MDIO_EEE_10GT) | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | ||||||
|  | 				 advertising); | ||||||
|  | 	if (eee_adv & MDIO_EEE_1000KX) | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, | ||||||
|  | 				 advertising); | ||||||
|  | 	if (eee_adv & MDIO_EEE_10GKX4) | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, | ||||||
|  | 				 advertising); | ||||||
|  | 	if (eee_adv & MDIO_EEE_10GKR) | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, | ||||||
|  | 				 advertising); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * phy_init_eee - init and check the EEE feature |  * phy_init_eee - init and check the EEE feature | ||||||
|  * @phydev: target phy_device struct |  * @phydev: target phy_device struct | ||||||
|  | @ -991,9 +1046,12 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | ||||||
| 	/* According to 802.3az,the EEE is supported only in full duplex-mode.
 | 	/* According to 802.3az,the EEE is supported only in full duplex-mode.
 | ||||||
| 	 */ | 	 */ | ||||||
| 	if (phydev->duplex == DUPLEX_FULL) { | 	if (phydev->duplex == DUPLEX_FULL) { | ||||||
|  | 		__ETHTOOL_DECLARE_LINK_MODE_MASK(common); | ||||||
|  | 		__ETHTOOL_DECLARE_LINK_MODE_MASK(lp); | ||||||
|  | 		__ETHTOOL_DECLARE_LINK_MODE_MASK(adv); | ||||||
| 		int eee_lp, eee_cap, eee_adv; | 		int eee_lp, eee_cap, eee_adv; | ||||||
| 		u32 lp, cap, adv; |  | ||||||
| 		int status; | 		int status; | ||||||
|  | 		u32 cap; | ||||||
| 
 | 
 | ||||||
| 		/* Read phy status to properly get the right settings */ | 		/* Read phy status to properly get the right settings */ | ||||||
| 		status = phy_read_status(phydev); | 		status = phy_read_status(phydev); | ||||||
|  | @ -1020,9 +1078,11 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) | ||||||
| 		if (eee_adv <= 0) | 		if (eee_adv <= 0) | ||||||
| 			goto eee_exit_err; | 			goto eee_exit_err; | ||||||
| 
 | 
 | ||||||
| 		adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); | 		mmd_eee_adv_to_linkmode(adv, eee_adv); | ||||||
| 		lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); | 		mmd_eee_adv_to_linkmode(lp, eee_lp); | ||||||
| 		if (!phy_check_valid(phydev->speed, phydev->duplex, lp & adv)) | 		linkmode_and(common, adv, lp); | ||||||
|  | 
 | ||||||
|  | 		if (!phy_check_valid(phydev->speed, phydev->duplex, common)) | ||||||
| 			goto eee_exit_err; | 			goto eee_exit_err; | ||||||
| 
 | 
 | ||||||
| 		if (clk_stop_enable) { | 		if (clk_stop_enable) { | ||||||
|  |  | ||||||
|  | @ -66,10 +66,12 @@ static const int phy_basic_ports_array[] = { | ||||||
| 	ETHTOOL_LINK_MODE_TP_BIT, | 	ETHTOOL_LINK_MODE_TP_BIT, | ||||||
| 	ETHTOOL_LINK_MODE_MII_BIT, | 	ETHTOOL_LINK_MODE_MII_BIT, | ||||||
| }; | }; | ||||||
|  | EXPORT_SYMBOL_GPL(phy_basic_ports_array); | ||||||
| 
 | 
 | ||||||
| static const int phy_fibre_port_array[] = { | static const int phy_fibre_port_array[] = { | ||||||
| 	ETHTOOL_LINK_MODE_FIBRE_BIT, | 	ETHTOOL_LINK_MODE_FIBRE_BIT, | ||||||
| }; | }; | ||||||
|  | EXPORT_SYMBOL_GPL(phy_fibre_port_array); | ||||||
| 
 | 
 | ||||||
| static const int phy_all_ports_features_array[] = { | static const int phy_all_ports_features_array[] = { | ||||||
| 	ETHTOOL_LINK_MODE_Autoneg_BIT, | 	ETHTOOL_LINK_MODE_Autoneg_BIT, | ||||||
|  | @ -80,27 +82,32 @@ static const int phy_all_ports_features_array[] = { | ||||||
| 	ETHTOOL_LINK_MODE_BNC_BIT, | 	ETHTOOL_LINK_MODE_BNC_BIT, | ||||||
| 	ETHTOOL_LINK_MODE_Backplane_BIT, | 	ETHTOOL_LINK_MODE_Backplane_BIT, | ||||||
| }; | }; | ||||||
|  | EXPORT_SYMBOL_GPL(phy_all_ports_features_array); | ||||||
| 
 | 
 | ||||||
| static const int phy_10_100_features_array[] = { | const int phy_10_100_features_array[4] = { | ||||||
| 	ETHTOOL_LINK_MODE_10baseT_Half_BIT, | 	ETHTOOL_LINK_MODE_10baseT_Half_BIT, | ||||||
| 	ETHTOOL_LINK_MODE_10baseT_Full_BIT, | 	ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||||||
| 	ETHTOOL_LINK_MODE_100baseT_Half_BIT, | 	ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||||||
| 	ETHTOOL_LINK_MODE_100baseT_Full_BIT, | 	ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
| }; | }; | ||||||
|  | EXPORT_SYMBOL_GPL(phy_10_100_features_array); | ||||||
| 
 | 
 | ||||||
| static const int phy_basic_t1_features_array[] = { | const int phy_basic_t1_features_array[2] = { | ||||||
| 	ETHTOOL_LINK_MODE_TP_BIT, | 	ETHTOOL_LINK_MODE_TP_BIT, | ||||||
| 	ETHTOOL_LINK_MODE_100baseT_Full_BIT, | 	ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
| }; | }; | ||||||
|  | EXPORT_SYMBOL_GPL(phy_basic_t1_features_array); | ||||||
| 
 | 
 | ||||||
| static const int phy_gbit_features_array[] = { | const int phy_gbit_features_array[2] = { | ||||||
| 	ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | 	ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
| 	ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | 	ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
| }; | }; | ||||||
|  | EXPORT_SYMBOL_GPL(phy_gbit_features_array); | ||||||
| 
 | 
 | ||||||
| static const int phy_10gbit_features_array[] = { | const int phy_10gbit_features_array[1] = { | ||||||
| 	ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | 	ETHTOOL_LINK_MODE_10000baseT_Full_BIT, | ||||||
| }; | }; | ||||||
|  | EXPORT_SYMBOL_GPL(phy_10gbit_features_array); | ||||||
| 
 | 
 | ||||||
| __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init; | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init; | ||||||
| EXPORT_SYMBOL_GPL(phy_10gbit_full_features); | EXPORT_SYMBOL_GPL(phy_10gbit_full_features); | ||||||
|  | @ -1441,8 +1448,13 @@ static int genphy_config_advert(struct phy_device *phydev) | ||||||
| 	int err, changed = 0; | 	int err, changed = 0; | ||||||
| 
 | 
 | ||||||
| 	/* Only allow advertising what this PHY supports */ | 	/* Only allow advertising what this PHY supports */ | ||||||
| 	phydev->advertising &= phydev->supported; | 	linkmode_and(phydev->advertising, phydev->advertising, | ||||||
| 	advertise = phydev->advertising; | 		     phydev->supported); | ||||||
|  | 	if (!ethtool_convert_link_mode_to_legacy_u32(&advertise, | ||||||
|  | 						     phydev->advertising)) | ||||||
|  | 		phydev_warn(phydev, "PHY advertising (%*pb) more modes than genphy supports, some modes not advertised.\n", | ||||||
|  | 			    __ETHTOOL_LINK_MODE_MASK_NBITS, | ||||||
|  | 			    phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	/* Setup standard advertisement */ | 	/* Setup standard advertisement */ | ||||||
| 	adv = phy_read(phydev, MII_ADVERTISE); | 	adv = phy_read(phydev, MII_ADVERTISE); | ||||||
|  | @ -1481,10 +1493,11 @@ static int genphy_config_advert(struct phy_device *phydev) | ||||||
| 	oldadv = adv; | 	oldadv = adv; | ||||||
| 	adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | 	adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||||||
| 
 | 
 | ||||||
| 	if (phydev->supported & (SUPPORTED_1000baseT_Half | | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
| 				 SUPPORTED_1000baseT_Full)) { | 			      phydev->supported) || | ||||||
|  | 	    linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 			      phydev->supported)) | ||||||
| 		adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); | 		adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if (adv != oldadv) | 	if (adv != oldadv) | ||||||
| 		changed = 1; | 		changed = 1; | ||||||
|  | @ -1692,8 +1705,10 @@ int genphy_read_status(struct phy_device *phydev) | ||||||
| 	phydev->lp_advertising = 0; | 	phydev->lp_advertising = 0; | ||||||
| 
 | 
 | ||||||
| 	if (AUTONEG_ENABLE == phydev->autoneg) { | 	if (AUTONEG_ENABLE == phydev->autoneg) { | ||||||
| 		if (phydev->supported & (SUPPORTED_1000baseT_Half | 		if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
| 					| SUPPORTED_1000baseT_Full)) { | 				      phydev->supported) || | ||||||
|  | 		    linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				      phydev->supported)) { | ||||||
| 			lpagb = phy_read(phydev, MII_STAT1000); | 			lpagb = phy_read(phydev, MII_STAT1000); | ||||||
| 			if (lpagb < 0) | 			if (lpagb < 0) | ||||||
| 				return lpagb; | 				return lpagb; | ||||||
|  | @ -1800,11 +1815,13 @@ EXPORT_SYMBOL(genphy_soft_reset); | ||||||
| int genphy_config_init(struct phy_device *phydev) | int genphy_config_init(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	int val; | 	int val; | ||||||
| 	u32 features; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(features) = { 0, }; | ||||||
| 
 | 
 | ||||||
| 	features = (SUPPORTED_TP | SUPPORTED_MII | 	linkmode_set_bit_array(phy_basic_ports_array, | ||||||
| 			| SUPPORTED_AUI | SUPPORTED_FIBRE | | 			       ARRAY_SIZE(phy_basic_ports_array), | ||||||
| 			SUPPORTED_BNC | SUPPORTED_Pause | SUPPORTED_Asym_Pause); | 			       features); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, features); | ||||||
|  | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, features); | ||||||
| 
 | 
 | ||||||
| 	/* Do we support autonegotiation? */ | 	/* Do we support autonegotiation? */ | ||||||
| 	val = phy_read(phydev, MII_BMSR); | 	val = phy_read(phydev, MII_BMSR); | ||||||
|  | @ -1812,16 +1829,16 @@ int genphy_config_init(struct phy_device *phydev) | ||||||
| 		return val; | 		return val; | ||||||
| 
 | 
 | ||||||
| 	if (val & BMSR_ANEGCAPABLE) | 	if (val & BMSR_ANEGCAPABLE) | ||||||
| 		features |= SUPPORTED_Autoneg; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, features); | ||||||
| 
 | 
 | ||||||
| 	if (val & BMSR_100FULL) | 	if (val & BMSR_100FULL) | ||||||
| 		features |= SUPPORTED_100baseT_Full; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, features); | ||||||
| 	if (val & BMSR_100HALF) | 	if (val & BMSR_100HALF) | ||||||
| 		features |= SUPPORTED_100baseT_Half; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, features); | ||||||
| 	if (val & BMSR_10FULL) | 	if (val & BMSR_10FULL) | ||||||
| 		features |= SUPPORTED_10baseT_Full; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, features); | ||||||
| 	if (val & BMSR_10HALF) | 	if (val & BMSR_10HALF) | ||||||
| 		features |= SUPPORTED_10baseT_Half; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, features); | ||||||
| 
 | 
 | ||||||
| 	if (val & BMSR_ESTATEN) { | 	if (val & BMSR_ESTATEN) { | ||||||
| 		val = phy_read(phydev, MII_ESTATUS); | 		val = phy_read(phydev, MII_ESTATUS); | ||||||
|  | @ -1829,13 +1846,15 @@ int genphy_config_init(struct phy_device *phydev) | ||||||
| 			return val; | 			return val; | ||||||
| 
 | 
 | ||||||
| 		if (val & ESTATUS_1000_TFULL) | 		if (val & ESTATUS_1000_TFULL) | ||||||
| 			features |= SUPPORTED_1000baseT_Full; | 			linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 					 features); | ||||||
| 		if (val & ESTATUS_1000_THALF) | 		if (val & ESTATUS_1000_THALF) | ||||||
| 			features |= SUPPORTED_1000baseT_Half; | 			linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
|  | 					 features); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	phydev->supported &= features; | 	linkmode_and(phydev->supported, phydev->supported, features); | ||||||
| 	phydev->advertising &= features; | 	linkmode_and(phydev->advertising, phydev->advertising, features); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -1879,20 +1898,37 @@ EXPORT_SYMBOL(genphy_loopback); | ||||||
| 
 | 
 | ||||||
| static int __set_phy_supported(struct phy_device *phydev, u32 max_speed) | static int __set_phy_supported(struct phy_device *phydev, u32 max_speed) | ||||||
| { | { | ||||||
| 	phydev->supported &= ~(PHY_1000BT_FEATURES | PHY_100BT_FEATURES | | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(speeds) = { 0, }; | ||||||
| 			       PHY_10BT_FEATURES); | 
 | ||||||
|  | 	linkmode_set_bit_array(phy_10_100_features_array, | ||||||
|  | 			       ARRAY_SIZE(phy_10_100_features_array), | ||||||
|  | 			       speeds); | ||||||
|  | 	linkmode_set_bit_array(phy_gbit_features_array, | ||||||
|  | 			       ARRAY_SIZE(phy_gbit_features_array), | ||||||
|  | 			       speeds); | ||||||
|  | 
 | ||||||
|  | 	linkmode_andnot(phydev->supported, phydev->supported, speeds); | ||||||
| 
 | 
 | ||||||
| 	switch (max_speed) { | 	switch (max_speed) { | ||||||
| 	default: | 	default: | ||||||
| 		return -ENOTSUPP; | 		return -ENOTSUPP; | ||||||
| 	case SPEED_1000: | 	case SPEED_1000: | ||||||
| 		phydev->supported |= PHY_1000BT_FEATURES; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
| 		/* fall through */ | 		/* fall through */ | ||||||
| 	case SPEED_100: | 	case SPEED_100: | ||||||
| 		phydev->supported |= PHY_100BT_FEATURES; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
| 		/* fall through */ | 		/* fall through */ | ||||||
| 	case SPEED_10: | 	case SPEED_10: | ||||||
| 		phydev->supported |= PHY_10BT_FEATURES; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -1906,7 +1942,7 @@ int phy_set_max_speed(struct phy_device *phydev, u32 max_speed) | ||||||
| 	if (err) | 	if (err) | ||||||
| 		return err; | 		return err; | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -1923,10 +1959,8 @@ EXPORT_SYMBOL(phy_set_max_speed); | ||||||
|  */ |  */ | ||||||
| void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode) | void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode) | ||||||
| { | { | ||||||
| 	WARN_ON(link_mode > 31); | 	linkmode_clear_bit(link_mode, phydev->supported); | ||||||
| 
 | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 	phydev->supported &= ~BIT(link_mode); |  | ||||||
| 	phydev->advertising = phydev->supported; |  | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(phy_remove_link_mode); | EXPORT_SYMBOL(phy_remove_link_mode); | ||||||
| 
 | 
 | ||||||
|  | @ -1939,9 +1973,9 @@ EXPORT_SYMBOL(phy_remove_link_mode); | ||||||
|  */ |  */ | ||||||
| void phy_support_sym_pause(struct phy_device *phydev) | void phy_support_sym_pause(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	phydev->supported &= ~SUPPORTED_Asym_Pause; | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported); | ||||||
| 	phydev->supported |= SUPPORTED_Pause; | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(phy_support_sym_pause); | EXPORT_SYMBOL(phy_support_sym_pause); | ||||||
| 
 | 
 | ||||||
|  | @ -1953,8 +1987,9 @@ EXPORT_SYMBOL(phy_support_sym_pause); | ||||||
|  */ |  */ | ||||||
| void phy_support_asym_pause(struct phy_device *phydev) | void phy_support_asym_pause(struct phy_device *phydev) | ||||||
| { | { | ||||||
| 	phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported); | ||||||
|  | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(phy_support_asym_pause); | EXPORT_SYMBOL(phy_support_asym_pause); | ||||||
| 
 | 
 | ||||||
|  | @ -1972,12 +2007,13 @@ EXPORT_SYMBOL(phy_support_asym_pause); | ||||||
| void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx, | void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx, | ||||||
| 		       bool autoneg) | 		       bool autoneg) | ||||||
| { | { | ||||||
| 	phydev->supported &= ~SUPPORTED_Pause; | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	if (rx && tx && autoneg) | 	if (rx && tx && autoneg) | ||||||
| 		phydev->supported |= SUPPORTED_Pause; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(phy_set_sym_pause); | EXPORT_SYMBOL(phy_set_sym_pause); | ||||||
| 
 | 
 | ||||||
|  | @ -1994,20 +2030,29 @@ EXPORT_SYMBOL(phy_set_sym_pause); | ||||||
|  */ |  */ | ||||||
| void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx) | void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx) | ||||||
| { | { | ||||||
| 	u16 oldadv = phydev->advertising; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(oldadv); | ||||||
| 	u16 newadv = oldadv &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause); |  | ||||||
| 
 | 
 | ||||||
| 	if (rx) | 	linkmode_copy(oldadv, phydev->advertising); | ||||||
| 		newadv |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; |  | ||||||
| 	if (tx) |  | ||||||
| 		newadv ^= SUPPORTED_Asym_Pause; |  | ||||||
| 
 | 
 | ||||||
| 	if (oldadv != newadv) { | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
| 		phydev->advertising = newadv; | 			   phydev->advertising); | ||||||
|  | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 			   phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 		if (phydev->autoneg) | 	if (rx) { | ||||||
| 			phy_start_aneg(phydev); | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 				 phydev->advertising); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				 phydev->advertising); | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	if (tx) | ||||||
|  | 		linkmode_change_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				    phydev->advertising); | ||||||
|  | 
 | ||||||
|  | 	if (!linkmode_equal(oldadv, phydev->advertising) && | ||||||
|  | 	    phydev->autoneg) | ||||||
|  | 		phy_start_aneg(phydev); | ||||||
| } | } | ||||||
| EXPORT_SYMBOL(phy_set_asym_pause); | EXPORT_SYMBOL(phy_set_asym_pause); | ||||||
| 
 | 
 | ||||||
|  | @ -2023,8 +2068,10 @@ EXPORT_SYMBOL(phy_set_asym_pause); | ||||||
| bool phy_validate_pause(struct phy_device *phydev, | bool phy_validate_pause(struct phy_device *phydev, | ||||||
| 			struct ethtool_pauseparam *pp) | 			struct ethtool_pauseparam *pp) | ||||||
| { | { | ||||||
| 	if (!(phydev->supported & SUPPORTED_Pause) || | 	if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
| 	    (!(phydev->supported & SUPPORTED_Asym_Pause) && | 			       phydev->supported) || | ||||||
|  | 	    (!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				phydev->supported) && | ||||||
| 	     pp->rx_pause != pp->tx_pause)) | 	     pp->rx_pause != pp->tx_pause)) | ||||||
| 		return false; | 		return false; | ||||||
| 	return true; | 	return true; | ||||||
|  | @ -2112,9 +2159,9 @@ static int phy_probe(struct device *dev) | ||||||
| 	 * or both of these values | 	 * or both of these values | ||||||
| 	 */ | 	 */ | ||||||
| 	ethtool_convert_link_mode_to_legacy_u32(&features, phydrv->features); | 	ethtool_convert_link_mode_to_legacy_u32(&features, phydrv->features); | ||||||
| 	phydev->supported = features; | 	linkmode_copy(phydev->supported, phydrv->features); | ||||||
| 	of_set_phy_supported(phydev); | 	of_set_phy_supported(phydev); | ||||||
| 	phydev->advertising = phydev->supported; | 	linkmode_copy(phydev->advertising, phydev->supported); | ||||||
| 
 | 
 | ||||||
| 	/* Get the EEE modes we want to prohibit. We will ask
 | 	/* Get the EEE modes we want to prohibit. We will ask
 | ||||||
| 	 * the PHY stop advertising these mode later on | 	 * the PHY stop advertising these mode later on | ||||||
|  | @ -2134,14 +2181,22 @@ static int phy_probe(struct device *dev) | ||||||
| 	 */ | 	 */ | ||||||
| 	if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) || | 	if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features) || | ||||||
| 	    test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) { | 	    test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydrv->features)) { | ||||||
| 		phydev->supported &= ~(SUPPORTED_Pause | SUPPORTED_Asym_Pause); | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 				   phydev->supported); | ||||||
|  | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				   phydev->supported); | ||||||
| 		if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features)) | 		if (test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydrv->features)) | ||||||
| 			phydev->supported |= SUPPORTED_Pause; | 			linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 					 phydev->supported); | ||||||
| 		if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | 		if (test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
| 			     phydrv->features)) | 			     phydrv->features)) | ||||||
| 			phydev->supported |= SUPPORTED_Asym_Pause; | 			linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 					 phydev->supported); | ||||||
| 	} else { | 	} else { | ||||||
| 		phydev->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause; | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
|  | 		linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 				 phydev->supported); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/* Set the state to READY by default */ | 	/* Set the state to READY by default */ | ||||||
|  |  | ||||||
|  | @ -191,8 +191,7 @@ static int phylink_parse_fixedlink(struct phylink *pl, | ||||||
| 	phylink_validate(pl, pl->supported, &pl->link_config); | 	phylink_validate(pl, pl->supported, &pl->link_config); | ||||||
| 
 | 
 | ||||||
| 	s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, | 	s = phy_lookup_setting(pl->link_config.speed, pl->link_config.duplex, | ||||||
| 			       pl->supported, | 			       pl->supported, true); | ||||||
| 			       __ETHTOOL_LINK_MODE_MASK_NBITS, true); |  | ||||||
| 	linkmode_zero(pl->supported); | 	linkmode_zero(pl->supported); | ||||||
| 	phylink_set(pl->supported, MII); | 	phylink_set(pl->supported, MII); | ||||||
| 	if (s) { | 	if (s) { | ||||||
|  | @ -634,13 +633,11 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy) | ||||||
| { | { | ||||||
| 	struct phylink_link_state config; | 	struct phylink_link_state config; | ||||||
| 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported); | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported); | ||||||
| 	u32 advertising; |  | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
| 	memset(&config, 0, sizeof(config)); | 	memset(&config, 0, sizeof(config)); | ||||||
| 	ethtool_convert_legacy_u32_to_link_mode(supported, phy->supported); | 	linkmode_copy(supported, phy->supported); | ||||||
| 	ethtool_convert_legacy_u32_to_link_mode(config.advertising, | 	linkmode_copy(config.advertising, phy->advertising); | ||||||
| 						phy->advertising); |  | ||||||
| 	config.interface = pl->link_config.interface; | 	config.interface = pl->link_config.interface; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
|  | @ -673,15 +670,14 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy) | ||||||
| 	linkmode_copy(pl->link_config.advertising, config.advertising); | 	linkmode_copy(pl->link_config.advertising, config.advertising); | ||||||
| 
 | 
 | ||||||
| 	/* Restrict the phy advertisement according to the MAC support. */ | 	/* Restrict the phy advertisement according to the MAC support. */ | ||||||
| 	ethtool_convert_link_mode_to_legacy_u32(&advertising, config.advertising); | 	linkmode_copy(phy->advertising, config.advertising); | ||||||
| 	phy->advertising = advertising; |  | ||||||
| 	mutex_unlock(&pl->state_mutex); | 	mutex_unlock(&pl->state_mutex); | ||||||
| 	mutex_unlock(&phy->lock); | 	mutex_unlock(&phy->lock); | ||||||
| 
 | 
 | ||||||
| 	netdev_dbg(pl->netdev, | 	netdev_dbg(pl->netdev, | ||||||
| 		   "phy: setting supported %*pb advertising 0x%08x\n", | 		   "phy: setting supported %*pb advertising %*pb\n", | ||||||
| 		   __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, | 		   __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, | ||||||
| 		   phy->advertising); | 		   __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); | ||||||
| 
 | 
 | ||||||
| 	phy_start_machine(phy); | 	phy_start_machine(phy); | ||||||
| 	if (phy->irq > 0) | 	if (phy->irq > 0) | ||||||
|  | @ -1088,8 +1084,7 @@ int phylink_ethtool_ksettings_set(struct phylink *pl, | ||||||
| 		 * duplex. | 		 * duplex. | ||||||
| 		 */ | 		 */ | ||||||
| 		s = phy_lookup_setting(kset->base.speed, kset->base.duplex, | 		s = phy_lookup_setting(kset->base.speed, kset->base.duplex, | ||||||
| 				       pl->supported, | 				       pl->supported, false); | ||||||
| 				       __ETHTOOL_LINK_MODE_MASK_NBITS, false); |  | ||||||
| 		if (!s) | 		if (!s) | ||||||
| 			return -EINVAL; | 			return -EINVAL; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ | ||||||
| #include <linux/slab.h> | #include <linux/slab.h> | ||||||
| #include <linux/if_vlan.h> | #include <linux/if_vlan.h> | ||||||
| #include <linux/uaccess.h> | #include <linux/uaccess.h> | ||||||
|  | #include <linux/linkmode.h> | ||||||
| #include <linux/list.h> | #include <linux/list.h> | ||||||
| #include <linux/ip.h> | #include <linux/ip.h> | ||||||
| #include <linux/ipv6.h> | #include <linux/ipv6.h> | ||||||
|  | @ -1586,18 +1587,17 @@ static int lan78xx_set_pause(struct net_device *net, | ||||||
| 		dev->fc_request_control |= FLOW_CTRL_TX; | 		dev->fc_request_control |= FLOW_CTRL_TX; | ||||||
| 
 | 
 | ||||||
| 	if (ecmd.base.autoneg) { | 	if (ecmd.base.autoneg) { | ||||||
|  | 		__ETHTOOL_DECLARE_LINK_MODE_MASK(fc) = { 0, }; | ||||||
| 		u32 mii_adv; | 		u32 mii_adv; | ||||||
| 		u32 advertising; |  | ||||||
| 
 | 
 | ||||||
| 		ethtool_convert_link_mode_to_legacy_u32( | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
| 			&advertising, ecmd.link_modes.advertising); | 				   ecmd.link_modes.advertising); | ||||||
| 
 | 		linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
| 		advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); | 				   ecmd.link_modes.advertising); | ||||||
| 		mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control); | 		mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control); | ||||||
| 		advertising |= mii_adv_to_ethtool_adv_t(mii_adv); | 		mii_adv_to_linkmode_adv_t(fc, mii_adv); | ||||||
| 
 | 		linkmode_or(ecmd.link_modes.advertising, fc, | ||||||
| 		ethtool_convert_legacy_u32_to_link_mode( | 			    ecmd.link_modes.advertising); | ||||||
| 			ecmd.link_modes.advertising, advertising); |  | ||||||
| 
 | 
 | ||||||
| 		phy_ethtool_ksettings_set(phydev, &ecmd); | 		phy_ethtool_ksettings_set(phydev, &ecmd); | ||||||
| 	} | 	} | ||||||
|  | @ -2095,6 +2095,7 @@ static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev) | ||||||
| 
 | 
 | ||||||
| static int lan78xx_phy_init(struct lan78xx_net *dev) | static int lan78xx_phy_init(struct lan78xx_net *dev) | ||||||
| { | { | ||||||
|  | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(fc) = { 0, }; | ||||||
| 	int ret; | 	int ret; | ||||||
| 	u32 mii_adv; | 	u32 mii_adv; | ||||||
| 	struct phy_device *phydev; | 	struct phy_device *phydev; | ||||||
|  | @ -2158,9 +2159,13 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) | ||||||
| 
 | 
 | ||||||
| 	/* support both flow controls */ | 	/* support both flow controls */ | ||||||
| 	dev->fc_request_control = (FLOW_CTRL_RX | FLOW_CTRL_TX); | 	dev->fc_request_control = (FLOW_CTRL_RX | FLOW_CTRL_TX); | ||||||
| 	phydev->advertising &= ~(ADVERTISED_Pause | ADVERTISED_Asym_Pause); | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 			   phydev->advertising); | ||||||
|  | 	linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, | ||||||
|  | 			   phydev->advertising); | ||||||
| 	mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control); | 	mii_adv = (u32)mii_advertise_flowctrl(dev->fc_request_control); | ||||||
| 	phydev->advertising |= mii_adv_to_ethtool_adv_t(mii_adv); | 	mii_adv_to_linkmode_adv_t(fc, mii_adv); | ||||||
|  | 	linkmode_or(phydev->advertising, fc, phydev->advertising); | ||||||
| 
 | 
 | ||||||
| 	if (phydev->mdio.dev.of_node) { | 	if (phydev->mdio.dev.of_node) { | ||||||
| 		u32 reg; | 		u32 reg; | ||||||
|  |  | ||||||
|  | @ -385,19 +385,21 @@ static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * ethtool_adv_to_lcl_adv_t |  * linkmode_adv_to_lcl_adv_t | ||||||
|  * @advertising:pointer to ethtool advertising |  * @advertising:pointer to linkmode advertising | ||||||
|  * |  * | ||||||
|  * A small helper function that translates ethtool advertising to LVL |  * A small helper function that translates linkmode advertising to LVL | ||||||
|  * pause capabilities. |  * pause capabilities. | ||||||
|  */ |  */ | ||||||
| static inline u32 ethtool_adv_to_lcl_adv_t(u32 advertising) | static inline u32 linkmode_adv_to_lcl_adv_t(unsigned long *advertising) | ||||||
| { | { | ||||||
| 	u32 lcl_adv = 0; | 	u32 lcl_adv = 0; | ||||||
| 
 | 
 | ||||||
| 	if (advertising & ADVERTISED_Pause) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 			      advertising)) | ||||||
| 		lcl_adv |= ADVERTISE_PAUSE_CAP; | 		lcl_adv |= ADVERTISE_PAUSE_CAP; | ||||||
| 	if (advertising & ADVERTISED_Asym_Pause) | 	if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, | ||||||
|  | 			      advertising)) | ||||||
| 		lcl_adv |= ADVERTISE_PAUSE_ASYM; | 		lcl_adv |= ADVERTISE_PAUSE_ASYM; | ||||||
| 
 | 
 | ||||||
| 	return lcl_adv; | 	return lcl_adv; | ||||||
|  |  | ||||||
|  | @ -58,6 +58,11 @@ extern __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_ini | ||||||
| #define PHY_10GBIT_FEATURES ((unsigned long *)&phy_10gbit_features) | #define PHY_10GBIT_FEATURES ((unsigned long *)&phy_10gbit_features) | ||||||
| #define PHY_10GBIT_FULL_FEATURES ((unsigned long *)&phy_10gbit_full_features) | #define PHY_10GBIT_FULL_FEATURES ((unsigned long *)&phy_10gbit_full_features) | ||||||
| 
 | 
 | ||||||
|  | extern const int phy_10_100_features_array[4]; | ||||||
|  | extern const int phy_basic_t1_features_array[2]; | ||||||
|  | extern const int phy_gbit_features_array[2]; | ||||||
|  | extern const int phy_10gbit_features_array[1]; | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Set phydev->irq to PHY_POLL if interrupts are not supported, |  * Set phydev->irq to PHY_POLL if interrupts are not supported, | ||||||
|  * or not desired for this PHY.  Set to PHY_IGNORE_INTERRUPT if |  * or not desired for this PHY.  Set to PHY_IGNORE_INTERRUPT if | ||||||
|  | @ -405,10 +410,11 @@ struct phy_device { | ||||||
| 	int pause; | 	int pause; | ||||||
| 	int asym_pause; | 	int asym_pause; | ||||||
| 
 | 
 | ||||||
| 	/* Union of PHY and Attached devices' supported modes */ | 	/* Union of PHY and Attached devices' supported link modes */ | ||||||
| 	/* See mii.h for more info */ | 	/* See ethtool.h for more info */ | ||||||
| 	u32 supported; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported); | ||||||
| 	u32 advertising; | 	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising); | ||||||
|  | 
 | ||||||
| 	u32 lp_advertising; | 	u32 lp_advertising; | ||||||
| 
 | 
 | ||||||
| 	/* Energy efficient ethernet modes which should be prohibited */ | 	/* Energy efficient ethernet modes which should be prohibited */ | ||||||
|  | @ -660,9 +666,9 @@ struct phy_setting { | ||||||
| 
 | 
 | ||||||
| const struct phy_setting * | const struct phy_setting * | ||||||
| phy_lookup_setting(int speed, int duplex, const unsigned long *mask, | phy_lookup_setting(int speed, int duplex, const unsigned long *mask, | ||||||
| 		   size_t maxbit, bool exact); | 		   bool exact); | ||||||
| size_t phy_speeds(unsigned int *speeds, size_t size, | size_t phy_speeds(unsigned int *speeds, size_t size, | ||||||
| 		  unsigned long *mask, size_t maxbit); | 		  unsigned long *mask); | ||||||
| 
 | 
 | ||||||
| void phy_resolve_aneg_linkmode(struct phy_device *phydev); | void phy_resolve_aneg_linkmode(struct phy_device *phydev); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Andrew Lunn
						Andrew Lunn