Commit 7127f2fe authored by David S. Miller's avatar David S. Miller

Merge branch 'u32-to-linkmode-fixes'

Andrew Lunn says:

====================
u32 to linkmode fixes

This patchset fixes issues found in the last patchset which converted
the phydev advertise etc, from a u32 to a linux bitmap. Most of the
issues are the result of clearing bits which should not of been
cleared. To make the API clearer, the idea from Heiner Kallweit was
used, with _mod_ to indicate the function modifies just the bits it
needs to, or _to_ to clear all bits and just set bit that need to be
set.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b255e500 9db299c7
...@@ -1047,21 +1047,21 @@ static int m88e1145_config_init(struct phy_device *phydev) ...@@ -1047,21 +1047,21 @@ static int m88e1145_config_init(struct phy_device *phydev)
} }
/** /**
* fiber_lpa_to_linkmode_lpa_t * fiber_lpa_mod_linkmode_lpa_t
* @advertising: the linkmode advertisement settings * @advertising: the linkmode advertisement settings
* @lpa: value of the MII_LPA register for fiber link * @lpa: value of the MII_LPA register for fiber link
* *
* A small helper function that translates MII_LPA * A small helper function that translates MII_LPA bits to linkmode LP
* bits to linkmode LP advertisement settings. * advertisement settings. Other bits in advertising are left
* unchanged.
*/ */
static void fiber_lpa_to_linkmode_lpa_t(unsigned long *advertising, u32 lpa) static void fiber_lpa_mod_linkmode_lpa_t(unsigned long *advertising, u32 lpa)
{ {
if (lpa & LPA_FIBER_1000HALF) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising, lpa & LPA_FIBER_1000HALF);
advertising);
if (lpa & LPA_FIBER_1000FULL) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising, lpa & LPA_FIBER_1000FULL);
advertising);
} }
/** /**
...@@ -1138,7 +1138,7 @@ static int marvell_read_status_page_an(struct phy_device *phydev, ...@@ -1138,7 +1138,7 @@ static int marvell_read_status_page_an(struct phy_device *phydev,
if (!fiber) { if (!fiber) {
mii_lpa_to_linkmode_lpa_t(phydev->lp_advertising, lpa); mii_lpa_to_linkmode_lpa_t(phydev->lp_advertising, lpa);
mii_stat1000_to_linkmode_lpa_t(phydev->lp_advertising, lpagb); mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, lpagb);
if (phydev->duplex == DUPLEX_FULL) { if (phydev->duplex == DUPLEX_FULL) {
phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
...@@ -1146,7 +1146,7 @@ static int marvell_read_status_page_an(struct phy_device *phydev, ...@@ -1146,7 +1146,7 @@ static int marvell_read_status_page_an(struct phy_device *phydev,
} }
} else { } else {
/* The fiber link is only 1000M capable */ /* The fiber link is only 1000M capable */
fiber_lpa_to_linkmode_lpa_t(phydev->lp_advertising, lpa); fiber_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
if (phydev->duplex == DUPLEX_FULL) { if (phydev->duplex == DUPLEX_FULL) {
if (!(lpa & LPA_PAUSE_FIBER)) { if (!(lpa & LPA_PAUSE_FIBER)) {
......
...@@ -490,7 +490,7 @@ static int mv3310_read_status(struct phy_device *phydev) ...@@ -490,7 +490,7 @@ static int mv3310_read_status(struct phy_device *phydev)
if (val < 0) if (val < 0)
return val; return val;
mii_stat1000_to_linkmode_lpa_t(phydev->lp_advertising, val); mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
if (phydev->autoneg == AUTONEG_ENABLE) if (phydev->autoneg == AUTONEG_ENABLE)
phy_resolve_aneg_linkmode(phydev); phy_resolve_aneg_linkmode(phydev);
......
...@@ -437,7 +437,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd) ...@@ -437,7 +437,7 @@ int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd)
} }
break; break;
case MII_ADVERTISE: case MII_ADVERTISE:
mii_adv_to_linkmode_adv_t(phydev->advertising, mii_adv_mod_linkmode_adv_t(phydev->advertising,
val); val);
change_autoneg = true; change_autoneg = true;
break; break;
......
...@@ -1739,7 +1739,7 @@ int genphy_read_status(struct phy_device *phydev) ...@@ -1739,7 +1739,7 @@ int genphy_read_status(struct phy_device *phydev)
return -ENOLINK; return -ENOLINK;
} }
mii_stat1000_to_linkmode_lpa_t(phydev->lp_advertising, mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
lpagb); lpagb);
common_adv_gb = lpagb & adv << 2; common_adv_gb = lpagb & adv << 2;
} }
...@@ -1748,7 +1748,7 @@ int genphy_read_status(struct phy_device *phydev) ...@@ -1748,7 +1748,7 @@ int genphy_read_status(struct phy_device *phydev)
if (lpa < 0) if (lpa < 0)
return lpa; return lpa;
mii_lpa_to_linkmode_lpa_t(phydev->lp_advertising, lpa); mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
adv = phy_read(phydev, MII_ADVERTISE); adv = phy_read(phydev, MII_ADVERTISE);
if (adv < 0) if (adv < 0)
......
...@@ -57,6 +57,15 @@ static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr) ...@@ -57,6 +57,15 @@ static inline void linkmode_clear_bit(int nr, volatile unsigned long *addr)
__clear_bit(nr, addr); __clear_bit(nr, addr);
} }
static inline void linkmode_mod_bit(int nr, volatile unsigned long *addr,
int set)
{
if (set)
linkmode_set_bit(nr, addr);
else
linkmode_clear_bit(nr, addr);
}
static inline void linkmode_change_bit(int nr, volatile unsigned long *addr) static inline void linkmode_change_bit(int nr, volatile unsigned long *addr)
{ {
__change_bit(nr, addr); __change_bit(nr, addr);
......
...@@ -288,22 +288,22 @@ static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa) ...@@ -288,22 +288,22 @@ static inline u32 mii_stat1000_to_ethtool_lpa_t(u32 lpa)
} }
/** /**
* mii_stat1000_to_linkmode_lpa_t * mii_stat1000_mod_linkmode_lpa_t
* @advertising: target the linkmode advertisement settings * @advertising: target the linkmode advertisement settings
* @adv: value of the MII_STAT1000 register * @adv: value of the MII_STAT1000 register
* *
* A small helper function that translates MII_STAT1000 bits, when in * A small helper function that translates MII_STAT1000 bits, when in
* 1000Base-T mode, to linkmode advertisement settings. * 1000Base-T mode, to linkmode advertisement settings. Other bits in
* advertising are not changes.
*/ */
static inline void mii_stat1000_to_linkmode_lpa_t(unsigned long *advertising, static inline void mii_stat1000_mod_linkmode_lpa_t(unsigned long *advertising,
u32 lpa) u32 lpa)
{ {
if (lpa & LPA_1000HALF) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, advertising, lpa & LPA_1000HALF);
advertising);
if (lpa & LPA_1000FULL) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, advertising, lpa & LPA_1000FULL);
advertising);
} }
/** /**
...@@ -372,35 +372,51 @@ static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa) ...@@ -372,35 +372,51 @@ static inline u32 mii_lpa_to_ethtool_lpa_x(u32 lpa)
return result | mii_adv_to_ethtool_adv_x(lpa); return result | mii_adv_to_ethtool_adv_x(lpa);
} }
/**
* mii_adv_mod_linkmode_adv_t
* @advertising:pointer to destination link mode.
* @adv: value of the MII_ADVERTISE register
*
* A small helper function that translates MII_ADVERTISE bits to
* linkmode advertisement settings. Leaves other bits unchanged.
*/
static inline void mii_adv_mod_linkmode_adv_t(unsigned long *advertising,
u32 adv)
{
linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
advertising, adv & ADVERTISE_10HALF);
linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
advertising, adv & ADVERTISE_10FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
advertising, adv & ADVERTISE_100HALF);
linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
advertising, adv & ADVERTISE_100FULL);
linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising,
adv & ADVERTISE_PAUSE_CAP);
linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
advertising, adv & ADVERTISE_PAUSE_ASYM);
}
/** /**
* mii_adv_to_linkmode_adv_t * mii_adv_to_linkmode_adv_t
* @advertising:pointer to destination link mode. * @advertising:pointer to destination link mode.
* @adv: value of the MII_ADVERTISE register * @adv: value of the MII_ADVERTISE register
* *
* A small helper function that translates MII_ADVERTISE bits * A small helper function that translates MII_ADVERTISE bits
* to linkmode advertisement settings. * to linkmode advertisement settings. Clears the old value
* of advertising.
*/ */
static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising, static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
u32 adv) u32 adv)
{ {
linkmode_zero(advertising); linkmode_zero(advertising);
if (adv & ADVERTISE_10HALF) mii_adv_mod_linkmode_adv_t(advertising, adv);
linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
advertising);
if (adv & ADVERTISE_10FULL)
linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
advertising);
if (adv & ADVERTISE_100HALF)
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
advertising);
if (adv & ADVERTISE_100FULL)
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
advertising);
if (adv & ADVERTISE_PAUSE_CAP)
linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising);
if (adv & ADVERTISE_PAUSE_ASYM)
linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, advertising);
} }
/** /**
...@@ -408,16 +424,35 @@ static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising, ...@@ -408,16 +424,35 @@ static inline void mii_adv_to_linkmode_adv_t(unsigned long *advertising,
* @adv: value of the MII_LPA register * @adv: value of the MII_LPA register
* *
* A small helper function that translates MII_LPA bits, when in * A small helper function that translates MII_LPA bits, when in
* 1000Base-T mode, to linkmode LP advertisement settings. * 1000Base-T mode, to linkmode LP advertisement settings. Clears the
* old value of advertising
*/ */
static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising, static inline void mii_lpa_to_linkmode_lpa_t(unsigned long *lp_advertising,
u32 lpa) u32 lpa)
{ {
mii_adv_to_linkmode_adv_t(lp_advertising, lpa);
if (lpa & LPA_LPACK) if (lpa & LPA_LPACK)
linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
lp_advertising); lp_advertising);
mii_adv_to_linkmode_adv_t(lp_advertising, lpa); }
/**
* mii_lpa_mod_linkmode_lpa_t
* @adv: value of the MII_LPA register
*
* A small helper function that translates MII_LPA bits, when in
* 1000Base-T mode, to linkmode LP advertisement settings. Leaves
* other bits unchanged.
*/
static inline void mii_lpa_mod_linkmode_lpa_t(unsigned long *lp_advertising,
u32 lpa)
{
mii_adv_mod_linkmode_adv_t(lp_advertising, lpa);
linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
lp_advertising, lpa & LPA_LPACK);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment