mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-03 14:34:27 -05:00 
			
		
		
		
	* properly format/comment all patches * merge debloat patches * merge Kconfig patches * merge swconfig patches * merge hotplug patches * drop 200-fix_localversion.patch - upstream * drop 222-arm_zimage_none.patch - unused * drop 252-mv_cesa_depends.patch - no longer required * drop 410-mtd-move-forward-declaration-of-struct-mtd_info.patch - unused * drop 661-fq_codel_keep_dropped_stats.patch - outdated * drop 702-phy_add_aneg_done_function.patch - upstream * drop 840-rtc7301.patch - unused * drop 841-rtc_pt7c4338.patch - upstream * drop 921-use_preinit_as_init.patch - unused * drop spio-gpio-old and gpio-mmc - unused Signed-off-by: John Crispin <john@phrozen.org>
		
			
				
	
	
		
			126 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			126 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
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
 | 
						|
@@ -37,4 +37,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
 |