linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ansuel Smith <ansuelsmth@gmail.com>
To: Andrew Lunn <andrew@lunn.ch>,
	Vivien Didelot <vivien.didelot@gmail.com>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Vladimir Oltean <olteanv@gmail.com>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	Rob Herring <robh+dt@kernel.org>,
	Heiner Kallweit <hkallweit1@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	netdev@vger.kernel.org (open list:NETWORKING DRIVERS),
	devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND
	FLATTENED DEVICE TREE BINDINGS),
	linux-kernel@vger.kernel.org (open list)
Cc: Ansuel Smith <ansuelsmth@gmail.com>
Subject: [RFC PATCH net-next v5 25/25] net: phy: add support for qca8k switch internal PHY in at803x
Date: Tue, 11 May 2021 04:05:00 +0200	[thread overview]
Message-ID: <20210511020500.17269-26-ansuelsmth@gmail.com> (raw)
In-Reply-To: <20210511020500.17269-1-ansuelsmth@gmail.com>

Since the at803x share the same regs, it's assumed they are based on the
same implementation. Make it part of the at803x PHY driver to skip
having redudant code.
Add initial support for qca8k internal PHYs. The internal PHYs requires
special mmd and debug values to be set based on the switch revision
passwd using the dev_flags. Supports output of idle, receive and eee_wake
errors stats.
Some debug values sets can't be translated as the documentation lacks any
reference about them.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
 drivers/net/phy/Kconfig  |   5 +-
 drivers/net/phy/at803x.c | 132 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 134 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 288bf405ebdb..25511f39b01f 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -247,10 +247,11 @@ config NXP_TJA11XX_PHY
 	  Currently supports the NXP TJA1100 and TJA1101 PHY.
 
 config AT803X_PHY
-	tristate "Qualcomm Atheros AR803X PHYs"
+	tristate "Qualcomm Atheros AR803X PHYs and QCA833x PHYs"
 	depends on REGULATOR
 	help
-	  Currently supports the AR8030, AR8031, AR8033 and AR8035 model
+	  Currently supports the AR8030, AR8031, AR8033, AR8035 and internal
+	  QCA8337(Internal qca8k PHY) model
 
 config QSEMI_PHY
 	tristate "Quality Semiconductor PHYs"
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index d2378a73de6f..6697c9368b40 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -92,10 +92,16 @@
 #define AT803X_DEBUG_REG_5			0x05
 #define AT803X_DEBUG_TX_CLK_DLY_EN		BIT(8)
 
+#define AT803X_DEBUG_REG_3C			0x3C
+
+#define AT803X_DEBUG_REG_3D			0x3D
+
 #define AT803X_DEBUG_REG_1F			0x1F
 #define AT803X_DEBUG_PLL_ON			BIT(2)
 #define AT803X_DEBUG_RGMII_1V8			BIT(3)
 
+#define MDIO_AZ_DEBUG				0x800D
+
 /* AT803x supports either the XTAL input pad, an internal PLL or the
  * DSP as clock reference for the clock output pad. The XTAL reference
  * is only used for 25 MHz output, all other frequencies need the PLL.
@@ -144,6 +150,12 @@
 #define ATH8035_PHY_ID				0x004dd072
 #define AT8030_PHY_ID_MASK			0xffffffef
 
+#define QCA8327_PHY_ID				0x004dd034
+#define QCA8337_PHY_ID				0x004dd036
+#define QCA8K_PHY_ID_MASK			0xffffffff
+
+#define QCA8K_DEVFLAGS_REVISION_MASK		GENMASK(2, 0)
+
 #define AT803X_PAGE_FIBER			0
 #define AT803X_PAGE_COPPER			1
 
@@ -155,6 +167,24 @@ MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
 MODULE_AUTHOR("Matus Ujhelyi");
 MODULE_LICENSE("GPL");
 
+enum stat_access_type {
+	PHY,
+	MMD
+};
+
+struct at803x_hw_stat {
+	const char *string;
+	u8 reg;
+	u32 mask;
+	enum stat_access_type access_type;
+};
+
+static struct at803x_hw_stat at803x_hw_stats[] = {
+	{ "phy_idle_errors", 0xa, GENMASK(7, 0), PHY},
+	{ "phy_receive_errors", 0x15, GENMASK(15, 0), PHY},
+	{ "eee_wake_errors", 0x16, GENMASK(15, 0), MMD},
+};
+
 struct at803x_priv {
 	int flags;
 	u16 clk_25m_reg;
@@ -164,6 +194,7 @@ struct at803x_priv {
 	struct regulator_dev *vddio_rdev;
 	struct regulator_dev *vddh_rdev;
 	struct regulator *vddio;
+	u64 stats[ARRAY_SIZE(at803x_hw_stats)];
 };
 
 struct at803x_context {
@@ -175,6 +206,17 @@ struct at803x_context {
 	u16 led_control;
 };
 
+static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data)
+{
+	int ret;
+
+	ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
+	if (ret < 0)
+		return ret;
+
+	return phy_write(phydev, AT803X_DEBUG_DATA, data);
+}
+
 static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
 {
 	int ret;
@@ -337,6 +379,53 @@ static void at803x_get_wol(struct phy_device *phydev,
 		wol->wolopts |= WAKE_MAGIC;
 }
 
+static int at803x_get_sset_count(struct phy_device *phydev)
+{
+	return ARRAY_SIZE(at803x_hw_stats);
+}
+
+static void at803x_get_strings(struct phy_device *phydev, u8 *data)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) {
+		strscpy(data + i * ETH_GSTRING_LEN,
+			at803x_hw_stats[i].string, ETH_GSTRING_LEN);
+	}
+}
+
+static u64 at803x_get_stat(struct phy_device *phydev, int i)
+{
+	struct at803x_hw_stat stat = at803x_hw_stats[i];
+	struct at803x_priv *priv = phydev->priv;
+	int val;
+	u64 ret;
+
+	if (stat.access_type == MMD)
+		val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg);
+	else
+		val = phy_read(phydev, stat.reg);
+
+	if (val < 0) {
+		ret = U64_MAX;
+	} else {
+		val = val & stat.mask;
+		priv->stats[i] += val;
+		ret = priv->stats[i];
+	}
+
+	return ret;
+}
+
+static void at803x_get_stats(struct phy_device *phydev,
+			     struct ethtool_stats *stats, u64 *data)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++)
+		data[i] = at803x_get_stat(phydev, i);
+}
+
 static int at803x_suspend(struct phy_device *phydev)
 {
 	int value;
@@ -1172,6 +1261,34 @@ static int at803x_cable_test_start(struct phy_device *phydev)
 	return 0;
 }
 
+static int qca83xx_config_init(struct phy_device *phydev)
+{
+	u8 switch_revision;
+
+	switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK;
+
+	switch (switch_revision) {
+	case 1:
+		/* For 100M waveform */
+		at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_0, 0x02ea);
+		/* Turn on Gigabit clock */
+		at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x68a0);
+		break;
+
+	case 2:
+		phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0);
+		fallthrough;
+	case 4:
+		phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f);
+		at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3D, 0x6860);
+		at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_5, 0x2c46);
+		at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000);
+		break;
+	}
+
+	return 0;
+}
+
 static struct phy_driver at803x_driver[] = {
 {
 	/* Qualcomm Atheros AR8035 */
@@ -1268,7 +1385,20 @@ static struct phy_driver at803x_driver[] = {
 	.read_status		= at803x_read_status,
 	.soft_reset		= genphy_soft_reset,
 	.config_aneg		= at803x_config_aneg,
-} };
+}, {
+	/* QCA8337 */
+	.phy_id = QCA8337_PHY_ID,
+	.phy_id_mask = QCA8K_PHY_ID_MASK,
+	.name = "QCA PHY 8337",
+	/* PHY_GBIT_FEATURES */
+	.probe = at803x_probe,
+	.flags = PHY_IS_INTERNAL,
+	.config_init = qca83xx_config_init,
+	.soft_reset = genphy_soft_reset,
+	.get_sset_count = at803x_get_sset_count,
+	.get_strings = at803x_get_strings,
+	.get_stats = at803x_get_stats,
+}, };
 
 module_phy_driver(at803x_driver);
 
-- 
2.30.2


      parent reply	other threads:[~2021-05-11  2:11 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-11  2:04 [RFC PATCH net-next v5 00/25] Multiple improvement to qca8k stability Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 01/25] net: dsa: qca8k: change simple print to dev variant Ansuel Smith
2021-05-14 16:35   ` Andrew Lunn
2021-05-11  2:04 ` [RFC PATCH net-next v5 02/25] net: dsa: qca8k: use iopoll macro for qca8k_busy_wait Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 03/25] net: dsa: qca8k: improve qca8k read/write/rmw bus access Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 04/25] net: dsa: qca8k: handle qca8k_set_page errors Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 05/25] net: dsa: qca8k: handle error with qca8k_read operation Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 06/25] net: dsa: qca8k: handle error with qca8k_write operation Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 07/25] net: dsa: qca8k: handle error with qca8k_rmw operation Ansuel Smith
2021-05-14 16:43   ` Andrew Lunn
2021-05-11  2:04 ` [RFC PATCH net-next v5 08/25] net: dsa: qca8k: handle error from qca8k_busy_wait Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 09/25] net: dsa: qca8k: add support for qca8327 switch Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 10/25] devicetree: net: dsa: qca8k: Document new compatible qca8327 Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 11/25] net: dsa: qca8k: add priority tweak to qca8337 switch Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 12/25] net: dsa: qca8k: limit port5 delay to qca8337 Ansuel Smith
2021-05-14 16:45   ` Andrew Lunn
2021-05-11  2:04 ` [RFC PATCH net-next v5 13/25] net: dsa: qca8k: add GLOBAL_FC settings needed for qca8327 Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 14/25] net: dsa: qca8k: add support for switch rev Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 15/25] net: dsa: qca8k: add ethernet-ports fallback to setup_mdio_bus Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 16/25] net: dsa: qca8k: make rgmii delay configurable Ansuel Smith
2021-05-14 16:55   ` Andrew Lunn
2021-05-11  2:04 ` [RFC PATCH net-next v5 17/25] net: dsa: qca8k: clear MASTER_EN after phy read/write Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 18/25] net: dsa: qca8k: dsa: qca8k: protect MASTER busy_wait with mdio mutex Ansuel Smith
2021-05-14 16:58   ` Andrew Lunn
2021-05-11  2:04 ` [RFC PATCH net-next v5 19/25] net: dsa: qca8k: enlarge mdio delay and timeout Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 20/25] net: dsa: qca8k: add support for internal phy and internal mdio Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 21/25] devicetree: bindings: dsa: qca8k: Document internal mdio definition Ansuel Smith
2021-05-11 16:23   ` Rob Herring
2021-05-11  2:04 ` [RFC PATCH net-next v5 22/25] net: dsa: qca8k: improve internal mdio read/write bus access Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 23/25] net: dsa: qca8k: pass switch_revision info to phy dev_flags Ansuel Smith
2021-05-11  2:04 ` [RFC PATCH net-next v5 24/25] net: phy: at803x: clean whitespace errors Ansuel Smith
2021-05-11  2:05 ` Ansuel Smith [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210511020500.17269-26-ansuelsmth@gmail.com \
    --to=ansuelsmth@gmail.com \
    --cc=andrew@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=devicetree@vger.kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=hkallweit1@gmail.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=netdev@vger.kernel.org \
    --cc=olteanv@gmail.com \
    --cc=robh+dt@kernel.org \
    --cc=vivien.didelot@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).