mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
Merge branch 'broadcom-phy-internal-counters'
Florian Fainelli says: ==================== net: phy: broadcom: Support for PHY counters This patch series adds support for reading the Broadcom PHYs internal counters. Changes in v3: - fixed the allocation of priv->stats in bcm7xxx Changes in v2: - fixed modular build reported by kbuild - constify array of stats ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
0f29f05bd7
@ -17,6 +17,7 @@
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
#define MII_BCM_CHANNEL_WIDTH 0x2000
|
||||
#define BCM_CL45VEN_EEE_ADV 0x3c
|
||||
@ -317,6 +318,75 @@ int bcm_phy_downshift_set(struct phy_device *phydev, u8 count)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcm_phy_downshift_set);
|
||||
|
||||
struct bcm_phy_hw_stat {
|
||||
const char *string;
|
||||
u8 reg;
|
||||
u8 shift;
|
||||
u8 bits;
|
||||
};
|
||||
|
||||
/* Counters freeze at either 0xffff or 0xff, better than nothing */
|
||||
static const struct bcm_phy_hw_stat bcm_phy_hw_stats[] = {
|
||||
{ "phy_receive_errors", MII_BRCM_CORE_BASE12, 0, 16 },
|
||||
{ "phy_serdes_ber_errors", MII_BRCM_CORE_BASE13, 8, 8 },
|
||||
{ "phy_false_carrier_sense_errors", MII_BRCM_CORE_BASE13, 0, 8 },
|
||||
{ "phy_local_rcvr_nok", MII_BRCM_CORE_BASE14, 8, 8 },
|
||||
{ "phy_remote_rcv_nok", MII_BRCM_CORE_BASE14, 0, 8 },
|
||||
};
|
||||
|
||||
int bcm_phy_get_sset_count(struct phy_device *phydev)
|
||||
{
|
||||
return ARRAY_SIZE(bcm_phy_hw_stats);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcm_phy_get_sset_count);
|
||||
|
||||
void bcm_phy_get_strings(struct phy_device *phydev, u8 *data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
|
||||
memcpy(data + i * ETH_GSTRING_LEN,
|
||||
bcm_phy_hw_stats[i].string, ETH_GSTRING_LEN);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcm_phy_get_strings);
|
||||
|
||||
#ifndef UINT64_MAX
|
||||
#define UINT64_MAX (u64)(~((u64)0))
|
||||
#endif
|
||||
|
||||
/* Caller is supposed to provide appropriate storage for the library code to
|
||||
* access the shadow copy
|
||||
*/
|
||||
static u64 bcm_phy_get_stat(struct phy_device *phydev, u64 *shadow,
|
||||
unsigned int i)
|
||||
{
|
||||
struct bcm_phy_hw_stat stat = bcm_phy_hw_stats[i];
|
||||
int val;
|
||||
u64 ret;
|
||||
|
||||
val = phy_read(phydev, stat.reg);
|
||||
if (val < 0) {
|
||||
ret = UINT64_MAX;
|
||||
} else {
|
||||
val >>= stat.shift;
|
||||
val = val & ((1 << stat.bits) - 1);
|
||||
shadow[i] += val;
|
||||
ret = shadow[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow,
|
||||
struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bcm_phy_hw_stats); i++)
|
||||
data[i] = bcm_phy_get_stat(phydev, shadow, i);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcm_phy_get_stats);
|
||||
|
||||
MODULE_DESCRIPTION("Broadcom PHY Library");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
|
@ -42,4 +42,9 @@ int bcm_phy_downshift_get(struct phy_device *phydev, u8 *count);
|
||||
|
||||
int bcm_phy_downshift_set(struct phy_device *phydev, u8 count);
|
||||
|
||||
int bcm_phy_get_sset_count(struct phy_device *phydev);
|
||||
void bcm_phy_get_strings(struct phy_device *phydev, u8 *data);
|
||||
void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow,
|
||||
struct ethtool_stats *stats, u64 *data);
|
||||
|
||||
#endif /* _LINUX_BCM_PHY_LIB_H */
|
||||
|
@ -45,6 +45,10 @@
|
||||
#define AFE_VDAC_OTHERS_0 MISC_ADDR(0x39, 3)
|
||||
#define AFE_HPF_TRIM_OTHERS MISC_ADDR(0x3a, 0)
|
||||
|
||||
struct bcm7xxx_phy_priv {
|
||||
u64 *stats;
|
||||
};
|
||||
|
||||
static void r_rc_cal_reset(struct phy_device *phydev)
|
||||
{
|
||||
/* Reset R_CAL/RC_CAL Engine */
|
||||
@ -350,6 +354,33 @@ static int bcm7xxx_28nm_set_tunable(struct phy_device *phydev,
|
||||
return genphy_restart_aneg(phydev);
|
||||
}
|
||||
|
||||
static void bcm7xxx_28nm_get_phy_stats(struct phy_device *phydev,
|
||||
struct ethtool_stats *stats, u64 *data)
|
||||
{
|
||||
struct bcm7xxx_phy_priv *priv = phydev->priv;
|
||||
|
||||
bcm_phy_get_stats(phydev, priv->stats, stats, data);
|
||||
}
|
||||
|
||||
static int bcm7xxx_28nm_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct bcm7xxx_phy_priv *priv;
|
||||
|
||||
priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
phydev->priv = priv;
|
||||
|
||||
priv->stats = devm_kcalloc(&phydev->mdio.dev,
|
||||
bcm_phy_get_sset_count(phydev), sizeof(u64),
|
||||
GFP_KERNEL);
|
||||
if (!priv->stats)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define BCM7XXX_28NM_GPHY(_oui, _name) \
|
||||
{ \
|
||||
.phy_id = (_oui), \
|
||||
@ -364,6 +395,10 @@ static int bcm7xxx_28nm_set_tunable(struct phy_device *phydev,
|
||||
.resume = bcm7xxx_28nm_resume, \
|
||||
.get_tunable = bcm7xxx_28nm_get_tunable, \
|
||||
.set_tunable = bcm7xxx_28nm_set_tunable, \
|
||||
.get_sset_count = bcm_phy_get_sset_count, \
|
||||
.get_strings = bcm_phy_get_strings, \
|
||||
.get_stats = bcm7xxx_28nm_get_phy_stats, \
|
||||
.probe = bcm7xxx_28nm_probe, \
|
||||
}
|
||||
|
||||
#define BCM7XXX_40NM_EPHY(_oui, _name) \
|
||||
|
@ -244,6 +244,9 @@
|
||||
#define LPI_FEATURE_EN_DIG1000X 0x4000
|
||||
|
||||
/* Core register definitions*/
|
||||
#define MII_BRCM_CORE_BASE12 0x12
|
||||
#define MII_BRCM_CORE_BASE13 0x13
|
||||
#define MII_BRCM_CORE_BASE14 0x14
|
||||
#define MII_BRCM_CORE_BASE1E 0x1E
|
||||
#define MII_BRCM_CORE_EXPB0 0xB0
|
||||
#define MII_BRCM_CORE_EXPB1 0xB1
|
||||
|
Loading…
Reference in New Issue
Block a user