net: phy: broadcom: Add support code for downshift/Wirespeed
Broadcom's Wirespeed feature allows us to configure how auto-negotiation should behave with fewer working pairs of wires on a cable. Add support code for retrieving and setting such downshift counters using the recently added ethtool downshift tunables. Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
5519da874a
Коммит
d06f78c423
|
@ -225,6 +225,92 @@ int bcm_phy_enable_eee(struct phy_device *phydev)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(bcm_phy_enable_eee);
|
||||
|
||||
int bcm_phy_downshift_get(struct phy_device *phydev, u8 *count)
|
||||
{
|
||||
int val;
|
||||
|
||||
val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
/* Check if wirespeed is enabled or not */
|
||||
if (!(val & MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN)) {
|
||||
*count = DOWNSHIFT_DEV_DISABLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR2);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
/* Downgrade after one link attempt */
|
||||
if (val & BCM54XX_SHD_SCR2_WSPD_RTRY_DIS) {
|
||||
*count = 1;
|
||||
} else {
|
||||
/* Downgrade after configured retry count */
|
||||
val >>= BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT;
|
||||
val &= BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK;
|
||||
*count = val + BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcm_phy_downshift_get);
|
||||
|
||||
int bcm_phy_downshift_set(struct phy_device *phydev, u8 count)
|
||||
{
|
||||
int val = 0, ret = 0;
|
||||
|
||||
/* Range check the number given */
|
||||
if (count - BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET >
|
||||
BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK &&
|
||||
count != DOWNSHIFT_DEV_DEFAULT_COUNT) {
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
|
||||
if (val < 0)
|
||||
return val;
|
||||
|
||||
/* Se the write enable bit */
|
||||
val |= MII_BCM54XX_AUXCTL_MISC_WREN;
|
||||
|
||||
if (count == DOWNSHIFT_DEV_DISABLE) {
|
||||
val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN;
|
||||
return bcm54xx_auxctl_write(phydev,
|
||||
MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
|
||||
val);
|
||||
} else {
|
||||
val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN;
|
||||
ret = bcm54xx_auxctl_write(phydev,
|
||||
MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
|
||||
val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR2);
|
||||
val &= ~(BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK <<
|
||||
BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT |
|
||||
BCM54XX_SHD_SCR2_WSPD_RTRY_DIS);
|
||||
|
||||
switch (count) {
|
||||
case 1:
|
||||
val |= BCM54XX_SHD_SCR2_WSPD_RTRY_DIS;
|
||||
break;
|
||||
case DOWNSHIFT_DEV_DEFAULT_COUNT:
|
||||
val |= 1 << BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT;
|
||||
break;
|
||||
default:
|
||||
val |= (count - BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET) <<
|
||||
BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT;
|
||||
break;
|
||||
}
|
||||
|
||||
return bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR2, val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcm_phy_downshift_set);
|
||||
|
||||
MODULE_DESCRIPTION("Broadcom PHY Library");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
|
|
|
@ -37,4 +37,9 @@ int bcm_phy_config_intr(struct phy_device *phydev);
|
|||
int bcm_phy_enable_apd(struct phy_device *phydev, bool dll_pwr_down);
|
||||
|
||||
int bcm_phy_enable_eee(struct phy_device *phydev);
|
||||
|
||||
int bcm_phy_downshift_get(struct phy_device *phydev, u8 *count);
|
||||
|
||||
int bcm_phy_downshift_set(struct phy_device *phydev, u8 count);
|
||||
|
||||
#endif /* _LINUX_BCM_PHY_LIB_H */
|
||||
|
|
|
@ -114,6 +114,7 @@
|
|||
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x0007
|
||||
#define MII_BCM54XX_AUXCTL_SHDWSEL_READ_SHIFT 12
|
||||
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN (1 << 8)
|
||||
#define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN (1 << 4)
|
||||
|
||||
#define MII_BCM54XX_AUXCTL_SHDWSEL_MASK 0x0007
|
||||
|
||||
|
@ -130,6 +131,7 @@
|
|||
#define BCM_LED_SRC_INTR 0x6
|
||||
#define BCM_LED_SRC_QUALITY 0x7
|
||||
#define BCM_LED_SRC_RCVLED 0x8
|
||||
#define BCM_LED_SRC_WIRESPEED 0x9
|
||||
#define BCM_LED_SRC_MULTICOLOR1 0xa
|
||||
#define BCM_LED_SRC_OPENSHORT 0xb
|
||||
#define BCM_LED_SRC_OFF 0xe /* Tied high */
|
||||
|
@ -141,6 +143,14 @@
|
|||
* Shadow values go into bits [14:10] of register 0x1c to select a shadow
|
||||
* register to access.
|
||||
*/
|
||||
|
||||
/* 00100: Reserved control register 2 */
|
||||
#define BCM54XX_SHD_SCR2 0x04
|
||||
#define BCM54XX_SHD_SCR2_WSPD_RTRY_DIS 0x100
|
||||
#define BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_SHIFT 2
|
||||
#define BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_OFFSET 2
|
||||
#define BCM54XX_SHD_SCR2_WSPD_RTRY_LMT_MASK 0x7
|
||||
|
||||
/* 00101: Spare Control Register 3 */
|
||||
#define BCM54XX_SHD_SCR3 0x05
|
||||
#define BCM54XX_SHD_SCR3_DEF_CLK125 0x0001
|
||||
|
|
Загрузка…
Ссылка в новой задаче