net: Add ethtool to mii advertisment conversion helpers

Translating between ethtool advertisement settings and MII
advertisements are common operations for ethernet drivers.  This patch
adds a set of helper functions that implements the conversion.  The
patch then modifies a couple of the drivers to use the new functions.

Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Matt Carlson 2011-11-16 18:36:59 -05:00 committed by David S. Miller
parent f85fa27913
commit 28011cf19b
6 changed files with 196 additions and 119 deletions

View file

@ -9,6 +9,7 @@
#define __LINUX_MII_H__
#include <linux/types.h>
#include <linux/ethtool.h>
/* Generic MII registers. */
#define MII_BMCR 0x00 /* Basic mode control register */
@ -239,6 +240,171 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock,
return 0;
}
/**
* ethtool_adv_to_mii_100bt
* @ethadv: the ethtool advertisement settings
*
* A small helper function that translates ethtool advertisement
* settings to phy autonegotiation advertisements for the
* MII_ADVERTISE register.
*/
static inline u32 ethtool_adv_to_mii_100bt(u32 ethadv)
{
u32 result = 0;
if (ethadv & ADVERTISED_10baseT_Half)
result |= ADVERTISE_10HALF;
if (ethadv & ADVERTISED_10baseT_Full)
result |= ADVERTISE_10FULL;
if (ethadv & ADVERTISED_100baseT_Half)
result |= ADVERTISE_100HALF;
if (ethadv & ADVERTISED_100baseT_Full)
result |= ADVERTISE_100FULL;
if (ethadv & ADVERTISED_Pause)
result |= ADVERTISE_PAUSE_CAP;
if (ethadv & ADVERTISED_Asym_Pause)
result |= ADVERTISE_PAUSE_ASYM;
return result;
}
/**
* mii_adv_to_ethtool_100bt
* @adv: value of the MII_ADVERTISE register
*
* A small helper function that translates MII_ADVERTISE bits
* to ethtool advertisement settings.
*/
static inline u32 mii_adv_to_ethtool_100bt(u32 adv)
{
u32 result = 0;
if (adv & ADVERTISE_10HALF)
result |= ADVERTISED_10baseT_Half;
if (adv & ADVERTISE_10FULL)
result |= ADVERTISED_10baseT_Full;
if (adv & ADVERTISE_100HALF)
result |= ADVERTISED_100baseT_Half;
if (adv & ADVERTISE_100FULL)
result |= ADVERTISED_100baseT_Full;
if (adv & ADVERTISE_PAUSE_CAP)
result |= ADVERTISED_Pause;
if (adv & ADVERTISE_PAUSE_ASYM)
result |= ADVERTISED_Asym_Pause;
return result;
}
/**
* ethtool_adv_to_mii_1000T
* @ethadv: the ethtool advertisement settings
*
* A small helper function that translates ethtool advertisement
* settings to phy autonegotiation advertisements for the
* MII_CTRL1000 register when in 1000T mode.
*/
static inline u32 ethtool_adv_to_mii_1000T(u32 ethadv)
{
u32 result = 0;
if (ethadv & ADVERTISED_1000baseT_Half)
result |= ADVERTISE_1000HALF;
if (ethadv & ADVERTISED_1000baseT_Full)
result |= ADVERTISE_1000FULL;
return result;
}
/**
* mii_adv_to_ethtool_1000T
* @adv: value of the MII_CTRL1000 register
*
* A small helper function that translates MII_CTRL1000
* bits, when in 1000Base-T mode, to ethtool
* advertisement settings.
*/
static inline u32 mii_adv_to_ethtool_1000T(u32 adv)
{
u32 result = 0;
if (adv & ADVERTISE_1000HALF)
result |= ADVERTISED_1000baseT_Half;
if (adv & ADVERTISE_1000FULL)
result |= ADVERTISED_1000baseT_Full;
return result;
}
#define mii_lpa_to_ethtool_100bt(lpa) mii_adv_to_ethtool_100bt(lpa)
/**
* mii_lpa_to_ethtool_1000T
* @adv: value of the MII_STAT1000 register
*
* A small helper function that translates MII_STAT1000
* bits, when in 1000Base-T mode, to ethtool
* advertisement settings.
*/
static inline u32 mii_lpa_to_ethtool_1000T(u32 lpa)
{
u32 result = 0;
if (lpa & LPA_1000HALF)
result |= ADVERTISED_1000baseT_Half;
if (lpa & LPA_1000FULL)
result |= ADVERTISED_1000baseT_Full;
return result;
}
/**
* ethtool_adv_to_mii_1000X
* @ethadv: the ethtool advertisement settings
*
* A small helper function that translates ethtool advertisement
* settings to phy autonegotiation advertisements for the
* MII_CTRL1000 register when in 1000Base-X mode.
*/
static inline u32 ethtool_adv_to_mii_1000X(u32 ethadv)
{
u32 result = 0;
if (ethadv & ADVERTISED_1000baseT_Half)
result |= ADVERTISE_1000XHALF;
if (ethadv & ADVERTISED_1000baseT_Full)
result |= ADVERTISE_1000XFULL;
if (ethadv & ADVERTISED_Pause)
result |= ADVERTISE_1000XPAUSE;
if (ethadv & ADVERTISED_Asym_Pause)
result |= ADVERTISE_1000XPSE_ASYM;
return result;
}
/**
* mii_adv_to_ethtool_1000X
* @adv: value of the MII_CTRL1000 register
*
* A small helper function that translates MII_CTRL1000
* bits, when in 1000Base-X mode, to ethtool
* advertisement settings.
*/
static inline u32 mii_adv_to_ethtool_1000X(u32 adv)
{
u32 result = 0;
if (adv & ADVERTISE_1000XHALF)
result |= ADVERTISED_1000baseT_Half;
if (adv & ADVERTISE_1000XFULL)
result |= ADVERTISED_1000baseT_Full;
if (adv & ADVERTISE_1000XPAUSE)
result |= ADVERTISED_Pause;
if (adv & ADVERTISE_1000XPSE_ASYM)
result |= ADVERTISED_Asym_Pause;
return result;
}
/**
* mii_advertise_flowctrl - get flow control advertisement flags
* @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)