/branches/18.06.1/target/linux/generic/backport-4.9/076-v4.11-0002-net-phy-broadcom-Add-support-code-for-reading-PHY-co.patch |
@@ -0,0 +1,125 @@ |
From: Florian Fainelli <f.fainelli@gmail.com> |
Date: Tue, 29 Nov 2016 09:57:17 -0800 |
Subject: [PATCH] net: phy: broadcom: Add support code for reading PHY counters |
|
Broadcom PHYs expose a number of PHY error counters: receive errors, |
false carrier sense, SerDes BER count, local and remote receive errors. |
Add support code to allow retrieving these error counters. Since the |
Broadcom PHY library code is used by several drivers, make it possible |
for them to specify the storage for the software copy of the statistics. |
|
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com> |
Signed-off-by: David S. Miller <davem@davemloft.net> |
--- |
|
--- a/drivers/net/phy/bcm-phy-lib.c |
+++ b/drivers/net/phy/bcm-phy-lib.c |
@@ -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 |
@@ -231,6 +232,75 @@ int bcm_phy_set_eee(struct phy_device *p |
} |
EXPORT_SYMBOL_GPL(bcm_phy_set_eee); |
|
+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"); |
--- a/drivers/net/phy/bcm-phy-lib.h |
+++ b/drivers/net/phy/bcm-phy-lib.h |
@@ -44,4 +44,10 @@ int bcm_phy_config_intr(struct phy_devic |
int bcm_phy_enable_apd(struct phy_device *phydev, bool dll_pwr_down); |
|
int bcm_phy_set_eee(struct phy_device *phydev, bool enable); |
+ |
+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 */ |
--- a/include/linux/brcmphy.h |
+++ b/include/linux/brcmphy.h |
@@ -234,6 +234,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 |