All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v1 00/14] Add TJA1120 support
@ 2023-06-16 13:53 Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling Radu Pirea (NXP OSS)
                   ` (13 more replies)
  0 siblings, 14 replies; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

Hello everyone,

This patch series got bigger than I expected. It cleans up the
next-c45-tja11xx driver and adds support for the TJA1120(1000BaseT1
automotive phy).

Master/slave custom implementation was replaced with the generic
implementation (genphy_c45_config_aneg/genphy_c45_read_status).

The TJA1120 and TJA1103 are a bit different when it comes to the PTP
interface. The timestamp read procedure was changed, some addresses were
changed and some bits were moved from one register to another. Adding
TJA1120 support was tricky, and I tried not to duplicate the code. If
something looks too hacky to you, I am open to suggestions.

Cheers,
Radu P

Radu Pirea (NXP OSS) (14):
  net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling
  net: phy: nxp-c45-tja11xx: use phylib master/slave implementation
  net: phy: nxp-c45-tja11xx: remove RX BIST frame counters
  net: phy: nxp-c45-tja11xx: add *_reg_field functions
  net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120
  net: phy: add 1000baseT1 to phy_basic_t1_features
  net: phy: nxp-c45-tja11xx: add TJA1120 support
  net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges
  net: phy: nxp-c45-tja11xx: read egress ts on TJA1120
  net: phy: nxp-c45-tja11xx: handle FUSA irq
  net: phy: nxp-c45-tja11xx: run cable test with the PHY in test mode
  net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120
  net: phy: nxp-c45-tja11xx: reset PCS if the link goes down
  net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120

 drivers/net/phy/Kconfig           |    2 +-
 drivers/net/phy/nxp-c45-tja11xx.c | 1113 ++++++++++++++++++++++-------
 drivers/net/phy/phy_device.c      |    3 +-
 include/linux/phy.h               |    2 +-
 4 files changed, 846 insertions(+), 274 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 20:36   ` Andrew Lunn
  2023-06-16 13:53 ` [PATCH net-next v1 02/14] net: phy: nxp-c45-tja11xx: use phylib master/slave implementation Radu Pirea (NXP OSS)
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS), stable

.config_intr() handles only the link event interrupt and should
disable/enable the PTP interrupt also.

It's safe to disable/enable the PTP irq even if the egress ts irq
is disabled. This interrupt, the PTP one, acts as a global switch for all
PTP irqs.

Fixes: 514def5dd339 ("phy: nxp-c45-tja11xx: add timestamping support")
CC: stable@vger.kernel.org # 5.15+
Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 029875a59ff8..7b213c3f4536 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -63,6 +63,9 @@
 #define VEND1_PORT_ABILITIES		0x8046
 #define PTP_ABILITY			BIT(3)
 
+#define VEND1_PORT_FUNC_IRQ_EN		0x807A
+#define PTP_IRQS			BIT(3)
+
 #define VEND1_PORT_INFRA_CONTROL	0xAC00
 #define PORT_INFRA_CONTROL_EN		BIT(14)
 
@@ -890,12 +893,20 @@ static int nxp_c45_start_op(struct phy_device *phydev)
 
 static int nxp_c45_config_intr(struct phy_device *phydev)
 {
-	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+	/* The return value is ignored on purpose. It might be < 0.
+	 * 0x807A register is not present on SJA1110 PHYs.
+	 */
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 VEND1_PORT_FUNC_IRQ_EN, PTP_IRQS);
 		return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
 					VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
-	else
+	} else {
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   VEND1_PORT_FUNC_IRQ_EN, PTP_IRQS);
 		return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
 					  VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
+	}
 }
 
 static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 02/14] net: phy: nxp-c45-tja11xx: use phylib master/slave implementation
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 20:37   ` Andrew Lunn
  2023-06-16 13:53 ` [PATCH net-next v1 03/14] net: phy: nxp-c45-tja11xx: remove RX BIST frame counters Radu Pirea (NXP OSS)
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

Remove the custom implementation of master/save setup and read status
and use genphy_c45_config_aneg and genphy_c45_read_status since phylib
has support for master/slave setup and master/slave status.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 77 +------------------------------
 1 file changed, 2 insertions(+), 75 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 7b213c3f4536..78a30007edf8 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -19,13 +19,6 @@
 
 #define PHY_ID_TJA_1103			0x001BB010
 
-#define PMAPMD_B100T1_PMAPMD_CTL	0x0834
-#define B100T1_PMAPMD_CONFIG_EN		BIT(15)
-#define B100T1_PMAPMD_MASTER		BIT(14)
-#define MASTER_MODE			(B100T1_PMAPMD_CONFIG_EN | \
-					 B100T1_PMAPMD_MASTER)
-#define SLAVE_MODE			(B100T1_PMAPMD_CONFIG_EN)
-
 #define VEND1_DEVICE_CONTROL		0x0040
 #define DEVICE_CONTROL_RESET		BIT(15)
 #define DEVICE_CONTROL_CONFIG_GLOBAL_EN	BIT(14)
@@ -999,72 +992,6 @@ static int nxp_c45_cable_test_get_status(struct phy_device *phydev,
 	return nxp_c45_start_op(phydev);
 }
 
-static int nxp_c45_setup_master_slave(struct phy_device *phydev)
-{
-	switch (phydev->master_slave_set) {
-	case MASTER_SLAVE_CFG_MASTER_FORCE:
-	case MASTER_SLAVE_CFG_MASTER_PREFERRED:
-		phy_write_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_B100T1_PMAPMD_CTL,
-			      MASTER_MODE);
-		break;
-	case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
-	case MASTER_SLAVE_CFG_SLAVE_FORCE:
-		phy_write_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_B100T1_PMAPMD_CTL,
-			      SLAVE_MODE);
-		break;
-	case MASTER_SLAVE_CFG_UNKNOWN:
-	case MASTER_SLAVE_CFG_UNSUPPORTED:
-		return 0;
-	default:
-		phydev_warn(phydev, "Unsupported Master/Slave mode\n");
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-static int nxp_c45_read_master_slave(struct phy_device *phydev)
-{
-	int reg;
-
-	phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
-	phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
-
-	reg = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, PMAPMD_B100T1_PMAPMD_CTL);
-	if (reg < 0)
-		return reg;
-
-	if (reg & B100T1_PMAPMD_MASTER) {
-		phydev->master_slave_get = MASTER_SLAVE_CFG_MASTER_FORCE;
-		phydev->master_slave_state = MASTER_SLAVE_STATE_MASTER;
-	} else {
-		phydev->master_slave_get = MASTER_SLAVE_CFG_SLAVE_FORCE;
-		phydev->master_slave_state = MASTER_SLAVE_STATE_SLAVE;
-	}
-
-	return 0;
-}
-
-static int nxp_c45_config_aneg(struct phy_device *phydev)
-{
-	return nxp_c45_setup_master_slave(phydev);
-}
-
-static int nxp_c45_read_status(struct phy_device *phydev)
-{
-	int ret;
-
-	ret = genphy_c45_read_status(phydev);
-	if (ret)
-		return ret;
-
-	ret = nxp_c45_read_master_slave(phydev);
-	if (ret)
-		return ret;
-
-	return 0;
-}
-
 static int nxp_c45_get_sqi(struct phy_device *phydev)
 {
 	int reg;
@@ -1366,11 +1293,11 @@ static struct phy_driver nxp_c45_driver[] = {
 		.features		= PHY_BASIC_T1_FEATURES,
 		.probe			= nxp_c45_probe,
 		.soft_reset		= nxp_c45_soft_reset,
-		.config_aneg		= nxp_c45_config_aneg,
+		.config_aneg		= genphy_c45_config_aneg,
 		.config_init		= nxp_c45_config_init,
 		.config_intr		= nxp_c45_config_intr,
 		.handle_interrupt	= nxp_c45_handle_interrupt,
-		.read_status		= nxp_c45_read_status,
+		.read_status		= genphy_c45_read_status,
 		.suspend		= genphy_c45_pma_suspend,
 		.resume			= genphy_c45_pma_resume,
 		.get_sset_count		= nxp_c45_get_sset_count,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 03/14] net: phy: nxp-c45-tja11xx: remove RX BIST frame counters
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 02/14] net: phy: nxp-c45-tja11xx: use phylib master/slave implementation Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 20:39   ` Andrew Lunn
  2023-06-16 13:53 ` [PATCH net-next v1 04/14] net: phy: nxp-c45-tja11xx: add *_reg_field functions Radu Pirea (NXP OSS)
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

RX BIST frame counters can be used only when the PHY is in test mode. In
production mode, the counters will be always read as 0. So, they don't
provide any useful information and are removed from the statistics.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 78a30007edf8..e39f0b46e934 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -84,9 +84,6 @@
 #define VEND1_SYMBOL_ERROR_COUNTER	0x8350
 #define VEND1_LINK_DROP_COUNTER		0x8352
 #define VEND1_LINK_LOSSES_AND_FAILURES	0x8353
-#define VEND1_R_GOOD_FRAME_CNT		0xA950
-#define VEND1_R_BAD_FRAME_CNT		0xA952
-#define VEND1_R_RXER_FRAME_CNT		0xA954
 #define VEND1_RX_PREAMBLE_COUNT		0xAFCE
 #define VEND1_TX_PREAMBLE_COUNT		0xAFCF
 #define VEND1_RX_IPG_LENGTH		0xAFD0
@@ -812,12 +809,6 @@ static const struct nxp_c45_phy_stats nxp_c45_hw_stats[] = {
 		VEND1_LINK_LOSSES_AND_FAILURES, 10, GENMASK(15, 10) },
 	{ "phy_link_failure_cnt", MDIO_MMD_VEND1,
 		VEND1_LINK_LOSSES_AND_FAILURES, 0, GENMASK(9, 0) },
-	{ "r_good_frame_cnt", MDIO_MMD_VEND1,
-		VEND1_R_GOOD_FRAME_CNT, 0, GENMASK(15, 0) },
-	{ "r_bad_frame_cnt", MDIO_MMD_VEND1,
-		VEND1_R_BAD_FRAME_CNT, 0, GENMASK(15, 0) },
-	{ "r_rxer_frame_cnt", MDIO_MMD_VEND1,
-		VEND1_R_RXER_FRAME_CNT, 0, GENMASK(15, 0) },
 	{ "rx_preamble_count", MDIO_MMD_VEND1,
 		VEND1_RX_PREAMBLE_COUNT, 0, GENMASK(5, 0) },
 	{ "tx_preamble_count", MDIO_MMD_VEND1,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 04/14] net: phy: nxp-c45-tja11xx: add *_reg_field functions
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (2 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 03/14] net: phy: nxp-c45-tja11xx: remove RX BIST frame counters Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 20:42   ` Andrew Lunn
  2023-06-16 13:53 ` [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120 Radu Pirea (NXP OSS)
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

Between TJA1120 and TJA1103 the hardware was improved, but some register
addresses were changed and some bit fields were moved from one register
to another.

To integrate more PHYs in the same driver with the same register fields,
but these register fields located in different registers at
different offsets, I introduced the nxp_c45_reg_field structure.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 78 +++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index e39f0b46e934..a1dc888000b4 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -194,6 +194,21 @@ struct nxp_c45_skb_cb {
 	unsigned int type;
 };
 
+#define NXP_C45_REG_FIELD(_reg, _devad, _offset, _size)	\
+	((struct nxp_c45_reg_field) {			\
+		.reg = _reg,				\
+		.devad =  _devad,			\
+		.offset = _offset,			\
+		.size = _size,				\
+	})
+
+struct nxp_c45_reg_field {
+	u16 reg;
+	u8 devad;
+	u8 offset;
+	u8 size;
+};
+
 struct nxp_c45_hwts {
 	u32	nsec;
 	u32	sec;
@@ -228,6 +243,69 @@ struct nxp_c45_phy_stats {
 	u16		mask;
 };
 
+static int nxp_c45_read_reg_field(struct phy_device *phydev,
+				  const struct nxp_c45_reg_field *reg_field)
+{
+	u16 mask;
+	int ret;
+
+	if (reg_field->size == 0) {
+		phydev_warn(phydev, "Trying to read a reg field of size 0.");
+		return -EINVAL;
+	}
+
+	ret = phy_read_mmd(phydev, reg_field->devad, reg_field->reg);
+	if (ret < 0)
+		return ret;
+
+	mask = reg_field->size == 1 ? BIT(reg_field->offset) :
+		GENMASK(reg_field->offset + reg_field->size - 1,
+			reg_field->offset);
+	ret &= mask;
+	ret >>= reg_field->offset;
+
+	return ret;
+}
+
+static int nxp_c45_write_reg_field(struct phy_device *phydev,
+				   const struct nxp_c45_reg_field *reg_field,
+				   u16 val)
+{
+	u16 mask;
+	u16 set;
+
+	if (reg_field->size == 0) {
+		phydev_warn(phydev, "Trying to write a reg field of size 0.");
+		return -EINVAL;
+	}
+
+	mask = reg_field->size == 1 ? BIT(reg_field->offset) :
+		GENMASK(reg_field->offset + reg_field->size - 1,
+			reg_field->offset);
+	set = val << reg_field->offset;
+
+	return phy_modify_mmd_changed(phydev, reg_field->devad,
+				      reg_field->reg, mask, set);
+}
+
+static int nxp_c45_set_reg_field(struct phy_device *phydev,
+				 const struct nxp_c45_reg_field *reg_field)
+{
+	if (reg_field->size != 1)
+		return -EINVAL;
+
+	return nxp_c45_write_reg_field(phydev, reg_field, 1);
+}
+
+static int nxp_c45_clear_reg_field(struct phy_device *phydev,
+				   const struct nxp_c45_reg_field *reg_field)
+{
+	if (reg_field->size != 1)
+		return -EINVAL;
+
+	return nxp_c45_write_reg_field(phydev, reg_field, 0);
+}
+
 static bool nxp_c45_poll_txts(struct phy_device *phydev)
 {
 	return phydev->irq <= 0;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (3 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 04/14] net: phy: nxp-c45-tja11xx: add *_reg_field functions Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 19:35   ` Simon Horman
  2023-06-19  7:53   ` Horatiu Vultur
  2023-06-16 13:53 ` [PATCH net-next v1 06/14] net: phy: add 1000baseT1 to phy_basic_t1_features Radu Pirea (NXP OSS)
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

Remove the defined bits and register addresses that are not common
between TJA1103 and TJA1120 and replace them with reg_fields and
register addresses from phydev->drv->driver_data.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 498 ++++++++++++++++++++----------
 1 file changed, 331 insertions(+), 167 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index a1dc888000b4..2bf778bd08e3 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -41,10 +41,8 @@
 #define SQI_MASK			GENMASK(2, 0)
 #define MAX_SQI				SQI_MASK
 
-#define VEND1_CABLE_TEST		0x8330
 #define CABLE_TEST_ENABLE		BIT(15)
 #define CABLE_TEST_START		BIT(14)
-#define CABLE_TEST_VALID		BIT(13)
 #define CABLE_TEST_OK			0x00
 #define CABLE_TEST_SHORTED		0x01
 #define CABLE_TEST_OPEN			0x02
@@ -92,59 +90,18 @@
 
 #define VEND1_PTP_CONFIG		0x1102
 #define EXT_TRG_EDGE			BIT(1)
-#define PPS_OUT_POL			BIT(2)
-#define PPS_OUT_EN			BIT(3)
 
-#define VEND1_LTC_LOAD_CTRL		0x1105
-#define READ_LTC			BIT(2)
-#define LOAD_LTC			BIT(0)
-
-#define VEND1_LTC_WR_NSEC_0		0x1106
-#define VEND1_LTC_WR_NSEC_1		0x1107
-#define VEND1_LTC_WR_SEC_0		0x1108
-#define VEND1_LTC_WR_SEC_1		0x1109
-
-#define VEND1_LTC_RD_NSEC_0		0x110A
-#define VEND1_LTC_RD_NSEC_1		0x110B
-#define VEND1_LTC_RD_SEC_0		0x110C
-#define VEND1_LTC_RD_SEC_1		0x110D
-
-#define VEND1_RATE_ADJ_SUBNS_0		0x110F
-#define VEND1_RATE_ADJ_SUBNS_1		0x1110
 #define CLK_RATE_ADJ_LD			BIT(15)
 #define CLK_RATE_ADJ_DIR		BIT(14)
 
-#define VEND1_HW_LTC_LOCK_CTRL		0x1115
-#define HW_LTC_LOCK_EN			BIT(0)
-
-#define VEND1_PTP_IRQ_EN		0x1131
-#define VEND1_PTP_IRQ_STATUS		0x1132
-#define PTP_IRQ_EGR_TS			BIT(0)
-
 #define VEND1_RX_TS_INSRT_CTRL		0x114D
-#define RX_TS_INSRT_MODE2		0x02
+#define TJA1103_RX_TS_INSRT_MODE2	0x02
 
 #define VEND1_EGR_RING_DATA_0		0x114E
-#define VEND1_EGR_RING_DATA_1_SEQ_ID	0x114F
-#define VEND1_EGR_RING_DATA_2_NSEC_15_0	0x1150
-#define VEND1_EGR_RING_DATA_3		0x1151
 #define VEND1_EGR_RING_CTRL		0x1154
 
-#define VEND1_EXT_TRG_TS_DATA_0		0x1121
-#define VEND1_EXT_TRG_TS_DATA_1		0x1122
-#define VEND1_EXT_TRG_TS_DATA_2		0x1123
-#define VEND1_EXT_TRG_TS_DATA_3		0x1124
-#define VEND1_EXT_TRG_TS_DATA_4		0x1125
-#define VEND1_EXT_TRG_TS_CTRL		0x1126
-
-#define RING_DATA_0_DOMAIN_NUMBER	GENMASK(7, 0)
-#define RING_DATA_0_MSG_TYPE		GENMASK(11, 8)
-#define RING_DATA_0_SEC_4_2		GENMASK(14, 2)
 #define RING_DATA_0_TS_VALID		BIT(15)
 
-#define RING_DATA_3_NSEC_29_16		GENMASK(13, 0)
-#define RING_DATA_3_SEC_1_0		GENMASK(15, 14)
-#define RING_DATA_5_SEC_16_5		GENMASK(15, 4)
 #define RING_DONE			BIT(0)
 
 #define TS_SEC_MASK			GENMASK(1, 0)
@@ -155,18 +112,11 @@
 #define VEND1_PORT_PTP_CONTROL		0x9000
 #define PORT_PTP_CONTROL_BYPASS		BIT(11)
 
-#define VEND1_PTP_CLK_PERIOD		0x1104
 #define PTP_CLK_PERIOD_100BT1		15ULL
 
-#define VEND1_EVENT_MSG_FILT		0x1148
 #define EVENT_MSG_FILT_ALL		0x0F
 #define EVENT_MSG_FILT_NONE		0x00
 
-#define VEND1_TX_PIPE_DLY_NS		0x1149
-#define VEND1_TX_PIPEDLY_SUBNS		0x114A
-#define VEND1_RX_PIPE_DLY_NS		0x114B
-#define VEND1_RX_PIPEDLY_SUBNS		0x114C
-
 #define VEND1_GPIO_FUNC_CONFIG_BASE	0x2C40
 #define GPIO_FUNC_EN			BIT(15)
 #define GPIO_FUNC_PTP			BIT(6)
@@ -184,8 +134,8 @@
 #define MAX_ID_PS			2260U
 #define DEFAULT_ID_PS			2000U
 
-#define PPM_TO_SUBNS_INC(ppb)	div_u64(GENMASK_ULL(31, 0) * (ppb) * \
-					PTP_CLK_PERIOD_100BT1, NSEC_PER_SEC)
+#define PPM_TO_SUBNS_INC(ppb, ptp_clk_period) div_u64(GENMASK_ULL(31, 0) * \
+	(ppb) * (ptp_clk_period), NSEC_PER_SEC)
 
 #define NXP_C45_SKB_CB(skb)	((struct nxp_c45_skb_cb *)(skb)->cb)
 
@@ -217,7 +167,69 @@ struct nxp_c45_hwts {
 	u8	msg_type;
 };
 
+struct nxp_c45_regmap {
+	/* PTP config regs. */
+	u16 vend1_ptp_clk_period;
+	u16 vend1_event_msg_filt;
+
+	/* LTC bits and regs. */
+	struct nxp_c45_reg_field ltc_read;
+	struct nxp_c45_reg_field ltc_write;
+	struct nxp_c45_reg_field ltc_lock_ctrl;
+	u16 vend1_ltc_wr_nsec_0;
+	u16 vend1_ltc_wr_nsec_1;
+	u16 vend1_ltc_wr_sec_0;
+	u16 vend1_ltc_wr_sec_1;
+	u16 vend1_ltc_rd_nsec_0;
+	u16 vend1_ltc_rd_nsec_1;
+	u16 vend1_ltc_rd_sec_0;
+	u16 vend1_ltc_rd_sec_1;
+	u16 vend1_rate_adj_subns_0;
+	u16 vend1_rate_adj_subns_1;
+
+	/* External trigger reg fields. */
+	struct nxp_c45_reg_field irq_egr_ts_en;
+	struct nxp_c45_reg_field irq_egr_ts_status;
+	struct nxp_c45_reg_field domain_number;
+	struct nxp_c45_reg_field msg_type;
+	struct nxp_c45_reg_field sequence_id;
+	struct nxp_c45_reg_field sec_1_0;
+	struct nxp_c45_reg_field sec_4_2;
+	struct nxp_c45_reg_field nsec_15_0;
+	struct nxp_c45_reg_field nsec_29_16;
+
+	/* PPS and EXT Trigger bits and regs. */
+	struct nxp_c45_reg_field pps_enable;
+	struct nxp_c45_reg_field pps_polarity;
+	u16 vend1_ext_trg_data_0;
+	u16 vend1_ext_trg_data_1;
+	u16 vend1_ext_trg_data_2;
+	u16 vend1_ext_trg_data_3;
+	u16 vend1_ext_trg_ctrl;
+
+	/* Cable test reg fields. */
+	u16 cable_test;
+	struct nxp_c45_reg_field cable_test_valid;
+	struct nxp_c45_reg_field cable_test_result;
+};
+
+struct nxp_c45_phy_stats {
+	const char	*name;
+	const struct nxp_c45_reg_field counter;
+};
+
+struct nxp_c45_phy_data {
+	const struct nxp_c45_regmap *regmap;
+	const struct nxp_c45_phy_stats *stats;
+	int n_stats;
+	u8 ptp_clk_period;
+	void (*counters_enable)(struct phy_device *phydev);
+	void (*ptp_init)(struct phy_device *phydev);
+	void (*ptp_enable)(struct phy_device *phydev, bool enable);
+};
+
 struct nxp_c45_phy {
+	const struct nxp_c45_phy_data *phy_data;
 	struct phy_device *phydev;
 	struct mii_timestamper mii_ts;
 	struct ptp_clock *ptp_clock;
@@ -235,13 +247,19 @@ struct nxp_c45_phy {
 	bool extts;
 };
 
-struct nxp_c45_phy_stats {
-	const char	*name;
-	u8		mmd;
-	u16		reg;
-	u8		off;
-	u16		mask;
-};
+static inline
+const struct nxp_c45_phy_data *nxp_c45_get_data(struct phy_device *phydev)
+{
+	return phydev->drv->driver_data;
+}
+
+static inline
+const struct nxp_c45_regmap *nxp_c45_get_regmap(struct phy_device *phydev)
+{
+	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
+
+	return phy_data ? phy_data->regmap : NULL;
+}
 
 static int nxp_c45_read_reg_field(struct phy_device *phydev,
 				  const struct nxp_c45_reg_field *reg_field)
@@ -316,17 +334,17 @@ static int _nxp_c45_ptp_gettimex64(struct ptp_clock_info *ptp,
 				   struct ptp_system_timestamp *sts)
 {
 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
 
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_LTC_LOAD_CTRL,
-		      READ_LTC);
+	nxp_c45_set_reg_field(priv->phydev, &regmap->ltc_read);
 	ts->tv_nsec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				   VEND1_LTC_RD_NSEC_0);
+				   regmap->vend1_ltc_rd_nsec_0);
 	ts->tv_nsec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				    VEND1_LTC_RD_NSEC_1) << 16;
+				    regmap->vend1_ltc_rd_nsec_1) << 16;
 	ts->tv_sec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				  VEND1_LTC_RD_SEC_0);
+				  regmap->vend1_ltc_rd_sec_0);
 	ts->tv_sec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				   VEND1_LTC_RD_SEC_1) << 16;
+				   regmap->vend1_ltc_rd_sec_1) << 16;
 
 	return 0;
 }
@@ -348,17 +366,17 @@ static int _nxp_c45_ptp_settime64(struct ptp_clock_info *ptp,
 				  const struct timespec64 *ts)
 {
 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
 
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_LTC_WR_NSEC_0,
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_nsec_0,
 		      ts->tv_nsec);
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_LTC_WR_NSEC_1,
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_nsec_1,
 		      ts->tv_nsec >> 16);
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_LTC_WR_SEC_0,
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_sec_0,
 		      ts->tv_sec);
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_LTC_WR_SEC_1,
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, regmap->vend1_ltc_wr_sec_1,
 		      ts->tv_sec >> 16);
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_LTC_LOAD_CTRL,
-		      LOAD_LTC);
+	nxp_c45_set_reg_field(priv->phydev, &regmap->ltc_write);
 
 	return 0;
 }
@@ -378,6 +396,8 @@ static int nxp_c45_ptp_settime64(struct ptp_clock_info *ptp,
 static int nxp_c45_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 {
 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
+	const struct nxp_c45_phy_data *data = nxp_c45_get_data(priv->phydev);
+	const struct nxp_c45_regmap *regmap = data->regmap;
 	s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
 	u64 subns_inc_val;
 	bool inc;
@@ -386,16 +406,18 @@ static int nxp_c45_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
 	inc = ppb >= 0;
 	ppb = abs(ppb);
 
-	subns_inc_val = PPM_TO_SUBNS_INC(ppb);
+	subns_inc_val = PPM_TO_SUBNS_INC(ppb, data->ptp_clk_period);
 
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_RATE_ADJ_SUBNS_0,
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
+		      regmap->vend1_rate_adj_subns_0,
 		      subns_inc_val);
 	subns_inc_val >>= 16;
 	subns_inc_val |= CLK_RATE_ADJ_LD;
 	if (inc)
 		subns_inc_val |= CLK_RATE_ADJ_DIR;
 
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_RATE_ADJ_SUBNS_1,
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
+		      regmap->vend1_rate_adj_subns_1,
 		      subns_inc_val);
 	mutex_unlock(&priv->ptp_lock);
 
@@ -439,21 +461,25 @@ static bool nxp_c45_match_ts(struct ptp_header *header,
 static void nxp_c45_get_extts(struct nxp_c45_phy *priv,
 			      struct timespec64 *extts)
 {
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
+
 	extts->tv_nsec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				      VEND1_EXT_TRG_TS_DATA_0);
+				      regmap->vend1_ext_trg_data_0);
 	extts->tv_nsec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				       VEND1_EXT_TRG_TS_DATA_1) << 16;
+				       regmap->vend1_ext_trg_data_1) << 16;
 	extts->tv_sec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				     VEND1_EXT_TRG_TS_DATA_2);
+				     regmap->vend1_ext_trg_data_2);
 	extts->tv_sec |= phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				      VEND1_EXT_TRG_TS_DATA_3) << 16;
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EXT_TRG_TS_CTRL,
-		      RING_DONE);
+				      regmap->vend1_ext_trg_data_3) << 16;
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
+		      regmap->vend1_ext_trg_ctrl, RING_DONE);
 }
 
 static bool nxp_c45_get_hwtxts(struct nxp_c45_phy *priv,
 			       struct nxp_c45_hwts *hwts)
 {
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
+	struct phy_device *phydev = priv->phydev;
 	bool valid;
 	u16 reg;
 
@@ -465,16 +491,18 @@ static bool nxp_c45_get_hwtxts(struct nxp_c45_phy *priv,
 	if (!valid)
 		goto nxp_c45_get_hwtxts_out;
 
-	hwts->domain_number = reg;
-	hwts->msg_type = (reg & RING_DATA_0_MSG_TYPE) >> 8;
-	hwts->sec = (reg & RING_DATA_0_SEC_4_2) >> 10;
-	hwts->sequence_id = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-					 VEND1_EGR_RING_DATA_1_SEQ_ID);
-	hwts->nsec = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
-				  VEND1_EGR_RING_DATA_2_NSEC_15_0);
-	reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EGR_RING_DATA_3);
-	hwts->nsec |= (reg & RING_DATA_3_NSEC_29_16) << 16;
-	hwts->sec |= (reg & RING_DATA_3_SEC_1_0) >> 14;
+	hwts->domain_number =
+		nxp_c45_read_reg_field(phydev, &regmap->domain_number);
+	hwts->msg_type =
+		nxp_c45_read_reg_field(phydev, &regmap->msg_type);
+	hwts->sequence_id =
+		nxp_c45_read_reg_field(phydev, &regmap->sequence_id);
+	hwts->nsec =
+		nxp_c45_read_reg_field(phydev, &regmap->nsec_15_0);
+	hwts->nsec |=
+		nxp_c45_read_reg_field(phydev, &regmap->nsec_29_16) << 16;
+	hwts->sec = nxp_c45_read_reg_field(phydev, &regmap->sec_1_0);
+	hwts->sec |= nxp_c45_read_reg_field(phydev, &regmap->sec_4_2) << 2;
 
 nxp_c45_get_hwtxts_out:
 	mutex_unlock(&priv->ptp_lock);
@@ -579,6 +607,7 @@ static void nxp_c45_gpio_config(struct nxp_c45_phy *priv,
 static int nxp_c45_perout_enable(struct nxp_c45_phy *priv,
 				 struct ptp_perout_request *perout, int on)
 {
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
 	struct phy_device *phydev = priv->phydev;
 	int pin;
 
@@ -590,10 +619,10 @@ static int nxp_c45_perout_enable(struct nxp_c45_phy *priv,
 		return pin;
 
 	if (!on) {
-		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CONFIG,
-				   PPS_OUT_EN);
-		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CONFIG,
-				   PPS_OUT_POL);
+		nxp_c45_clear_reg_field(priv->phydev,
+					&regmap->pps_enable);
+		nxp_c45_clear_reg_field(priv->phydev,
+					&regmap->pps_polarity);
 
 		nxp_c45_gpio_config(priv, pin, GPIO_DISABLE);
 
@@ -622,16 +651,16 @@ static int nxp_c45_perout_enable(struct nxp_c45_phy *priv,
 		}
 
 		if (perout->phase.nsec == 0)
-			phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-					   VEND1_PTP_CONFIG, PPS_OUT_POL);
+			nxp_c45_clear_reg_field(priv->phydev,
+						&regmap->pps_polarity);
 		else
-			phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
-					 VEND1_PTP_CONFIG, PPS_OUT_POL);
+			nxp_c45_set_reg_field(priv->phydev,
+					      &regmap->pps_polarity);
 	}
 
 	nxp_c45_gpio_config(priv, pin, GPIO_PPS_OUT_CFG);
 
-	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CONFIG, PPS_OUT_EN);
+	nxp_c45_set_reg_field(priv->phydev, &regmap->pps_enable);
 
 	return 0;
 }
@@ -806,6 +835,7 @@ static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
 	struct nxp_c45_phy *priv = container_of(mii_ts, struct nxp_c45_phy,
 						mii_ts);
 	struct phy_device *phydev = priv->phydev;
+	const struct nxp_c45_phy_data *data;
 	struct hwtstamp_config cfg;
 
 	if (copy_from_user(&cfg, ifreq->ifr_data, sizeof(cfg)))
@@ -814,6 +844,7 @@ static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
 	if (cfg.tx_type < 0 || cfg.tx_type > HWTSTAMP_TX_ON)
 		return -ERANGE;
 
+	data = nxp_c45_get_data(phydev);
 	priv->hwts_tx = cfg.tx_type;
 
 	switch (cfg.rx_filter) {
@@ -831,27 +862,26 @@ static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
 	}
 
 	if (priv->hwts_rx || priv->hwts_tx) {
-		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_EVENT_MSG_FILT,
+		phy_write_mmd(phydev, MDIO_MMD_VEND1,
+			      data->regmap->vend1_event_msg_filt,
 			      EVENT_MSG_FILT_ALL);
-		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-				   VEND1_PORT_PTP_CONTROL,
-				   PORT_PTP_CONTROL_BYPASS);
+		if (data && data->ptp_enable)
+			data->ptp_enable(phydev, true);
 	} else {
-		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_EVENT_MSG_FILT,
+		phy_write_mmd(phydev, MDIO_MMD_VEND1,
+			      data->regmap->vend1_event_msg_filt,
 			      EVENT_MSG_FILT_NONE);
-		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_PTP_CONTROL,
-				 PORT_PTP_CONTROL_BYPASS);
+		if (data && data->ptp_enable)
+			data->ptp_enable(phydev, false);
 	}
 
 	if (nxp_c45_poll_txts(priv->phydev))
 		goto nxp_c45_no_ptp_irq;
 
 	if (priv->hwts_tx)
-		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
-				 VEND1_PTP_IRQ_EN, PTP_IRQ_EGR_TS);
+		nxp_c45_set_reg_field(phydev, &data->regmap->irq_egr_ts_en);
 	else
-		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
-				   VEND1_PTP_IRQ_EN, PTP_IRQ_EGR_TS);
+		nxp_c45_clear_reg_field(phydev, &data->regmap->irq_egr_ts_en);
 
 nxp_c45_no_ptp_irq:
 	return copy_to_user(ifreq->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
@@ -876,57 +906,79 @@ static int nxp_c45_ts_info(struct mii_timestamper *mii_ts,
 	return 0;
 }
 
-static const struct nxp_c45_phy_stats nxp_c45_hw_stats[] = {
-	{ "phy_symbol_error_cnt", MDIO_MMD_VEND1,
-		VEND1_SYMBOL_ERROR_COUNTER, 0, GENMASK(15, 0) },
-	{ "phy_link_status_drop_cnt", MDIO_MMD_VEND1,
-		VEND1_LINK_DROP_COUNTER, 8, GENMASK(13, 8) },
-	{ "phy_link_availability_drop_cnt", MDIO_MMD_VEND1,
-		VEND1_LINK_DROP_COUNTER, 0, GENMASK(5, 0) },
-	{ "phy_link_loss_cnt", MDIO_MMD_VEND1,
-		VEND1_LINK_LOSSES_AND_FAILURES, 10, GENMASK(15, 10) },
-	{ "phy_link_failure_cnt", MDIO_MMD_VEND1,
-		VEND1_LINK_LOSSES_AND_FAILURES, 0, GENMASK(9, 0) },
-	{ "rx_preamble_count", MDIO_MMD_VEND1,
-		VEND1_RX_PREAMBLE_COUNT, 0, GENMASK(5, 0) },
-	{ "tx_preamble_count", MDIO_MMD_VEND1,
-		VEND1_TX_PREAMBLE_COUNT, 0, GENMASK(5, 0) },
-	{ "rx_ipg_length", MDIO_MMD_VEND1,
-		VEND1_RX_IPG_LENGTH, 0, GENMASK(8, 0) },
-	{ "tx_ipg_length", MDIO_MMD_VEND1,
-		VEND1_TX_IPG_LENGTH, 0, GENMASK(8, 0) },
+static const struct nxp_c45_phy_stats common_hw_stats[] = {
+	{ "phy_link_status_drop_cnt",
+		NXP_C45_REG_FIELD(0x8352, MDIO_MMD_VEND1, 8, 6), },
+	{ "phy_link_availability_drop_cnt",
+		NXP_C45_REG_FIELD(0x8352, MDIO_MMD_VEND1, 0, 6), },
+	{ "phy_link_loss_cnt",
+		NXP_C45_REG_FIELD(0x8353, MDIO_MMD_VEND1, 10, 6), },
+	{ "phy_link_failure_cnt",
+		NXP_C45_REG_FIELD(0x8353, MDIO_MMD_VEND1, 0, 10), },
+	{ "phy_symbol_error_cnt",
+		NXP_C45_REG_FIELD(0x8350, MDIO_MMD_VEND1, 0, 16) },
+};
+
+static const struct nxp_c45_phy_stats tja1103_hw_stats[] = {
+	{ "rx_preamble_count",
+		NXP_C45_REG_FIELD(0xAFCE, MDIO_MMD_VEND1, 0, 6), },
+	{ "tx_preamble_count",
+		NXP_C45_REG_FIELD(0xAFCF, MDIO_MMD_VEND1, 0, 6), },
+	{ "rx_ipg_length",
+		NXP_C45_REG_FIELD(0xAFD0, MDIO_MMD_VEND1, 0, 9), },
+	{ "tx_ipg_length",
+		NXP_C45_REG_FIELD(0xAFD1, MDIO_MMD_VEND1, 0, 9), },
 };
 
 static int nxp_c45_get_sset_count(struct phy_device *phydev)
 {
-	return ARRAY_SIZE(nxp_c45_hw_stats);
+	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
+
+	return ARRAY_SIZE(common_hw_stats) + (phy_data ? phy_data->n_stats : 0);
 }
 
 static void nxp_c45_get_strings(struct phy_device *phydev, u8 *data)
 {
+	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
+	size_t count = nxp_c45_get_sset_count(phydev);
+	size_t idx;
 	size_t i;
 
-	for (i = 0; i < ARRAY_SIZE(nxp_c45_hw_stats); i++) {
+	for (i = 0; i < count; i++) {
+		if (i < ARRAY_SIZE(common_hw_stats)) {
+			strncpy(data + i * ETH_GSTRING_LEN,
+				common_hw_stats[i].name, ETH_GSTRING_LEN);
+			continue;
+		}
+		idx = i - ARRAY_SIZE(common_hw_stats);
 		strncpy(data + i * ETH_GSTRING_LEN,
-			nxp_c45_hw_stats[i].name, ETH_GSTRING_LEN);
+			phy_data->stats[idx].name, ETH_GSTRING_LEN);
 	}
 }
 
 static void nxp_c45_get_stats(struct phy_device *phydev,
 			      struct ethtool_stats *stats, u64 *data)
 {
+	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
+	size_t count = nxp_c45_get_sset_count(phydev);
+	const struct nxp_c45_reg_field *reg_field;
+	size_t idx;
 	size_t i;
 	int ret;
 
-	for (i = 0; i < ARRAY_SIZE(nxp_c45_hw_stats); i++) {
-		ret = phy_read_mmd(phydev, nxp_c45_hw_stats[i].mmd,
-				   nxp_c45_hw_stats[i].reg);
-		if (ret < 0) {
-			data[i] = U64_MAX;
+	for (i = 0; i < count; i++) {
+		if (i < ARRAY_SIZE(common_hw_stats)) {
+			reg_field = &common_hw_stats[i].counter;
 		} else {
-			data[i] = ret & nxp_c45_hw_stats[i].mask;
-			data[i] >>= nxp_c45_hw_stats[i].off;
+			idx = i - ARRAY_SIZE(common_hw_stats);
+			reg_field = &phy_data->stats[idx].counter;
 		}
+
+		ret = nxp_c45_read_reg_field(phydev, reg_field);
+		if (ret < 0)
+			data[i] = U64_MAX;
+		else
+			data[i] = ret;
 	}
 }
 
@@ -974,6 +1026,7 @@ static int nxp_c45_config_intr(struct phy_device *phydev)
 static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev)
 {
 	struct nxp_c45_phy *priv = phydev->priv;
+	const struct nxp_c45_phy_data *data;
 	irqreturn_t ret = IRQ_NONE;
 	struct nxp_c45_hwts hwts;
 	int irq;
@@ -986,12 +1039,16 @@ static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev)
 		ret = IRQ_HANDLED;
 	}
 
+	data = nxp_c45_get_data(phydev);
+	if (!data)
+		return ret;
+
 	/* There is no need for ACK.
 	 * The irq signal will be asserted until the EGR TS FIFO will be
 	 * emptied.
 	 */
-	irq = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_IRQ_STATUS);
-	if (irq & PTP_IRQ_EGR_TS) {
+	irq = nxp_c45_read_reg_field(phydev, &data->regmap->irq_egr_ts_status);
+	if (irq) {
 		while (nxp_c45_get_hwtxts(priv, &hwts))
 			nxp_c45_process_txts(priv, &hwts);
 
@@ -1018,24 +1075,28 @@ static int nxp_c45_soft_reset(struct phy_device *phydev)
 
 static int nxp_c45_cable_test_start(struct phy_device *phydev)
 {
-	return phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_CABLE_TEST,
-			     CABLE_TEST_ENABLE | CABLE_TEST_START);
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(phydev);
+
+	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, regmap->cable_test,
+				CABLE_TEST_ENABLE | CABLE_TEST_START);
 }
 
 static int nxp_c45_cable_test_get_status(struct phy_device *phydev,
 					 bool *finished)
 {
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(phydev);
 	int ret;
 	u8 cable_test_result;
 
-	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_CABLE_TEST);
-	if (!(ret & CABLE_TEST_VALID)) {
+	ret = nxp_c45_read_reg_field(phydev, &regmap->cable_test_valid);
+	if (!ret) {
 		*finished = false;
 		return 0;
 	}
 
 	*finished = true;
-	cable_test_result = ret & GENMASK(2, 0);
+	cable_test_result = nxp_c45_read_reg_field(phydev,
+						   &regmap->cable_test_result);
 
 	switch (cable_test_result) {
 	case CABLE_TEST_OK:
@@ -1055,7 +1116,7 @@ static int nxp_c45_cable_test_get_status(struct phy_device *phydev,
 					ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC);
 	}
 
-	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_CABLE_TEST,
+	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, regmap->cable_test,
 			   CABLE_TEST_ENABLE);
 
 	return nxp_c45_start_op(phydev);
@@ -1094,6 +1155,30 @@ static int nxp_c45_check_delay(struct phy_device *phydev, u32 delay)
 	return 0;
 }
 
+static void nxp_c45_counters_enable(struct phy_device *phydev)
+{
+	const struct nxp_c45_phy_data *data = nxp_c45_get_data(phydev);
+
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_LINK_DROP_COUNTER,
+			 COUNTER_EN);
+
+	if (data && data->counters_enable)
+		data->counters_enable(phydev);
+}
+
+static void nxp_c45_ptp_init(struct phy_device *phydev)
+{
+	const struct nxp_c45_phy_data *data = nxp_c45_get_data(phydev);
+
+	phy_write_mmd(phydev, MDIO_MMD_VEND1,
+		      data->regmap->vend1_ptp_clk_period,
+		      data->ptp_clk_period);
+	nxp_c45_clear_reg_field(phydev, &data->regmap->ltc_lock_ctrl);
+
+	if (data && data->ptp_init)
+		data->ptp_init(phydev);
+}
+
 static u64 nxp_c45_get_phase_shift(u64 phase_offset_raw)
 {
 	/* The delay in degree phase is 73.8 + phase_offset_raw * 0.9.
@@ -1271,31 +1356,14 @@ static int nxp_c45_config_init(struct phy_device *phydev)
 	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PHY_CONFIG,
 			 PHY_CONFIG_AUTO);
 
-	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_LINK_DROP_COUNTER,
-			 COUNTER_EN);
-	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_PREAMBLE_COUNT,
-			 COUNTER_EN);
-	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TX_PREAMBLE_COUNT,
-			 COUNTER_EN);
-	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_IPG_LENGTH,
-			 COUNTER_EN);
-	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TX_IPG_LENGTH,
-			 COUNTER_EN);
-
 	ret = nxp_c45_set_phy_mode(phydev);
 	if (ret)
 		return ret;
 
 	phydev->autoneg = AUTONEG_DISABLE;
 
-	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_PTP_CLK_PERIOD,
-		      PTP_CLK_PERIOD_100BT1);
-	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_HW_LTC_LOCK_CTRL,
-			   HW_LTC_LOCK_EN);
-	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_TS_INSRT_CTRL,
-		      RX_TS_INSRT_MODE2);
-	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_FUNC_ENABLES,
-			 PTP_ENABLE);
+	nxp_c45_counters_enable(phydev);
+	nxp_c45_ptp_init(phydev);
 
 	return nxp_c45_start_op(phydev);
 }
@@ -1355,11 +1423,107 @@ static void nxp_c45_remove(struct phy_device *phydev)
 	skb_queue_purge(&priv->rx_queue);
 }
 
+static void tja1103_counters_enable(struct phy_device *phydev)
+{
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_PREAMBLE_COUNT,
+			 COUNTER_EN);
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TX_PREAMBLE_COUNT,
+			 COUNTER_EN);
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_IPG_LENGTH,
+			 COUNTER_EN);
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_TX_IPG_LENGTH,
+			 COUNTER_EN);
+}
+
+static void tja1103_ptp_init(struct phy_device *phydev)
+{
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_RX_TS_INSRT_CTRL,
+		      TJA1103_RX_TS_INSRT_MODE2);
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_FUNC_ENABLES,
+			 PTP_ENABLE);
+}
+
+static void tja1103_ptp_enable(struct phy_device *phydev, bool enable)
+{
+	if (enable)
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   VEND1_PORT_PTP_CONTROL,
+				   PORT_PTP_CONTROL_BYPASS);
+	else
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 VEND1_PORT_PTP_CONTROL,
+				 PORT_PTP_CONTROL_BYPASS);
+}
+
+static const struct nxp_c45_regmap tja1103_regmap = {
+	.vend1_ptp_clk_period	= 0x1104,
+	.vend1_event_msg_filt	= 0x1148,
+	.pps_enable		=
+		NXP_C45_REG_FIELD(0x1102, MDIO_MMD_VEND1, 3, 1),
+	.pps_polarity		=
+		NXP_C45_REG_FIELD(0x1102, MDIO_MMD_VEND1, 2, 1),
+	.ltc_lock_ctrl		=
+		NXP_C45_REG_FIELD(0x1115, MDIO_MMD_VEND1, 0, 1),
+	.ltc_read		=
+		NXP_C45_REG_FIELD(0x1105, MDIO_MMD_VEND1, 2, 1),
+	.ltc_write		=
+		NXP_C45_REG_FIELD(0x1105, MDIO_MMD_VEND1, 0, 1),
+	.vend1_ltc_wr_nsec_0	= 0x1106,
+	.vend1_ltc_wr_nsec_1	= 0x1107,
+	.vend1_ltc_wr_sec_0	= 0x1108,
+	.vend1_ltc_wr_sec_1	= 0x1109,
+	.vend1_ltc_rd_nsec_0	= 0x110A,
+	.vend1_ltc_rd_nsec_1	= 0x110B,
+	.vend1_ltc_rd_sec_0	= 0x110C,
+	.vend1_ltc_rd_sec_1	= 0x110D,
+	.vend1_rate_adj_subns_0	= 0x110F,
+	.vend1_rate_adj_subns_1	= 0x1110,
+	.irq_egr_ts_en		=
+		NXP_C45_REG_FIELD(0x1131, MDIO_MMD_VEND1, 0, 1),
+	.irq_egr_ts_status	=
+		NXP_C45_REG_FIELD(0x1132, MDIO_MMD_VEND1, 0, 1),
+	.domain_number		=
+		NXP_C45_REG_FIELD(0x114E, MDIO_MMD_VEND1, 0, 8),
+	.msg_type		=
+		NXP_C45_REG_FIELD(0x114E, MDIO_MMD_VEND1, 8, 4),
+	.sequence_id		=
+		NXP_C45_REG_FIELD(0x114F, MDIO_MMD_VEND1, 0, 16),
+	.sec_1_0		=
+		NXP_C45_REG_FIELD(0x1151, MDIO_MMD_VEND1, 14, 2),
+	.sec_4_2		=
+		NXP_C45_REG_FIELD(0x114E, MDIO_MMD_VEND1, 12, 3),
+	.nsec_15_0		=
+		NXP_C45_REG_FIELD(0x1150, MDIO_MMD_VEND1, 0, 16),
+	.nsec_29_16		=
+		NXP_C45_REG_FIELD(0x1151, MDIO_MMD_VEND1, 0, 14),
+	.vend1_ext_trg_data_0	= 0x1121,
+	.vend1_ext_trg_data_1	= 0x1122,
+	.vend1_ext_trg_data_2	= 0x1123,
+	.vend1_ext_trg_data_3	= 0x1124,
+	.vend1_ext_trg_ctrl	= 0x1126,
+	.cable_test		= 0x8330,
+	.cable_test_valid	=
+		NXP_C45_REG_FIELD(0x8330, MDIO_MMD_VEND1, 13, 1),
+	.cable_test_result	=
+		NXP_C45_REG_FIELD(0x8330, MDIO_MMD_VEND1, 0, 3),
+};
+
+static const struct nxp_c45_phy_data tja1103_phy_data = {
+	.regmap = &tja1103_regmap,
+	.stats = tja1103_hw_stats,
+	.n_stats = ARRAY_SIZE(tja1103_hw_stats),
+	.ptp_clk_period = PTP_CLK_PERIOD_100BT1,
+	.counters_enable = tja1103_counters_enable,
+	.ptp_init = tja1103_ptp_init,
+	.ptp_enable = tja1103_ptp_enable,
+};
+
 static struct phy_driver nxp_c45_driver[] = {
 	{
 		PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103),
 		.name			= "NXP C45 TJA1103",
 		.features		= PHY_BASIC_T1_FEATURES,
+		.driver_data		= &tja1103_phy_data,
 		.probe			= nxp_c45_probe,
 		.soft_reset		= nxp_c45_soft_reset,
 		.config_aneg		= genphy_c45_config_aneg,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 06/14] net: phy: add 1000baseT1 to phy_basic_t1_features
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (4 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120 Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 20:49   ` Andrew Lunn
  2023-06-16 13:53 ` [PATCH net-next v1 07/14] net: phy: nxp-c45-tja11xx: add TJA1120 support Radu Pirea (NXP OSS)
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

Add 1000baseT1 bit to phy_basic_t1_features.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/phy_device.c | 3 ++-
 include/linux/phy.h          | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 2cad9cc3f6b8..1c7fefeda7a3 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -96,10 +96,11 @@ const int phy_10_100_features_array[4] = {
 };
 EXPORT_SYMBOL_GPL(phy_10_100_features_array);
 
-const int phy_basic_t1_features_array[3] = {
+const int phy_basic_t1_features_array[4] = {
 	ETHTOOL_LINK_MODE_TP_BIT,
 	ETHTOOL_LINK_MODE_10baseT1L_Full_BIT,
 	ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
+	ETHTOOL_LINK_MODE_1000baseT1_Full_BIT,
 };
 EXPORT_SYMBOL_GPL(phy_basic_t1_features_array);
 
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 11c1e91563d4..47c2b55d899f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -70,7 +70,7 @@ extern const int phy_basic_ports_array[3];
 extern const int phy_fibre_port_array[1];
 extern const int phy_all_ports_features_array[7];
 extern const int phy_10_100_features_array[4];
-extern const int phy_basic_t1_features_array[3];
+extern const int phy_basic_t1_features_array[4];
 extern const int phy_basic_t1s_p2mp_features_array[2];
 extern const int phy_gbit_features_array[2];
 extern const int phy_10gbit_features_array[1];
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 07/14] net: phy: nxp-c45-tja11xx: add TJA1120 support
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (5 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 06/14] net: phy: add 1000baseT1 to phy_basic_t1_features Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 08/14] net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges Radu Pirea (NXP OSS)
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

Add TJA1120 driver entry and its driver_data.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/Kconfig           |   2 +-
 drivers/net/phy/nxp-c45-tja11xx.c | 160 +++++++++++++++++++++++++++++-
 2 files changed, 160 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index a40269c17597..aaed6d73f9f5 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -300,7 +300,7 @@ config NXP_C45_TJA11XX_PHY
 	depends on PTP_1588_CLOCK_OPTIONAL
 	help
 	  Enable support for NXP C45 TJA11XX PHYs.
-	  Currently supports only the TJA1103 PHY.
+	  Currently supports the TJA1103 and TJA1120 PHYs.
 
 config NXP_TJA11XX_PHY
 	tristate "NXP TJA11xx PHYs support"
diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 2bf778bd08e3..2160b9f8940c 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -18,12 +18,17 @@
 #include <linux/net_tstamp.h>
 
 #define PHY_ID_TJA_1103			0x001BB010
+#define PHY_ID_TJA_1120			0x001BB031
 
 #define VEND1_DEVICE_CONTROL		0x0040
 #define DEVICE_CONTROL_RESET		BIT(15)
 #define DEVICE_CONTROL_CONFIG_GLOBAL_EN	BIT(14)
 #define DEVICE_CONTROL_CONFIG_ALL_EN	BIT(13)
 
+#define VEND1_DEVICE_CONFIG		0x0048
+
+#define TJA1120_VEND1_EXT_TS_MODE	0x1012
+
 #define VEND1_PHY_IRQ_ACK		0x80A0
 #define VEND1_PHY_IRQ_EN		0x80A1
 #define VEND1_PHY_IRQ_STATUS		0x80A2
@@ -79,6 +84,14 @@
 #define MII_BASIC_CONFIG_RMII		0x5
 #define MII_BASIC_CONFIG_MII		0x4
 
+#define VEND1_SYMBOL_ERROR_CNT_XTD	0x8351
+#define EXTENDED_CNT_EN			BIT(15)
+#define VEND1_MONITOR_STATUS		0xAC80
+#define MONITOR_RESET			BIT(15)
+#define VEND1_MONITOR_CONFIG		0xAC86
+#define LOST_FRAMES_CNT_EN		BIT(9)
+#define ALL_FRAMES_CNT_EN		BIT(8)
+
 #define VEND1_SYMBOL_ERROR_COUNTER	0x8350
 #define VEND1_LINK_DROP_COUNTER		0x8352
 #define VEND1_LINK_LOSSES_AND_FAILURES	0x8353
@@ -97,11 +110,14 @@
 #define VEND1_RX_TS_INSRT_CTRL		0x114D
 #define TJA1103_RX_TS_INSRT_MODE2	0x02
 
+#define TJA1120_RX_TS_INSRT_CTRL	0x9012
+#define TJA1120_RX_TS_INSRT_EN		BIT(15)
+#define TJA1120_TS_INSRT_MODE		BIT(4)
+
 #define VEND1_EGR_RING_DATA_0		0x114E
 #define VEND1_EGR_RING_CTRL		0x1154
 
 #define RING_DATA_0_TS_VALID		BIT(15)
-
 #define RING_DONE			BIT(0)
 
 #define TS_SEC_MASK			GENMASK(1, 0)
@@ -113,6 +129,7 @@
 #define PORT_PTP_CONTROL_BYPASS		BIT(11)
 
 #define PTP_CLK_PERIOD_100BT1		15ULL
+#define PTP_CLK_PERIOD_1000BT1		8ULL
 
 #define EVENT_MSG_FILT_ALL		0x0F
 #define EVENT_MSG_FILT_NONE		0x00
@@ -930,6 +947,27 @@ static const struct nxp_c45_phy_stats tja1103_hw_stats[] = {
 		NXP_C45_REG_FIELD(0xAFD1, MDIO_MMD_VEND1, 0, 9), },
 };
 
+static const struct nxp_c45_phy_stats tja1120_hw_stats[] = {
+	{ "phy_symbol_error_cnt_ext",
+		NXP_C45_REG_FIELD(0x8351, MDIO_MMD_VEND1, 0, 14) },
+	{ "tx_frames",
+		NXP_C45_REG_FIELD(0xACA0, MDIO_MMD_VEND1, 0, 16), },
+	{ "tx_frames_xtd",
+		NXP_C45_REG_FIELD(0xACA1, MDIO_MMD_VEND1, 0, 8), },
+	{ "rx_frames",
+		NXP_C45_REG_FIELD(0xACA2, MDIO_MMD_VEND1, 0, 16), },
+	{ "rx_frames_xtd",
+		NXP_C45_REG_FIELD(0xACA3, MDIO_MMD_VEND1, 0, 8), },
+	{ "tx_lost_frames",
+		NXP_C45_REG_FIELD(0xACA4, MDIO_MMD_VEND1, 0, 16), },
+	{ "tx_lost_frames_xtd",
+		NXP_C45_REG_FIELD(0xACA5, MDIO_MMD_VEND1, 0, 8), },
+	{ "rx_lost_frames",
+		NXP_C45_REG_FIELD(0xACA6, MDIO_MMD_VEND1, 0, 16), },
+	{ "rx_lost_frames_xtd",
+		NXP_C45_REG_FIELD(0xACA7, MDIO_MMD_VEND1, 0, 8), },
+};
+
 static int nxp_c45_get_sset_count(struct phy_device *phydev)
 {
 	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
@@ -1518,6 +1556,101 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
 	.ptp_enable = tja1103_ptp_enable,
 };
 
+static void tja1120_counters_enable(struct phy_device *phydev)
+{
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_SYMBOL_ERROR_CNT_XTD,
+			 EXTENDED_CNT_EN);
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_MONITOR_STATUS,
+			 MONITOR_RESET);
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_MONITOR_CONFIG,
+			 ALL_FRAMES_CNT_EN | LOST_FRAMES_CNT_EN);
+}
+
+static void tja1120_ptp_init(struct phy_device *phydev)
+{
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, TJA1120_RX_TS_INSRT_CTRL,
+		      TJA1120_RX_TS_INSRT_EN | TJA1120_TS_INSRT_MODE);
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, TJA1120_VEND1_EXT_TS_MODE,
+		      TJA1120_TS_INSRT_MODE);
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_DEVICE_CONFIG,
+			 PTP_ENABLE);
+}
+
+static void tja1120_ptp_enable(struct phy_device *phydev, bool enable)
+{
+	if (enable)
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 VEND1_PORT_FUNC_ENABLES,
+				 PTP_ENABLE);
+	else
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   VEND1_PORT_FUNC_ENABLES,
+				   PTP_ENABLE);
+}
+
+static const struct nxp_c45_regmap tja1120_regmap = {
+	.vend1_ptp_clk_period	= 0x1020,
+	.vend1_event_msg_filt	= 0x9010,
+	.pps_enable		=
+		NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 4, 1),
+	.pps_polarity		=
+		NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 5, 1),
+	.ltc_lock_ctrl		=
+		NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 2, 1),
+	.ltc_read		=
+		NXP_C45_REG_FIELD(0x1000, MDIO_MMD_VEND1, 1, 1),
+	.ltc_write		=
+		NXP_C45_REG_FIELD(0x1000, MDIO_MMD_VEND1, 2, 1),
+	.vend1_ltc_wr_nsec_0	= 0x1040,
+	.vend1_ltc_wr_nsec_1	= 0x1041,
+	.vend1_ltc_wr_sec_0	= 0x1042,
+	.vend1_ltc_wr_sec_1	= 0x1043,
+	.vend1_ltc_rd_nsec_0	= 0x1048,
+	.vend1_ltc_rd_nsec_1	= 0x1049,
+	.vend1_ltc_rd_sec_0	= 0x104A,
+	.vend1_ltc_rd_sec_1	= 0x104B,
+	.vend1_rate_adj_subns_0	= 0x1030,
+	.vend1_rate_adj_subns_1	= 0x1031,
+	.irq_egr_ts_en		=
+		NXP_C45_REG_FIELD(0x900A, MDIO_MMD_VEND1, 1, 1),
+	.irq_egr_ts_status	=
+		NXP_C45_REG_FIELD(0x900C, MDIO_MMD_VEND1, 1, 1),
+	.domain_number		=
+		NXP_C45_REG_FIELD(0x9061, MDIO_MMD_VEND1, 8, 8),
+	.msg_type		=
+		NXP_C45_REG_FIELD(0x9061, MDIO_MMD_VEND1, 4, 4),
+	.sequence_id		=
+		NXP_C45_REG_FIELD(0x9062, MDIO_MMD_VEND1, 0, 16),
+	.sec_1_0		=
+		NXP_C45_REG_FIELD(0x9065, MDIO_MMD_VEND1, 0, 2),
+	.sec_4_2		=
+		NXP_C45_REG_FIELD(0x9065, MDIO_MMD_VEND1, 2, 3),
+	.nsec_15_0		=
+		NXP_C45_REG_FIELD(0x9063, MDIO_MMD_VEND1, 0, 16),
+	.nsec_29_16		=
+		NXP_C45_REG_FIELD(0x9064, MDIO_MMD_VEND1, 0, 14),
+	.vend1_ext_trg_data_0	= 0x1071,
+	.vend1_ext_trg_data_1	= 0x1072,
+	.vend1_ext_trg_data_2	= 0x1073,
+	.vend1_ext_trg_data_3	= 0x1074,
+	.vend1_ext_trg_ctrl	= 0x1075,
+	.cable_test		= 0x8360,
+	.cable_test_valid	=
+		NXP_C45_REG_FIELD(0x8361, MDIO_MMD_VEND1, 15, 1),
+	.cable_test_result	=
+		NXP_C45_REG_FIELD(0x8361, MDIO_MMD_VEND1, 0, 3),
+};
+
+static const struct nxp_c45_phy_data tja1120_phy_data = {
+	.regmap = &tja1120_regmap,
+	.stats = tja1120_hw_stats,
+	.n_stats = ARRAY_SIZE(tja1120_hw_stats),
+	.ptp_clk_period = PTP_CLK_PERIOD_1000BT1,
+	.counters_enable = tja1120_counters_enable,
+	.ptp_init = tja1120_ptp_init,
+	.ptp_enable = tja1120_ptp_enable,
+};
+
 static struct phy_driver nxp_c45_driver[] = {
 	{
 		PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103),
@@ -1543,12 +1676,37 @@ static struct phy_driver nxp_c45_driver[] = {
 		.get_sqi_max		= nxp_c45_get_sqi_max,
 		.remove			= nxp_c45_remove,
 	},
+	{
+		PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120),
+		.name			= "NXP C45 TJA1120",
+		.features		= PHY_BASIC_T1_FEATURES,
+		.driver_data		= &tja1120_phy_data,
+		.probe			= nxp_c45_probe,
+		.soft_reset		= nxp_c45_soft_reset,
+		.config_aneg		= genphy_c45_config_aneg,
+		.config_init		= nxp_c45_config_init,
+		.config_intr		= nxp_c45_config_intr,
+		.handle_interrupt	= nxp_c45_handle_interrupt,
+		.read_status		= genphy_c45_read_status,
+		.suspend		= genphy_c45_pma_suspend,
+		.resume			= genphy_c45_pma_resume,
+		.get_sset_count		= nxp_c45_get_sset_count,
+		.get_strings		= nxp_c45_get_strings,
+		.get_stats		= nxp_c45_get_stats,
+		.cable_test_start	= nxp_c45_cable_test_start,
+		.cable_test_get_status	= nxp_c45_cable_test_get_status,
+		.set_loopback		= genphy_c45_loopback,
+		.get_sqi		= nxp_c45_get_sqi,
+		.get_sqi_max		= nxp_c45_get_sqi_max,
+		.remove			= nxp_c45_remove,
+	},
 };
 
 module_phy_driver(nxp_c45_driver);
 
 static struct mdio_device_id __maybe_unused nxp_c45_tbl[] = {
 	{ PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120) },
 	{ /*sentinel*/ },
 };
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 08/14] net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (6 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 07/14] net: phy: nxp-c45-tja11xx: add TJA1120 support Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-19  8:10   ` Horatiu Vultur
  2023-06-16 13:53 ` [PATCH net-next v1 09/14] net: phy: nxp-c45-tja11xx: read egress ts on TJA1120 Radu Pirea (NXP OSS)
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

The external trigger configuration for TJA1120 has changed. The PHY
supports sampling of the LTC on rising and on falling edge.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 64 +++++++++++++++++++++++++++----
 1 file changed, 56 insertions(+), 8 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 2160b9f8940c..6aa738396daf 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -104,6 +104,10 @@
 #define VEND1_PTP_CONFIG		0x1102
 #define EXT_TRG_EDGE			BIT(1)
 
+#define TJA1120_SYNC_TRIG_FILTER	0x1010
+#define PTP_TRIG_RISE_TS		BIT(3)
+#define PTP_TRIG_FALLING_TS		BIT(2)
+
 #define CLK_RATE_ADJ_LD			BIT(15)
 #define CLK_RATE_ADJ_DIR		BIT(14)
 
@@ -240,6 +244,7 @@ struct nxp_c45_phy_data {
 	const struct nxp_c45_phy_stats *stats;
 	int n_stats;
 	u8 ptp_clk_period;
+	bool ext_ts_both_edges;
 	void (*counters_enable)(struct phy_device *phydev);
 	void (*ptp_init)(struct phy_device *phydev);
 	void (*ptp_enable)(struct phy_device *phydev, bool enable);
@@ -682,9 +687,52 @@ static int nxp_c45_perout_enable(struct nxp_c45_phy *priv,
 	return 0;
 }
 
+static void nxp_c45_set_rising_or_falling(struct phy_device *phydev,
+					  struct ptp_extts_request *extts)
+{
+	/* Some enable request has only the PTP_ENABLE_FEATURE flag set and in
+	 * this case external ts should be enabled on rising edge.
+	 */
+	if (extts->flags & PTP_RISING_EDGE ||
+	    extts->flags == PTP_ENABLE_FEATURE)
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   VEND1_PTP_CONFIG, EXT_TRG_EDGE);
+
+	if (extts->flags & PTP_FALLING_EDGE)
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 VEND1_PTP_CONFIG, EXT_TRG_EDGE);
+}
+
+static void nxp_c45_set_rising_and_falling(struct phy_device *phydev,
+					   struct ptp_extts_request *extts)
+{
+	/* Some enable request has only the PTP_ENABLE_FEATURE flag set and in
+	 * this case external ts should be enabled on rising edge.
+	 */
+	if (extts->flags & PTP_RISING_EDGE ||
+	    extts->flags == PTP_ENABLE_FEATURE)
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 TJA1120_SYNC_TRIG_FILTER,
+				 PTP_TRIG_RISE_TS);
+	else
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   TJA1120_SYNC_TRIG_FILTER,
+				   PTP_TRIG_RISE_TS);
+
+	if (extts->flags & PTP_FALLING_EDGE)
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 TJA1120_SYNC_TRIG_FILTER,
+				 PTP_TRIG_FALLING_TS);
+	else
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   TJA1120_SYNC_TRIG_FILTER,
+				   PTP_TRIG_FALLING_TS);
+}
+
 static int nxp_c45_extts_enable(struct nxp_c45_phy *priv,
 				struct ptp_extts_request *extts, int on)
 {
+	const struct nxp_c45_phy_data *data = nxp_c45_get_data(priv->phydev);
 	int pin;
 
 	if (extts->flags & ~(PTP_ENABLE_FEATURE |
@@ -695,7 +743,8 @@ static int nxp_c45_extts_enable(struct nxp_c45_phy *priv,
 
 	/* Sampling on both edges is not supported */
 	if ((extts->flags & PTP_RISING_EDGE) &&
-	    (extts->flags & PTP_FALLING_EDGE))
+	    (extts->flags & PTP_FALLING_EDGE) &&
+	    !data->ext_ts_both_edges)
 		return -EOPNOTSUPP;
 
 	pin = ptp_find_pin(priv->ptp_clock, PTP_PF_EXTTS, extts->index);
@@ -709,13 +758,10 @@ static int nxp_c45_extts_enable(struct nxp_c45_phy *priv,
 		return 0;
 	}
 
-	if (extts->flags & PTP_RISING_EDGE)
-		phy_clear_bits_mmd(priv->phydev, MDIO_MMD_VEND1,
-				   VEND1_PTP_CONFIG, EXT_TRG_EDGE);
-
-	if (extts->flags & PTP_FALLING_EDGE)
-		phy_set_bits_mmd(priv->phydev, MDIO_MMD_VEND1,
-				 VEND1_PTP_CONFIG, EXT_TRG_EDGE);
+	if (data->ext_ts_both_edges)
+		nxp_c45_set_rising_and_falling(priv->phydev, extts);
+	else
+		nxp_c45_set_rising_or_falling(priv->phydev, extts);
 
 	nxp_c45_gpio_config(priv, pin, GPIO_EXTTS_OUT_CFG);
 	priv->extts = true;
@@ -1551,6 +1597,7 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
 	.stats = tja1103_hw_stats,
 	.n_stats = ARRAY_SIZE(tja1103_hw_stats),
 	.ptp_clk_period = PTP_CLK_PERIOD_100BT1,
+	.ext_ts_both_edges = false,
 	.counters_enable = tja1103_counters_enable,
 	.ptp_init = tja1103_ptp_init,
 	.ptp_enable = tja1103_ptp_enable,
@@ -1646,6 +1693,7 @@ static const struct nxp_c45_phy_data tja1120_phy_data = {
 	.stats = tja1120_hw_stats,
 	.n_stats = ARRAY_SIZE(tja1120_hw_stats),
 	.ptp_clk_period = PTP_CLK_PERIOD_1000BT1,
+	.ext_ts_both_edges = true,
 	.counters_enable = tja1120_counters_enable,
 	.ptp_init = tja1120_ptp_init,
 	.ptp_enable = tja1120_ptp_enable,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 09/14] net: phy: nxp-c45-tja11xx: read egress ts on TJA1120
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (7 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 08/14] net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 10/14] net: phy: nxp-c45-tja11xx: handle FUSA irq Radu Pirea (NXP OSS)
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

The egress timestamp FIFO/circular buffer work different on TJA1120 than
TJA1103.

For TJA1103 the new timestamp should be manually moved from the FIFO to
the hardware buffer before checking if the timestamp is valid.

For TJA1120 the hardware will move automatically the new timestamp
from the FIFO to the buffer and the user should check the valid bit, read
the timestamp and unlock the buffer by writing any of the buffer
registers(which are read only).

Another change for the TJA1120 is the behaviour of the EGR TS IRQ bit.
This bit was a self-clear bit for TJA1103, but now should be cleared
before reading the timestamp.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 85 ++++++++++++++++++++++++-------
 1 file changed, 67 insertions(+), 18 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 6aa738396daf..838bd4a638bc 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -29,6 +29,11 @@
 
 #define TJA1120_VEND1_EXT_TS_MODE	0x1012
 
+#define TJA1120_EGRESS_TS_DATA_S	0x9060
+#define TJA1120_EGRESS_TS_END		0x9067
+#define TJA1120_TS_VALID		BIT(0)
+#define TJA1120_MORE_TS			BIT(15)
+
 #define VEND1_PHY_IRQ_ACK		0x80A0
 #define VEND1_PHY_IRQ_EN		0x80A1
 #define VEND1_PHY_IRQ_STATUS		0x80A2
@@ -62,6 +67,9 @@
 #define VEND1_PORT_FUNC_IRQ_EN		0x807A
 #define PTP_IRQS			BIT(3)
 
+#define VEND1_PTP_IRQ_ACK		0x9008
+#define EGR_TS_IRQ			BIT(1)
+
 #define VEND1_PORT_INFRA_CONTROL	0xAC00
 #define PORT_INFRA_CONTROL_EN		BIT(14)
 
@@ -160,6 +168,8 @@
 
 #define NXP_C45_SKB_CB(skb)	((struct nxp_c45_skb_cb *)(skb)->cb)
 
+struct nxp_c45_phy;
+
 struct nxp_c45_skb_cb {
 	struct ptp_header *header;
 	unsigned int type;
@@ -245,7 +255,10 @@ struct nxp_c45_phy_data {
 	int n_stats;
 	u8 ptp_clk_period;
 	bool ext_ts_both_edges;
+	bool ack_ptp_irq;
 	void (*counters_enable)(struct phy_device *phydev);
+	bool (*get_egressts)(struct nxp_c45_phy *priv,
+			     struct nxp_c45_hwts *hwts);
 	void (*ptp_init)(struct phy_device *phydev);
 	void (*ptp_enable)(struct phy_device *phydev, bool enable);
 };
@@ -497,21 +510,11 @@ static void nxp_c45_get_extts(struct nxp_c45_phy *priv,
 		      regmap->vend1_ext_trg_ctrl, RING_DONE);
 }
 
-static bool nxp_c45_get_hwtxts(struct nxp_c45_phy *priv,
-			       struct nxp_c45_hwts *hwts)
+static void nxp_c45_read_egress_ts(struct nxp_c45_phy *priv,
+				   struct nxp_c45_hwts *hwts)
 {
 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
 	struct phy_device *phydev = priv->phydev;
-	bool valid;
-	u16 reg;
-
-	mutex_lock(&priv->ptp_lock);
-	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EGR_RING_CTRL,
-		      RING_DONE);
-	reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EGR_RING_DATA_0);
-	valid = !!(reg & RING_DATA_0_TS_VALID);
-	if (!valid)
-		goto nxp_c45_get_hwtxts_out;
 
 	hwts->domain_number =
 		nxp_c45_read_reg_field(phydev, &regmap->domain_number);
@@ -525,12 +528,49 @@ static bool nxp_c45_get_hwtxts(struct nxp_c45_phy *priv,
 		nxp_c45_read_reg_field(phydev, &regmap->nsec_29_16) << 16;
 	hwts->sec = nxp_c45_read_reg_field(phydev, &regmap->sec_1_0);
 	hwts->sec |= nxp_c45_read_reg_field(phydev, &regmap->sec_4_2) << 2;
+}
+
+static bool nxp_c45_get_hwtxts(struct nxp_c45_phy *priv,
+			       struct nxp_c45_hwts *hwts)
+{
+	bool valid;
+	u16 reg;
 
+	mutex_lock(&priv->ptp_lock);
+	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EGR_RING_CTRL,
+		      RING_DONE);
+	reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1, VEND1_EGR_RING_DATA_0);
+	valid = !!(reg & RING_DATA_0_TS_VALID);
+	if (!valid)
+		goto nxp_c45_get_hwtxts_out;
+
+	nxp_c45_read_egress_ts(priv, hwts);
 nxp_c45_get_hwtxts_out:
 	mutex_unlock(&priv->ptp_lock);
 	return valid;
 }
 
+static bool tja1120_get_hwtxts(struct nxp_c45_phy *priv,
+			       struct nxp_c45_hwts *hwts)
+{
+	struct phy_device *phydev = priv->phydev;
+	bool valid;
+	u16 reg;
+
+	mutex_lock(&priv->ptp_lock);
+	reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_DATA_S);
+	valid = !!(reg & TJA1120_TS_VALID);
+	if (!valid)
+		goto tja1120_get_hwtxts_out;
+
+	nxp_c45_read_egress_ts(priv, hwts);
+	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_DATA_S,
+			   TJA1120_TS_VALID);
+tja1120_get_hwtxts_out:
+	mutex_unlock(&priv->ptp_lock);
+	return valid;
+}
+
 static void nxp_c45_process_txts(struct nxp_c45_phy *priv,
 				 struct nxp_c45_hwts *txts)
 {
@@ -569,6 +609,7 @@ static void nxp_c45_process_txts(struct nxp_c45_phy *priv,
 static long nxp_c45_do_aux_work(struct ptp_clock_info *ptp)
 {
 	struct nxp_c45_phy *priv = container_of(ptp, struct nxp_c45_phy, caps);
+	const struct nxp_c45_phy_data *data = nxp_c45_get_data(priv->phydev);
 	bool poll_txts = nxp_c45_poll_txts(priv->phydev);
 	struct skb_shared_hwtstamps *shhwtstamps_rx;
 	struct ptp_clock_event event;
@@ -580,7 +621,7 @@ static long nxp_c45_do_aux_work(struct ptp_clock_info *ptp)
 	u32 ts_raw;
 
 	while (!skb_queue_empty_lockless(&priv->tx_queue) && poll_txts) {
-		txts_valid = nxp_c45_get_hwtxts(priv, &hwts);
+		txts_valid = data->get_egressts(priv, &hwts);
 		if (unlikely(!txts_valid)) {
 			/* Still more skbs in the queue */
 			reschedule = true;
@@ -1127,13 +1168,17 @@ static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev)
 	if (!data)
 		return ret;
 
-	/* There is no need for ACK.
-	 * The irq signal will be asserted until the EGR TS FIFO will be
-	 * emptied.
-	 */
 	irq = nxp_c45_read_reg_field(phydev, &data->regmap->irq_egr_ts_status);
 	if (irq) {
-		while (nxp_c45_get_hwtxts(priv, &hwts))
+		/* If ack_ptp_irq is false, the IRQ bit is self-clear and will
+		 * be cleared when the EGR TS FIFO is empty. Otherwise, the
+		 * IRQ bit should be cleared before reading the timestamp,
+		 */
+
+		if (data->ack_ptp_irq)
+			phy_write_mmd(phydev, MDIO_MMD_VEND1,
+				      VEND1_PTP_IRQ_ACK, EGR_TS_IRQ);
+		while (data->get_egressts(priv, &hwts))
 			nxp_c45_process_txts(priv, &hwts);
 
 		ret = IRQ_HANDLED;
@@ -1598,7 +1643,9 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
 	.n_stats = ARRAY_SIZE(tja1103_hw_stats),
 	.ptp_clk_period = PTP_CLK_PERIOD_100BT1,
 	.ext_ts_both_edges = false,
+	.ack_ptp_irq = false,
 	.counters_enable = tja1103_counters_enable,
+	.get_egressts = nxp_c45_get_hwtxts,
 	.ptp_init = tja1103_ptp_init,
 	.ptp_enable = tja1103_ptp_enable,
 };
@@ -1694,7 +1741,9 @@ static const struct nxp_c45_phy_data tja1120_phy_data = {
 	.n_stats = ARRAY_SIZE(tja1120_hw_stats),
 	.ptp_clk_period = PTP_CLK_PERIOD_1000BT1,
 	.ext_ts_both_edges = true,
+	.ack_ptp_irq = true,
 	.counters_enable = tja1120_counters_enable,
+	.get_egressts = tja1120_get_hwtxts,
 	.ptp_init = tja1120_ptp_init,
 	.ptp_enable = tja1120_ptp_enable,
 };
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 10/14] net: phy: nxp-c45-tja11xx: handle FUSA irq
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (8 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 09/14] net: phy: nxp-c45-tja11xx: read egress ts on TJA1120 Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 20:55   ` Andrew Lunn
  2023-06-16 13:53 ` [PATCH net-next v1 11/14] net: phy: nxp-c45-tja11xx: run cable test with the PHY in test mode Radu Pirea (NXP OSS)
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

TJA1120 and TJA1103 have a set of functional safety hardware tests
executed after every reset, and when the tests are done, the IRQ line is
asserted. For the moment, the purpose of these handlers is to acknowledge
the IRQ and not to check the FUSA tests status.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 72 ++++++++++++++++++++++++++++++-
 1 file changed, 70 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 838bd4a638bc..0a17a1e80a2b 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -29,6 +29,11 @@
 
 #define TJA1120_VEND1_EXT_TS_MODE	0x1012
 
+#define TJA1120_GLOBAL_INFRA_IRQ_ACK	0x2C08
+#define TJA1120_GLOBAL_INFRA_IRQ_EN	0x2C0A
+#define TJA1120_GLOBAL_INFRA_IRQ_STATUS	0x2C0C
+#define TJA1120_DEV_BOOT_DONE		BIT(1)
+
 #define TJA1120_EGRESS_TS_DATA_S	0x9060
 #define TJA1120_EGRESS_TS_END		0x9067
 #define TJA1120_TS_VALID		BIT(0)
@@ -39,6 +44,9 @@
 #define VEND1_PHY_IRQ_STATUS		0x80A2
 #define PHY_IRQ_LINK_EVENT		BIT(1)
 
+#define VEND1_ALWAYS_ACCESSIBLE		0x801F
+#define FUSA_PASS			BIT(4)
+
 #define VEND1_PHY_CONTROL		0x8100
 #define PHY_CONFIG_EN			BIT(14)
 #define PHY_START_OP			BIT(0)
@@ -261,6 +269,8 @@ struct nxp_c45_phy_data {
 			     struct nxp_c45_hwts *hwts);
 	void (*ptp_init)(struct phy_device *phydev);
 	void (*ptp_enable)(struct phy_device *phydev, bool enable);
+	void (*nmi_handler)(struct phy_device *phydev,
+			    irqreturn_t *irq_status);
 };
 
 struct nxp_c45_phy {
@@ -1148,6 +1158,29 @@ static int nxp_c45_config_intr(struct phy_device *phydev)
 	}
 }
 
+static int tja1103_config_intr(struct phy_device *phydev)
+{
+	/* We can't disable the FUSA IRQ for TJA1103, but we can clean it up. */
+	phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_ALWAYS_ACCESSIBLE,
+		      FUSA_PASS);
+
+	return nxp_c45_config_intr(phydev);
+}
+
+static int tja1120_config_intr(struct phy_device *phydev)
+{
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 TJA1120_GLOBAL_INFRA_IRQ_EN,
+				 TJA1120_DEV_BOOT_DONE);
+	else
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   TJA1120_GLOBAL_INFRA_IRQ_EN,
+				   TJA1120_DEV_BOOT_DONE);
+
+	return nxp_c45_config_intr(phydev);
+}
+
 static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev)
 {
 	struct nxp_c45_phy *priv = phydev->priv;
@@ -1184,6 +1217,9 @@ static irqreturn_t nxp_c45_handle_interrupt(struct phy_device *phydev)
 		ret = IRQ_HANDLED;
 	}
 
+	if (data->nmi_handler)
+		data->nmi_handler(phydev, &ret);
+
 	return ret;
 }
 
@@ -1584,6 +1620,21 @@ static void tja1103_ptp_enable(struct phy_device *phydev, bool enable)
 				 PORT_PTP_CONTROL_BYPASS);
 }
 
+static void tja1103_nmi_handler(struct phy_device *phydev,
+				irqreturn_t *irq_status)
+{
+	int ret;
+
+	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+			   VEND1_ALWAYS_ACCESSIBLE);
+	if (ret & FUSA_PASS) {
+		phy_write_mmd(phydev, MDIO_MMD_VEND1,
+			      VEND1_ALWAYS_ACCESSIBLE,
+			      FUSA_PASS);
+		*irq_status = IRQ_HANDLED;
+	}
+}
+
 static const struct nxp_c45_regmap tja1103_regmap = {
 	.vend1_ptp_clk_period	= 0x1104,
 	.vend1_event_msg_filt	= 0x1148,
@@ -1648,6 +1699,7 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
 	.get_egressts = nxp_c45_get_hwtxts,
 	.ptp_init = tja1103_ptp_init,
 	.ptp_enable = tja1103_ptp_enable,
+	.nmi_handler = tja1103_nmi_handler,
 };
 
 static void tja1120_counters_enable(struct phy_device *phydev)
@@ -1682,6 +1734,21 @@ static void tja1120_ptp_enable(struct phy_device *phydev, bool enable)
 				   PTP_ENABLE);
 }
 
+static void tja1120_nmi_handler(struct phy_device *phydev,
+				irqreturn_t *irq_status)
+{
+	int ret;
+
+	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+			   TJA1120_GLOBAL_INFRA_IRQ_STATUS);
+	if (ret & TJA1120_DEV_BOOT_DONE) {
+		phy_write_mmd(phydev, MDIO_MMD_VEND1,
+			      TJA1120_GLOBAL_INFRA_IRQ_ACK,
+			      TJA1120_DEV_BOOT_DONE);
+		*irq_status = IRQ_HANDLED;
+	}
+}
+
 static const struct nxp_c45_regmap tja1120_regmap = {
 	.vend1_ptp_clk_period	= 0x1020,
 	.vend1_event_msg_filt	= 0x9010,
@@ -1746,6 +1813,7 @@ static const struct nxp_c45_phy_data tja1120_phy_data = {
 	.get_egressts = tja1120_get_hwtxts,
 	.ptp_init = tja1120_ptp_init,
 	.ptp_enable = tja1120_ptp_enable,
+	.nmi_handler = tja1120_nmi_handler,
 };
 
 static struct phy_driver nxp_c45_driver[] = {
@@ -1758,7 +1826,7 @@ static struct phy_driver nxp_c45_driver[] = {
 		.soft_reset		= nxp_c45_soft_reset,
 		.config_aneg		= genphy_c45_config_aneg,
 		.config_init		= nxp_c45_config_init,
-		.config_intr		= nxp_c45_config_intr,
+		.config_intr		= tja1103_config_intr,
 		.handle_interrupt	= nxp_c45_handle_interrupt,
 		.read_status		= genphy_c45_read_status,
 		.suspend		= genphy_c45_pma_suspend,
@@ -1782,7 +1850,7 @@ static struct phy_driver nxp_c45_driver[] = {
 		.soft_reset		= nxp_c45_soft_reset,
 		.config_aneg		= genphy_c45_config_aneg,
 		.config_init		= nxp_c45_config_init,
-		.config_intr		= nxp_c45_config_intr,
+		.config_intr		= tja1120_config_intr,
 		.handle_interrupt	= nxp_c45_handle_interrupt,
 		.read_status		= genphy_c45_read_status,
 		.suspend		= genphy_c45_pma_suspend,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 11/14] net: phy: nxp-c45-tja11xx: run cable test with the PHY in test mode
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (9 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 10/14] net: phy: nxp-c45-tja11xx: handle FUSA irq Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120 Radu Pirea (NXP OSS)
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

For TJA1120, the enable bit for cable test is not writable if the PHY is
not in test mode.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 0a17a1e80a2b..4b40be45c955 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -144,6 +144,7 @@
 
 #define VEND1_PORT_FUNC_ENABLES		0x8048
 #define PTP_ENABLE			BIT(3)
+#define PHY_TEST_ENABLE			BIT(0)
 
 #define VEND1_PORT_PTP_CONTROL		0x9000
 #define PORT_PTP_CONTROL_BYPASS		BIT(11)
@@ -1242,6 +1243,8 @@ static int nxp_c45_cable_test_start(struct phy_device *phydev)
 {
 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(phydev);
 
+	phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+			 VEND1_PORT_FUNC_ENABLES, PHY_TEST_ENABLE);
 	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, regmap->cable_test,
 				CABLE_TEST_ENABLE | CABLE_TEST_START);
 }
@@ -1283,6 +1286,8 @@ static int nxp_c45_cable_test_get_status(struct phy_device *phydev,
 
 	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, regmap->cable_test,
 			   CABLE_TEST_ENABLE);
+	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+			   VEND1_PORT_FUNC_ENABLES, PHY_TEST_ENABLE);
 
 	return nxp_c45_start_op(phydev);
 }
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (10 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 11/14] net: phy: nxp-c45-tja11xx: run cable test with the PHY in test mode Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-19  8:49   ` Horatiu Vultur
  2023-06-16 13:53 ` [PATCH net-next v1 13/14] net: phy: nxp-c45-tja11xx: reset PCS if the link goes down Radu Pirea (NXP OSS)
  2023-06-16 13:53 ` [PATCH net-next v1 14/14] net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120 Radu Pirea (NXP OSS)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

On TJA1120, the external trigger timestamp now has a VALID bit. This
changes the logic and we can't use the TJA1103 procedure.

For TJA1103, we can always read a valid timestamp from the registers,
compare the new timestamp with the old timestamp and, if they are not the
same, an event occurred. This logic cannot be applied for TJA1120 because
the timestamp is 0 if the VALID bit is not set.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 36 +++++++++++++++++++++++++------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 4b40be45c955..0ed96d696bad 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -34,6 +34,8 @@
 #define TJA1120_GLOBAL_INFRA_IRQ_STATUS	0x2C0C
 #define TJA1120_DEV_BOOT_DONE		BIT(1)
 
+#define TJA1120_VEND1_PTP_TRIG_DATA_S	0x1070
+
 #define TJA1120_EGRESS_TS_DATA_S	0x9060
 #define TJA1120_EGRESS_TS_END		0x9067
 #define TJA1120_TS_VALID		BIT(0)
@@ -268,6 +270,7 @@ struct nxp_c45_phy_data {
 	void (*counters_enable)(struct phy_device *phydev);
 	bool (*get_egressts)(struct nxp_c45_phy *priv,
 			     struct nxp_c45_hwts *hwts);
+	bool (*get_extts)(struct nxp_c45_phy *priv, struct timespec64 *extts);
 	void (*ptp_init)(struct phy_device *phydev);
 	void (*ptp_enable)(struct phy_device *phydev, bool enable);
 	void (*nmi_handler)(struct phy_device *phydev,
@@ -504,7 +507,7 @@ static bool nxp_c45_match_ts(struct ptp_header *header,
 	       header->domain_number  == hwts->domain_number;
 }
 
-static void nxp_c45_get_extts(struct nxp_c45_phy *priv,
+static bool nxp_c45_get_extts(struct nxp_c45_phy *priv,
 			      struct timespec64 *extts)
 {
 	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
@@ -519,6 +522,23 @@ static void nxp_c45_get_extts(struct nxp_c45_phy *priv,
 				      regmap->vend1_ext_trg_data_3) << 16;
 	phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
 		      regmap->vend1_ext_trg_ctrl, RING_DONE);
+
+	return true;
+}
+
+static bool tja1120_get_extts(struct nxp_c45_phy *priv,
+			      struct timespec64 *extts)
+{
+	bool valid;
+	u16 reg;
+
+	reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
+			   TJA1120_VEND1_PTP_TRIG_DATA_S);
+	valid = !!(reg & TJA1120_TS_VALID);
+	if (valid)
+		return nxp_c45_get_extts(priv, extts);
+
+	return valid;
 }
 
 static void nxp_c45_read_egress_ts(struct nxp_c45_phy *priv,
@@ -628,12 +648,12 @@ static long nxp_c45_do_aux_work(struct ptp_clock_info *ptp)
 	bool reschedule = false;
 	struct timespec64 ts;
 	struct sk_buff *skb;
-	bool txts_valid;
+	bool ts_valid;
 	u32 ts_raw;
 
 	while (!skb_queue_empty_lockless(&priv->tx_queue) && poll_txts) {
-		txts_valid = data->get_egressts(priv, &hwts);
-		if (unlikely(!txts_valid)) {
+		ts_valid = data->get_egressts(priv, &hwts);
+		if (unlikely(!ts_valid)) {
 			/* Still more skbs in the queue */
 			reschedule = true;
 			break;
@@ -654,9 +674,9 @@ static long nxp_c45_do_aux_work(struct ptp_clock_info *ptp)
 		netif_rx(skb);
 	}
 
-	if (priv->extts) {
-		nxp_c45_get_extts(priv, &ts);
-		if (timespec64_compare(&ts, &priv->extts_ts) != 0) {
+	if (priv->extts && data->get_extts) {
+		ts_valid = data->get_extts(priv, &ts);
+		if (ts_valid && timespec64_compare(&ts, &priv->extts_ts) != 0) {
 			priv->extts_ts = ts;
 			event.index = priv->extts_index;
 			event.type = PTP_CLOCK_EXTTS;
@@ -1702,6 +1722,7 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
 	.ack_ptp_irq = false,
 	.counters_enable = tja1103_counters_enable,
 	.get_egressts = nxp_c45_get_hwtxts,
+	.get_extts = nxp_c45_get_extts,
 	.ptp_init = tja1103_ptp_init,
 	.ptp_enable = tja1103_ptp_enable,
 	.nmi_handler = tja1103_nmi_handler,
@@ -1816,6 +1837,7 @@ static const struct nxp_c45_phy_data tja1120_phy_data = {
 	.ack_ptp_irq = true,
 	.counters_enable = tja1120_counters_enable,
 	.get_egressts = tja1120_get_hwtxts,
+	.get_extts = tja1120_get_extts,
 	.ptp_init = tja1120_ptp_init,
 	.ptp_enable = tja1120_ptp_enable,
 	.nmi_handler = tja1120_nmi_handler,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 13/14] net: phy: nxp-c45-tja11xx: reset PCS if the link goes down
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (11 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120 Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-16 21:00   ` Andrew Lunn
  2023-06-16 13:53 ` [PATCH net-next v1 14/14] net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120 Radu Pirea (NXP OSS)
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

During PTP testing on early TJA1120 engineering samples I observed that
if the link is lost and recovered, the tx timestamps will be randomly
lost. To avoid this HW issue, the PCS should be reseted.

Resetting the PCS will break the link and we should reset the PCS on
LINK UP -> LINK DOWN transition, otherwise we will trigger and infinite
loop of LINK UP -> LINK DOWN events.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 0ed96d696bad..0d22eb7534dc 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -56,6 +56,9 @@
 #define VEND1_PHY_CONFIG		0x8108
 #define PHY_CONFIG_AUTO			BIT(0)
 
+#define TJA1120_EPHY_RESETS		0x810A
+#define EPHY_PCS_RESET			BIT(3)
+
 #define VEND1_SIGNAL_QUALITY		0x8320
 #define SQI_VALID			BIT(14)
 #define SQI_MASK			GENMASK(2, 0)
@@ -1325,6 +1328,28 @@ static int nxp_c45_get_sqi(struct phy_device *phydev)
 	return reg;
 }
 
+static int tja1120_read_status(struct phy_device *phydev)
+{
+	unsigned int link = phydev->link;
+	int ret;
+
+	ret = genphy_c45_read_status(phydev);
+	if (ret)
+		return ret;
+
+	/* Bug workaround for TJA1120 enegineering samples: fix egress
+	 * timestamps lost after link recovery.
+	 */
+	if (link && !phydev->link) {
+		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+				 TJA1120_EPHY_RESETS, EPHY_PCS_RESET);
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   TJA1120_EPHY_RESETS, EPHY_PCS_RESET);
+	}
+
+	return ret;
+}
+
 static int nxp_c45_get_sqi_max(struct phy_device *phydev)
 {
 	return MAX_SQI;
@@ -1879,7 +1904,7 @@ static struct phy_driver nxp_c45_driver[] = {
 		.config_init		= nxp_c45_config_init,
 		.config_intr		= tja1120_config_intr,
 		.handle_interrupt	= nxp_c45_handle_interrupt,
-		.read_status		= genphy_c45_read_status,
+		.read_status		= tja1120_read_status,
 		.suspend		= genphy_c45_pma_suspend,
 		.resume			= genphy_c45_pma_resume,
 		.get_sset_count		= nxp_c45_get_sset_count,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* [PATCH net-next v1 14/14] net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120
  2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
                   ` (12 preceding siblings ...)
  2023-06-16 13:53 ` [PATCH net-next v1 13/14] net: phy: nxp-c45-tja11xx: reset PCS if the link goes down Radu Pirea (NXP OSS)
@ 2023-06-16 13:53 ` Radu Pirea (NXP OSS)
  2023-06-19  8:58   ` Horatiu Vultur
  13 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (NXP OSS) @ 2023-06-16 13:53 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran
  Cc: netdev, linux-kernel, sebastian.tobuschat, Radu Pirea (NXP OSS)

On TJA1120 engineering samples, the new timestamp is stuck in the FIFO.
If the MORE_TS bit is set and the VALID bit is not set, we know that we
have a timestamp in the FIFO but not in the buffer.

To move the new timestamp in the buffer registers, the current
timestamp(which is invalid) is unlocked by writing any of the buffer
registers.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
---
 drivers/net/phy/nxp-c45-tja11xx.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
index 0d22eb7534dc..3543c8fe099c 100644
--- a/drivers/net/phy/nxp-c45-tja11xx.c
+++ b/drivers/net/phy/nxp-c45-tja11xx.c
@@ -532,15 +532,30 @@ static bool nxp_c45_get_extts(struct nxp_c45_phy *priv,
 static bool tja1120_get_extts(struct nxp_c45_phy *priv,
 			      struct timespec64 *extts)
 {
+	const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
+	bool more_ts;
 	bool valid;
 	u16 reg;
 
+	reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
+			   regmap->vend1_ext_trg_ctrl);
+	more_ts = !!(reg & TJA1120_MORE_TS);
+
 	reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
 			   TJA1120_VEND1_PTP_TRIG_DATA_S);
 	valid = !!(reg & TJA1120_TS_VALID);
 	if (valid)
 		return nxp_c45_get_extts(priv, extts);
 
+	/* Bug workaround for TJA1120 enegineering samples: move the new
+	 * timestamp from the FIFO to the buffer.
+	 */
+	if (more_ts) {
+		phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
+			      regmap->vend1_ext_trg_ctrl, RING_DONE);
+		return nxp_c45_get_extts(priv, extts);
+	}
+
 	return valid;
 }
 
@@ -588,15 +603,25 @@ static bool tja1120_get_hwtxts(struct nxp_c45_phy *priv,
 			       struct nxp_c45_hwts *hwts)
 {
 	struct phy_device *phydev = priv->phydev;
+	bool more_ts;
 	bool valid;
 	u16 reg;
 
 	mutex_lock(&priv->ptp_lock);
+	reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_END);
+	more_ts = !!(reg & TJA1120_MORE_TS);
 	reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_DATA_S);
 	valid = !!(reg & TJA1120_TS_VALID);
-	if (!valid)
-		goto tja1120_get_hwtxts_out;
-
+	if (!valid) {
+		if (!more_ts)
+			goto tja1120_get_hwtxts_out;
+		/* Bug workaround for TJA1120 enegineering samples: move the
+		 * new timestamp from the FIFO to the buffer.
+		 */
+		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+				   TJA1120_EGRESS_TS_END, TJA1120_TS_VALID);
+		valid = true;
+	}
 	nxp_c45_read_egress_ts(priv, hwts);
 	phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_DATA_S,
 			   TJA1120_TS_VALID);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120
  2023-06-16 13:53 ` [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120 Radu Pirea (NXP OSS)
@ 2023-06-16 19:35   ` Simon Horman
  2023-06-19  7:53   ` Horatiu Vultur
  1 sibling, 0 replies; 37+ messages in thread
From: Simon Horman @ 2023-06-16 19:35 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

On Fri, Jun 16, 2023 at 04:53:14PM +0300, Radu Pirea (NXP OSS) wrote:
> Remove the defined bits and register addresses that are not common
> between TJA1103 and TJA1120 and replace them with reg_fields and
> register addresses from phydev->drv->driver_data.
> 
> Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>

Hi Radu,

thanks for your patch-set.

Some minor points from my side.

> @@ -831,27 +862,26 @@ static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
>  	}
>  
>  	if (priv->hwts_rx || priv->hwts_tx) {
> -		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_EVENT_MSG_FILT,
> +		phy_write_mmd(phydev, MDIO_MMD_VEND1,
> +			      data->regmap->vend1_event_msg_filt,
>  			      EVENT_MSG_FILT_ALL);
> -		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> -				   VEND1_PORT_PTP_CONTROL,
> -				   PORT_PTP_CONTROL_BYPASS);
> +		if (data && data->ptp_enable)
> +			data->ptp_enable(phydev, true);

A check for data being null is made here before dereferencing.
But a few lines above data is dereferenced without such a guard.

This is flagged by Smatch as:

 .../nxp-c45-tja11xx.c:868 nxp_c45_hwtstamp() warn: variable dereferenced before check 'data' (see line 866)`

>  	} else {
> -		phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_EVENT_MSG_FILT,
> +		phy_write_mmd(phydev, MDIO_MMD_VEND1,
> +			      data->regmap->vend1_event_msg_filt,
>  			      EVENT_MSG_FILT_NONE);
> -		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_PTP_CONTROL,
> -				 PORT_PTP_CONTROL_BYPASS);
> +		if (data && data->ptp_enable)
> +			data->ptp_enable(phydev, false);

Likewise here.

>  	}
>  
>  	if (nxp_c45_poll_txts(priv->phydev))
>  		goto nxp_c45_no_ptp_irq;
>  
>  	if (priv->hwts_tx)
> -		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
> -				 VEND1_PTP_IRQ_EN, PTP_IRQ_EGR_TS);
> +		nxp_c45_set_reg_field(phydev, &data->regmap->irq_egr_ts_en);
>  	else
> -		phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> -				   VEND1_PTP_IRQ_EN, PTP_IRQ_EGR_TS);
> +		nxp_c45_clear_reg_field(phydev, &data->regmap->irq_egr_ts_en);
>  
>  nxp_c45_no_ptp_irq:
>  	return copy_to_user(ifreq->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;

...

> +static void nxp_c45_ptp_init(struct phy_device *phydev)
> +{
> +	const struct nxp_c45_phy_data *data = nxp_c45_get_data(phydev);
> +
> +	phy_write_mmd(phydev, MDIO_MMD_VEND1,
> +		      data->regmap->vend1_ptp_clk_period,
> +		      data->ptp_clk_period);
> +	nxp_c45_clear_reg_field(phydev, &data->regmap->ltc_lock_ctrl);
> +
> +	if (data && data->ptp_init)
> +		data->ptp_init(phydev);

And here.

> +}
> +

...

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling
  2023-06-16 13:53 ` [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling Radu Pirea (NXP OSS)
@ 2023-06-16 20:36   ` Andrew Lunn
  2023-06-19  8:42     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew Lunn @ 2023-06-16 20:36 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat, stable

On Fri, Jun 16, 2023 at 04:53:10PM +0300, Radu Pirea (NXP OSS) wrote:
> .config_intr() handles only the link event interrupt and should
> disable/enable the PTP interrupt also.
> 
> It's safe to disable/enable the PTP irq even if the egress ts irq
> is disabled. This interrupt, the PTP one, acts as a global switch for all
> PTP irqs.
> 
> Fixes: 514def5dd339 ("phy: nxp-c45-tja11xx: add timestamping support")
> CC: stable@vger.kernel.org # 5.15+
> Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>

Please don't mix fixes and development work in one patchset. Please
post this to applying to net, not net-next.

>  static int nxp_c45_config_intr(struct phy_device *phydev)
>  {
> -	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
> +	/* The return value is ignored on purpose. It might be < 0.
> +	 * 0x807A register is not present on SJA1110 PHYs.
> +	 */
> +	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
> +		phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
> +				 VEND1_PORT_FUNC_IRQ_EN, PTP_IRQS);
>  		return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
>  					VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);

phy_set_bits_mmd() will not return an error if the register does not
exist. There is no such indication for MDIO. This is going to do a
read/modify/write. That read might get 0xffff, or random junk. And
then the write back will be successful. The only time
phy_read()/phy_write return error is when there is a problem within
the bus master, like its clock gets turned off and the transfer times
out.

So it is good to document you are accessing a register which might not
exist, but there is no need to ignore the return code.

       Andrew

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 02/14] net: phy: nxp-c45-tja11xx: use phylib master/slave implementation
  2023-06-16 13:53 ` [PATCH net-next v1 02/14] net: phy: nxp-c45-tja11xx: use phylib master/slave implementation Radu Pirea (NXP OSS)
@ 2023-06-16 20:37   ` Andrew Lunn
  0 siblings, 0 replies; 37+ messages in thread
From: Andrew Lunn @ 2023-06-16 20:37 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

On Fri, Jun 16, 2023 at 04:53:11PM +0300, Radu Pirea (NXP OSS) wrote:
> Remove the custom implementation of master/save setup and read status
> and use genphy_c45_config_aneg and genphy_c45_read_status since phylib
> has support for master/slave setup and master/slave status.
> 
> Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 03/14] net: phy: nxp-c45-tja11xx: remove RX BIST frame counters
  2023-06-16 13:53 ` [PATCH net-next v1 03/14] net: phy: nxp-c45-tja11xx: remove RX BIST frame counters Radu Pirea (NXP OSS)
@ 2023-06-16 20:39   ` Andrew Lunn
  2023-06-22 12:21     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew Lunn @ 2023-06-16 20:39 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

On Fri, Jun 16, 2023 at 04:53:12PM +0300, Radu Pirea (NXP OSS) wrote:
> RX BIST frame counters can be used only when the PHY is in test mode. In
> production mode, the counters will be always read as 0. So, they don't
> provide any useful information and are removed from the statistics.

Hummm

I wounder if this would be considered an ABI change?

	Andrew

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 04/14] net: phy: nxp-c45-tja11xx: add *_reg_field functions
  2023-06-16 13:53 ` [PATCH net-next v1 04/14] net: phy: nxp-c45-tja11xx: add *_reg_field functions Radu Pirea (NXP OSS)
@ 2023-06-16 20:42   ` Andrew Lunn
  0 siblings, 0 replies; 37+ messages in thread
From: Andrew Lunn @ 2023-06-16 20:42 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

> +static int nxp_c45_read_reg_field(struct phy_device *phydev,
> +				  const struct nxp_c45_reg_field *reg_field)
> +{
> +	u16 mask;
> +	int ret;
> +
> +	if (reg_field->size == 0) {
> +		phydev_warn(phydev, "Trying to read a reg field of size 0.");

I would actually use phydev_err(). 

> +	if (reg_field->size == 0) {
> +		phydev_warn(phydev, "Trying to write a reg field of size 0.");

Here as well.


    Andrew

---
pw-bot: cr

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 06/14] net: phy: add 1000baseT1 to phy_basic_t1_features
  2023-06-16 13:53 ` [PATCH net-next v1 06/14] net: phy: add 1000baseT1 to phy_basic_t1_features Radu Pirea (NXP OSS)
@ 2023-06-16 20:49   ` Andrew Lunn
  2023-06-19 11:01     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew Lunn @ 2023-06-16 20:49 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

On Fri, Jun 16, 2023 at 04:53:15PM +0300, Radu Pirea (NXP OSS) wrote:
> Add 1000baseT1 bit to phy_basic_t1_features.

Please add an explanation why this is safe. For example, why the
RTL9000AA does not start saying it supports 1000BaseT1_Full.

Has 1000BaseT1_Full been standardised? If there a feature bit in a
register to indicate the hardware supports it? That would be the
preferred method to determine what the hardware can do.

	Andrew

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 10/14] net: phy: nxp-c45-tja11xx: handle FUSA irq
  2023-06-16 13:53 ` [PATCH net-next v1 10/14] net: phy: nxp-c45-tja11xx: handle FUSA irq Radu Pirea (NXP OSS)
@ 2023-06-16 20:55   ` Andrew Lunn
  2023-06-19  6:31     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew Lunn @ 2023-06-16 20:55 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

> +#define VEND1_ALWAYS_ACCESSIBLE		0x801F

Odd name. Is there a VEND1_NEVER_ACCESSIBLE?
VEND1_SOMETIMES_ACCESSIBLE?

	Andrew

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 13/14] net: phy: nxp-c45-tja11xx: reset PCS if the link goes down
  2023-06-16 13:53 ` [PATCH net-next v1 13/14] net: phy: nxp-c45-tja11xx: reset PCS if the link goes down Radu Pirea (NXP OSS)
@ 2023-06-16 21:00   ` Andrew Lunn
  2023-06-19  6:17     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Andrew Lunn @ 2023-06-16 21:00 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

On Fri, Jun 16, 2023 at 04:53:22PM +0300, Radu Pirea (NXP OSS) wrote:
> During PTP testing on early TJA1120 engineering samples I observed that
> if the link is lost and recovered, the tx timestamps will be randomly
> lost. To avoid this HW issue, the PCS should be reseted.
> 
> Resetting the PCS will break the link and we should reset the PCS on
> LINK UP -> LINK DOWN transition, otherwise we will trigger and infinite
> loop of LINK UP -> LINK DOWN events.

> +static int tja1120_read_status(struct phy_device *phydev)
> +{
> +	unsigned int link = phydev->link;
> +	int ret;

Maybe consider using link_change_notify:

        /**
         * @link_change_notify: Called to inform a PHY device driver
         * when the core is about to change the link state. This
         * callback is supposed to be used as fixup hook for drivers
         * that need to take action when the link state
         * changes. Drivers are by no means allowed to mess with the
         * PHY device structure in their implementations.
         */
        void (*link_change_notify)(struct phy_device *dev);

Seems like a fixup to me.

      Andrew

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 13/14] net: phy: nxp-c45-tja11xx: reset PCS if the link goes down
  2023-06-16 21:00   ` Andrew Lunn
@ 2023-06-19  6:17     ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-19  6:17 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

On 17.06.2023 00:00, Andrew Lunn wrote:
> On Fri, Jun 16, 2023 at 04:53:22PM +0300, Radu Pirea (NXP OSS) wrote:
>> During PTP testing on early TJA1120 engineering samples I observed that
>> if the link is lost and recovered, the tx timestamps will be randomly
>> lost. To avoid this HW issue, the PCS should be reseted.
>>
>> Resetting the PCS will break the link and we should reset the PCS on
>> LINK UP -> LINK DOWN transition, otherwise we will trigger and infinite
>> loop of LINK UP -> LINK DOWN events.
> 
>> +static int tja1120_read_status(struct phy_device *phydev)
>> +{
>> +     unsigned int link = phydev->link;
>> +     int ret;
> 
> Maybe consider using link_change_notify:
> 
>          /**
>           * @link_change_notify: Called to inform a PHY device driver
>           * when the core is about to change the link state. This
>           * callback is supposed to be used as fixup hook for drivers
>           * that need to take action when the link state
>           * changes. Drivers are by no means allowed to mess with the
>           * PHY device structure in their implementations.
>           */
>          void (*link_change_notify)(struct phy_device *dev);
> 
> Seems like a fixup to me.
> 
>        Andrew

Ok. link_change_notify seems the right callback for this fix.
Thank you.

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 10/14] net: phy: nxp-c45-tja11xx: handle FUSA irq
  2023-06-16 20:55   ` Andrew Lunn
@ 2023-06-19  6:31     ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-19  6:31 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

On 16.06.2023 23:55, Andrew Lunn wrote:
>> +#define VEND1_ALWAYS_ACCESSIBLE              0x801F
> 
> Odd name. Is there a VEND1_NEVER_ACCESSIBLE?
> VEND1_SOMETIMES_ACCESSIBLE?
> 
>          Andrew

This is the name of the register in the TJA1103 user manual. It is 
accessible when the PHY is in sleep or the VDD_CORE is missing. However, 
VDDIO and VDDAO must be present to access it.

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120
  2023-06-16 13:53 ` [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120 Radu Pirea (NXP OSS)
  2023-06-16 19:35   ` Simon Horman
@ 2023-06-19  7:53   ` Horatiu Vultur
  1 sibling, 0 replies; 37+ messages in thread
From: Horatiu Vultur @ 2023-06-19  7:53 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

The 06/16/2023 16:53, Radu Pirea (NXP OSS) wrote:

Hi Radu,

> 
> 
> -struct nxp_c45_phy_stats {
> -       const char      *name;
> -       u8              mmd;
> -       u16             reg;
> -       u8              off;
> -       u16             mask;
> -};
> +static inline

It is recommended not to use inline inside .c files.

> +const struct nxp_c45_phy_data *nxp_c45_get_data(struct phy_device *phydev)
> +{
> +       return phydev->drv->driver_data;
> +}
> +
> +static inline
> +const struct nxp_c45_regmap *nxp_c45_get_regmap(struct phy_device *phydev)
> +{
> +       const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
> +
> +       return phy_data ? phy_data->regmap : NULL;

From what I can see nxp_c45_get_data(phydev) can't return a NULL pointer
so then I don't think you need the above check. And then maybe you can
remove more of the checks in the code where you check for data to not be
NULL.
The reason why I say nxp_c45_get_data(phydev) can't return a NULL is
because few lines bellow you have:

.driver_data            = &tja1103_phy_data,

...

> +}
> @@ -806,6 +835,7 @@ static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
>         struct nxp_c45_phy *priv = container_of(mii_ts, struct nxp_c45_phy,
>                                                 mii_ts);
>         struct phy_device *phydev = priv->phydev;
> +       const struct nxp_c45_phy_data *data;
>         struct hwtstamp_config cfg;
> 
>         if (copy_from_user(&cfg, ifreq->ifr_data, sizeof(cfg)))
> @@ -814,6 +844,7 @@ static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
>         if (cfg.tx_type < 0 || cfg.tx_type > HWTSTAMP_TX_ON)
>                 return -ERANGE;
> 
> +       data = nxp_c45_get_data(phydev);
>         priv->hwts_tx = cfg.tx_type;
> 
>         switch (cfg.rx_filter) {
> @@ -831,27 +862,26 @@ static int nxp_c45_hwtstamp(struct mii_timestamper *mii_ts,
>         }
> 
>         if (priv->hwts_rx || priv->hwts_tx) {
> -               phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_EVENT_MSG_FILT,
> +               phy_write_mmd(phydev, MDIO_MMD_VEND1,
> +                             data->regmap->vend1_event_msg_filt,
>                               EVENT_MSG_FILT_ALL);
> -               phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> -                                  VEND1_PORT_PTP_CONTROL,
> -                                  PORT_PTP_CONTROL_BYPASS);
> +               if (data && data->ptp_enable)

Like here

> +                       data->ptp_enable(phydev, true);
>         } else {
> -               phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_EVENT_MSG_FILT,
> +               phy_write_mmd(phydev, MDIO_MMD_VEND1,
> +                             data->regmap->vend1_event_msg_filt,
>                               EVENT_MSG_FILT_NONE);
> -               phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_PORT_PTP_CONTROL,
> -                                PORT_PTP_CONTROL_BYPASS);
> +               if (data && data->ptp_enable)

And here and few other places bellow:

> +                       data->ptp_enable(phydev, false);
>         }
> 
>         if (nxp_c45_poll_txts(priv->phydev))
>                 goto nxp_c45_no_ptp_irq;
> 
>         if (priv->hwts_tx)
> -               phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
> -                                VEND1_PTP_IRQ_EN, PTP_IRQ_EGR_TS);
> +               nxp_c45_set_reg_field(phydev, &data->regmap->irq_egr_ts_en);
>         else
> -               phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> -                                  VEND1_PTP_IRQ_EN, PTP_IRQ_EGR_TS);
> +               nxp_c45_clear_reg_field(phydev, &data->regmap->irq_egr_ts_en);
> 

...

> 
> +static const struct nxp_c45_phy_data tja1103_phy_data = {
> +       .regmap = &tja1103_regmap,
> +       .stats = tja1103_hw_stats,
> +       .n_stats = ARRAY_SIZE(tja1103_hw_stats),
> +       .ptp_clk_period = PTP_CLK_PERIOD_100BT1,
> +       .counters_enable = tja1103_counters_enable,
> +       .ptp_init = tja1103_ptp_init,
> +       .ptp_enable = tja1103_ptp_enable,
> +};
> +
>  static struct phy_driver nxp_c45_driver[] = {
>         {
>                 PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103),
>                 .name                   = "NXP C45 TJA1103",
>                 .features               = PHY_BASIC_T1_FEATURES,
> +               .driver_data            = &tja1103_phy_data,
>                 .probe                  = nxp_c45_probe,
>                 .soft_reset             = nxp_c45_soft_reset,
>                 .config_aneg            = genphy_c45_config_aneg,
> --
> 2.34.1
> 
> 

-- 
/Horatiu

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 08/14] net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges
  2023-06-16 13:53 ` [PATCH net-next v1 08/14] net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges Radu Pirea (NXP OSS)
@ 2023-06-19  8:10   ` Horatiu Vultur
  2023-06-19  8:36     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Horatiu Vultur @ 2023-06-19  8:10 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

The 06/16/2023 16:53, Radu Pirea (NXP OSS) wrote:

Hi Radu,

> 
> The external trigger configuration for TJA1120 has changed. The PHY
> supports sampling of the LTC on rising and on falling edge.

> 
> Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
> ---
>  drivers/net/phy/nxp-c45-tja11xx.c | 64 +++++++++++++++++++++++++++----
>  1 file changed, 56 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
> index 2160b9f8940c..6aa738396daf 100644
> --- a/drivers/net/phy/nxp-c45-tja11xx.c
> +++ b/drivers/net/phy/nxp-c45-tja11xx.c
> @@ -104,6 +104,10 @@
>  #define VEND1_PTP_CONFIG               0x1102
>  #define EXT_TRG_EDGE                   BIT(1)
> 
> +#define TJA1120_SYNC_TRIG_FILTER       0x1010
> +#define PTP_TRIG_RISE_TS               BIT(3)
> +#define PTP_TRIG_FALLING_TS            BIT(2)
> +
>  #define CLK_RATE_ADJ_LD                        BIT(15)
>  #define CLK_RATE_ADJ_DIR               BIT(14)
> 
> @@ -240,6 +244,7 @@ struct nxp_c45_phy_data {
>         const struct nxp_c45_phy_stats *stats;
>         int n_stats;
>         u8 ptp_clk_period;
> +       bool ext_ts_both_edges;
>         void (*counters_enable)(struct phy_device *phydev);
>         void (*ptp_init)(struct phy_device *phydev);
>         void (*ptp_enable)(struct phy_device *phydev, bool enable);
> @@ -682,9 +687,52 @@ static int nxp_c45_perout_enable(struct nxp_c45_phy *priv,
>         return 0;
>  }
> 
> +static void nxp_c45_set_rising_or_falling(struct phy_device *phydev,
> +                                         struct ptp_extts_request *extts)
> +{
> +       /* Some enable request has only the PTP_ENABLE_FEATURE flag set and in
> +        * this case external ts should be enabled on rising edge.
> +        */
> +       if (extts->flags & PTP_RISING_EDGE ||
> +           extts->flags == PTP_ENABLE_FEATURE)
> +               phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> +                                  VEND1_PTP_CONFIG, EXT_TRG_EDGE);

With this patch, are you not changing the behaviour for TJA1103?
In the way, before there was not check for extts->flags ==
PTP_ENABLE_FEATURE and now if that is set you configure to trigger on
raising edge. If that is the case, shouldn't be this in a different
patch?

> +
> +       if (extts->flags & PTP_FALLING_EDGE)
> +               phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
> +                                VEND1_PTP_CONFIG, EXT_TRG_EDGE);
> +}
> +
 

-- 
/Horatiu

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 08/14] net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges
  2023-06-19  8:10   ` Horatiu Vultur
@ 2023-06-19  8:36     ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-19  8:36 UTC (permalink / raw)
  To: Horatiu Vultur
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

On 19.06.2023 11:10, Horatiu Vultur wrote:
> The 06/16/2023 16:53, Radu Pirea (NXP OSS) wrote:
>>
>> +static void nxp_c45_set_rising_or_falling(struct phy_device *phydev,
>> +                                         struct ptp_extts_request *extts)
>> +{
>> +       /* Some enable request has only the PTP_ENABLE_FEATURE flag set and in
>> +        * this case external ts should be enabled on rising edge.
>> +        */
>> +       if (extts->flags & PTP_RISING_EDGE ||
>> +           extts->flags == PTP_ENABLE_FEATURE)
>> +               phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
>> +                                  VEND1_PTP_CONFIG, EXT_TRG_EDGE);
> 
> With this patch, are you not changing the behaviour for TJA1103?

Yes. The behaviour is changed. If extts->flags == PTP_ENABLE_FEATURE, 
the ext ts will be enabled on falling edge.

> In the way, before there was not check for extts->flags ==
> PTP_ENABLE_FEATURE and now if that is set you configure to trigger on
> raising edge. If that is the case, shouldn't be this in a different
> patch?

You are right. I will split this patch in two. One that enables ext ts 
on rising edge when extts->flags == PTP_ENABLE_FEATURE and another one 
with TJA1120 changes.

> 
>> +
>> +       if (extts->flags & PTP_FALLING_EDGE)
>> +               phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
>> +                                VEND1_PTP_CONFIG, EXT_TRG_EDGE);
>> +}
>> +
> 
> 
> --
> /Horatiu

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling
  2023-06-16 20:36   ` Andrew Lunn
@ 2023-06-19  8:42     ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-19  8:42 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat, stable

On 16.06.2023 23:36, Andrew Lunn wrote:
> On Fri, Jun 16, 2023 at 04:53:10PM +0300, Radu Pirea (NXP OSS) wrote:
>> .config_intr() handles only the link event interrupt and should
>> disable/enable the PTP interrupt also.
>>
>> It's safe to disable/enable the PTP irq even if the egress ts irq
>> is disabled. This interrupt, the PTP one, acts as a global switch for all
>> PTP irqs.
>>
>> Fixes: 514def5dd339 ("phy: nxp-c45-tja11xx: add timestamping support")
>> CC: stable@vger.kernel.org # 5.15+
>> Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
> 
> Please don't mix fixes and development work in one patchset. Please
> post this to applying to net, not net-next.

Ok. I will send it to net and apply your suggestions.

> 
>>   static int nxp_c45_config_intr(struct phy_device *phydev)
>>   {
>> -     if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
>> +     /* The return value is ignored on purpose. It might be < 0.
>> +      * 0x807A register is not present on SJA1110 PHYs.
>> +      */
>> +     if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
>> +             phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
>> +                              VEND1_PORT_FUNC_IRQ_EN, PTP_IRQS);
>>                return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
>>                                        VEND1_PHY_IRQ_EN, PHY_IRQ_LINK_EVENT);
> 
> phy_set_bits_mmd() will not return an error if the register does not
> exist. There is no such indication for MDIO. This is going to do a
> read/modify/write. That read might get 0xffff, or random junk. And
> then the write back will be successful. The only time
> phy_read()/phy_write return error is when there is a problem within
> the bus master, like its clock gets turned off and the transfer times
> out.
> 
> So it is good to document you are accessing a register which might not
> exist, but there is no need to ignore the return code.
> 
>         Andrew

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120
  2023-06-16 13:53 ` [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120 Radu Pirea (NXP OSS)
@ 2023-06-19  8:49   ` Horatiu Vultur
  2023-06-19 10:07     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Horatiu Vultur @ 2023-06-19  8:49 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

The 06/16/2023 16:53, Radu Pirea (NXP OSS) wrote:

Hi Radu,

> 
>  static void nxp_c45_read_egress_ts(struct nxp_c45_phy *priv,
> @@ -628,12 +648,12 @@ static long nxp_c45_do_aux_work(struct ptp_clock_info *ptp)
>         bool reschedule = false;
>         struct timespec64 ts;
>         struct sk_buff *skb;
> -       bool txts_valid;
> +       bool ts_valid;
>         u32 ts_raw;
> 
>         while (!skb_queue_empty_lockless(&priv->tx_queue) && poll_txts) {
> -               txts_valid = data->get_egressts(priv, &hwts);
> -               if (unlikely(!txts_valid)) {
> +               ts_valid = data->get_egressts(priv, &hwts);
> +               if (unlikely(!ts_valid)) {
>                         /* Still more skbs in the queue */
>                         reschedule = true;
>                         break;
> @@ -654,9 +674,9 @@ static long nxp_c45_do_aux_work(struct ptp_clock_info *ptp)
>                 netif_rx(skb);
>         }
> 
> -       if (priv->extts) {
> -               nxp_c45_get_extts(priv, &ts);
> -               if (timespec64_compare(&ts, &priv->extts_ts) != 0) {
> +       if (priv->extts && data->get_extts) {

The data->get_extts can't be null. So I don't think you need this check.

> +               ts_valid = data->get_extts(priv, &ts);
> +               if (ts_valid && timespec64_compare(&ts, &priv->extts_ts) != 0) {
>                         priv->extts_ts = ts;
>                         event.index = priv->extts_index;
>                         event.type = PTP_CLOCK_EXTTS;
> @@ -1702,6 +1722,7 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
>         .ack_ptp_irq = false,
>         .counters_enable = tja1103_counters_enable,
>         .get_egressts = nxp_c45_get_hwtxts,
> +       .get_extts = nxp_c45_get_extts,
>         .ptp_init = tja1103_ptp_init,
>         .ptp_enable = tja1103_ptp_enable,
>         .nmi_handler = tja1103_nmi_handler,
> @@ -1816,6 +1837,7 @@ static const struct nxp_c45_phy_data tja1120_phy_data = {
>         .ack_ptp_irq = true,
>         .counters_enable = tja1120_counters_enable,
>         .get_egressts = tja1120_get_hwtxts,
> +       .get_extts = tja1120_get_extts,
>         .ptp_init = tja1120_ptp_init,
>         .ptp_enable = tja1120_ptp_enable,
>         .nmi_handler = tja1120_nmi_handler,
> --
> 2.34.1
> 
> 

-- 
/Horatiu

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 14/14] net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120
  2023-06-16 13:53 ` [PATCH net-next v1 14/14] net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120 Radu Pirea (NXP OSS)
@ 2023-06-19  8:58   ` Horatiu Vultur
  2023-06-19  9:46     ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Horatiu Vultur @ 2023-06-19  8:58 UTC (permalink / raw)
  To: Radu Pirea (NXP OSS)
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

The 06/16/2023 16:53, Radu Pirea (NXP OSS) wrote:

Hi Radu,

> 
> On TJA1120 engineering samples, the new timestamp is stuck in the FIFO.
> If the MORE_TS bit is set and the VALID bit is not set, we know that we
> have a timestamp in the FIFO but not in the buffer.
> 
> To move the new timestamp in the buffer registers, the current
> timestamp(which is invalid) is unlocked by writing any of the buffer
> registers.

Shouldn't this be split and merged in patch 9 and patch 10?
As those two patches introduced this functions with issues.

> 
> Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
> ---
>  drivers/net/phy/nxp-c45-tja11xx.c | 31 ++++++++++++++++++++++++++++---
>  1 file changed, 28 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/phy/nxp-c45-tja11xx.c b/drivers/net/phy/nxp-c45-tja11xx.c
> index 0d22eb7534dc..3543c8fe099c 100644
> --- a/drivers/net/phy/nxp-c45-tja11xx.c
> +++ b/drivers/net/phy/nxp-c45-tja11xx.c
> @@ -532,15 +532,30 @@ static bool nxp_c45_get_extts(struct nxp_c45_phy *priv,
>  static bool tja1120_get_extts(struct nxp_c45_phy *priv,
>                               struct timespec64 *extts)
>  {
> +       const struct nxp_c45_regmap *regmap = nxp_c45_get_regmap(priv->phydev);
> +       bool more_ts;
>         bool valid;
>         u16 reg;
> 
> +       reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
> +                          regmap->vend1_ext_trg_ctrl);
> +       more_ts = !!(reg & TJA1120_MORE_TS);
> +
>         reg = phy_read_mmd(priv->phydev, MDIO_MMD_VEND1,
>                            TJA1120_VEND1_PTP_TRIG_DATA_S);
>         valid = !!(reg & TJA1120_TS_VALID);
>         if (valid)
>                 return nxp_c45_get_extts(priv, extts);
> 
> +       /* Bug workaround for TJA1120 enegineering samples: move the new
> +        * timestamp from the FIFO to the buffer.
> +        */
> +       if (more_ts) {
> +               phy_write_mmd(priv->phydev, MDIO_MMD_VEND1,
> +                             regmap->vend1_ext_trg_ctrl, RING_DONE);
> +               return nxp_c45_get_extts(priv, extts);
> +       }
> +
>         return valid;
>  }
> 
> @@ -588,15 +603,25 @@ static bool tja1120_get_hwtxts(struct nxp_c45_phy *priv,
>                                struct nxp_c45_hwts *hwts)
>  {
>         struct phy_device *phydev = priv->phydev;
> +       bool more_ts;
>         bool valid;
>         u16 reg;
> 
>         mutex_lock(&priv->ptp_lock);
> +       reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_END);
> +       more_ts = !!(reg & TJA1120_MORE_TS);
>         reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_DATA_S);
>         valid = !!(reg & TJA1120_TS_VALID);
> -       if (!valid)
> -               goto tja1120_get_hwtxts_out;
> -
> +       if (!valid) {
> +               if (!more_ts)
> +                       goto tja1120_get_hwtxts_out;
> +               /* Bug workaround for TJA1120 enegineering samples: move the
> +                * new timestamp from the FIFO to the buffer.
> +                */
> +               phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
> +                                  TJA1120_EGRESS_TS_END, TJA1120_TS_VALID);
> +               valid = true;
> +       }
>         nxp_c45_read_egress_ts(priv, hwts);
>         phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, TJA1120_EGRESS_TS_DATA_S,
>                            TJA1120_TS_VALID);
> --
> 2.34.1
> 
> 

-- 
/Horatiu

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 14/14] net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120
  2023-06-19  8:58   ` Horatiu Vultur
@ 2023-06-19  9:46     ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-19  9:46 UTC (permalink / raw)
  To: Horatiu Vultur
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat


On 19.06.2023 11:58, Horatiu Vultur wrote:
> The 06/16/2023 16:53, Radu Pirea (NXP OSS) wrote:
> 
> Hi Radu,
> 
>>
>> On TJA1120 engineering samples, the new timestamp is stuck in the FIFO.
>> If the MORE_TS bit is set and the VALID bit is not set, we know that we
>> have a timestamp in the FIFO but not in the buffer.
>>
>> To move the new timestamp in the buffer registers, the current
>> timestamp(which is invalid) is unlocked by writing any of the buffer
>> registers.
> 
> Shouldn't this be split and merged in patch 9 and patch 10?
> As those two patches introduced this functions with issues.
> 
Ok. I will merge the workarounds in patches 9 and 12 if it looks better 
to you. The intention here was to implement the timestamp reading 
sequence in a clean way and to add the workarounds later.
>>
>>
> 
> --
> /Horatiu

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120
  2023-06-19  8:49   ` Horatiu Vultur
@ 2023-06-19 10:07     ` Radu Pirea (OSS)
  2023-06-19 10:48       ` Horatiu Vultur
  0 siblings, 1 reply; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-19 10:07 UTC (permalink / raw)
  To: Horatiu Vultur
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

On 19.06.2023 11:49, Horatiu Vultur wrote:
> The data->get_extts can't be null. So I don't think you need this check.

I kinda agree with this because _I wrote the driver and I know what it 
does_, but on the other hand don't want to fight with any static analyzer.

> 
> --
> /Horatiu

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120
  2023-06-19 10:07     ` Radu Pirea (OSS)
@ 2023-06-19 10:48       ` Horatiu Vultur
  2023-06-20 14:31         ` Radu Pirea (OSS)
  0 siblings, 1 reply; 37+ messages in thread
From: Horatiu Vultur @ 2023-06-19 10:48 UTC (permalink / raw)
  To: Radu Pirea (OSS)
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat

The 06/19/2023 13:07, Radu Pirea (OSS) wrote:
> 
> On 19.06.2023 11:49, Horatiu Vultur wrote:
> > The data->get_extts can't be null. So I don't think you need this check.
> 
> I kinda agree with this because _I wrote the driver and I know what it
> does_, but on the other hand don't want to fight with any static analyzer.

Yes, but then wouldn't be an issue with the static analyzer tools that
can't detect this kind of code?

> 
> > 
> > --
> > /Horatiu
> 
> --
> Radu P.

-- 
/Horatiu

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 06/14] net: phy: add 1000baseT1 to phy_basic_t1_features
  2023-06-16 20:49   ` Andrew Lunn
@ 2023-06-19 11:01     ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-19 11:01 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat



On 16.06.2023 23:49, Andrew Lunn wrote:
> Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
> 
> 
> On Fri, Jun 16, 2023 at 04:53:15PM +0300, Radu Pirea (NXP OSS) wrote:
>> Add 1000baseT1 bit to phy_basic_t1_features.
> 
> Please add an explanation why this is safe. For example, why the
> RTL9000AA does not start saying it supports 1000BaseT1_Full.

I added 1000BaseT1_Full to that array because all the baseT1 features 
are in the same array. However this is not looking right to me. For 
example, the output of ethtool for TJA1120 looks like this:
[root@alarm ~]# ethtool end0
Settings for end0:
         Supported ports: [ TP ]
         Supported link modes:   100baseT1/Full
                                 1000baseT1/Full
                                 10baseT1L/Full
         Supported pause frame use: Symmetric
         Supports auto-negotiation: No
         Supported FEC modes: Not reported
         Advertised link modes:  100baseT1/Full
                                 1000baseT1/Full
                                 10baseT1L/Full
         Advertised pause frame use: Symmetric
         Advertised auto-negotiation: No
         Advertised FEC modes: Not reported
         Speed: 100Mb/s
         Duplex: Full
         Auto-negotiation: off
         master-slave cfg: forced master
         master-slave status: master
         Port: Twisted Pair
         PHYAD: 1
         Transceiver: external
         MDI-X: Unknown
         Supports Wake-on: g
         Wake-on: d

Which is wrong. TJA1120 does not support 10baseT1L nor 100baseT1.
We should have a phylib function that determines the features for T1 PHYs.

> 
> Has 1000BaseT1_Full been standardised? If there a feature bit in a
> register to indicate the hardware supports it? That would be the
> preferred method to determine what the hardware can do.

Yes, it was standardized in IEEE802.3bp and there are bits in the MMD 1 
that tells you if the PHY supports 1000BaseT1. And here I am talking
about BASE_T1_PMA_XTD_ABILITY(0x12).1.

> 
>          Andrew

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120
  2023-06-19 10:48       ` Horatiu Vultur
@ 2023-06-20 14:31         ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-20 14:31 UTC (permalink / raw)
  To: Horatiu Vultur
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	richardcochran, netdev, linux-kernel, sebastian.tobuschat



On 19.06.2023 13:48, Horatiu Vultur wrote:
> Caution: This is an external email. Please take care when clicking links or opening attachments. When in doubt, report the message using the 'Report this email' button
> 
> 
> The 06/19/2023 13:07, Radu Pirea (OSS) wrote:
>>
>> On 19.06.2023 11:49, Horatiu Vultur wrote:
>>> The data->get_extts can't be null. So I don't think you need this check.
>>
>> I kinda agree with this because _I wrote the driver and I know what it
>> does_, but on the other hand don't want to fight with any static analyzer.
> 
> Yes, but then wouldn't be an issue with the static analyzer tools that
> can't detect this kind of code?

You are right. I will remove the checks. They are useless in the end. A 
check of private data will be introduced only if a future PHY needs it.

Thank you.

> 
>>
>>>
>>> --
>>> /Horatiu
>>
>> --
>> Radu P.
> 
> --
> /Horatiu

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH net-next v1 03/14] net: phy: nxp-c45-tja11xx: remove RX BIST frame counters
  2023-06-16 20:39   ` Andrew Lunn
@ 2023-06-22 12:21     ` Radu Pirea (OSS)
  0 siblings, 0 replies; 37+ messages in thread
From: Radu Pirea (OSS) @ 2023-06-22 12:21 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: hkallweit1, linux, davem, edumazet, kuba, pabeni, richardcochran,
	netdev, linux-kernel, sebastian.tobuschat

On 16.06.2023 23:39, Andrew Lunn wrote:
> On Fri, Jun 16, 2023 at 04:53:12PM +0300, Radu Pirea (NXP OSS) wrote:
>> RX BIST frame counters can be used only when the PHY is in test mode. In
>> production mode, the counters will be always read as 0. So, they don't
>> provide any useful information and are removed from the statistics.
> 
> Hummm
> 
> I wounder if this would be considered an ABI change?
> 
>          Andrew

It can be considered an ABI change, but will not break the userspace 
compilation. A functional change will be introduced anyway because these 
counters will not be reported, but they don't provide useful 
information. These counters will always be 0. In the worst-case 
scenario, we can add them back.

-- 
Radu P.

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2023-06-22 12:21 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-16 13:53 [PATCH net-next v1 00/14] Add TJA1120 support Radu Pirea (NXP OSS)
2023-06-16 13:53 ` [PATCH net-next v1 01/14] net: phy: nxp-c45-tja11xx: fix the PTP interrupt enablig/disabling Radu Pirea (NXP OSS)
2023-06-16 20:36   ` Andrew Lunn
2023-06-19  8:42     ` Radu Pirea (OSS)
2023-06-16 13:53 ` [PATCH net-next v1 02/14] net: phy: nxp-c45-tja11xx: use phylib master/slave implementation Radu Pirea (NXP OSS)
2023-06-16 20:37   ` Andrew Lunn
2023-06-16 13:53 ` [PATCH net-next v1 03/14] net: phy: nxp-c45-tja11xx: remove RX BIST frame counters Radu Pirea (NXP OSS)
2023-06-16 20:39   ` Andrew Lunn
2023-06-22 12:21     ` Radu Pirea (OSS)
2023-06-16 13:53 ` [PATCH net-next v1 04/14] net: phy: nxp-c45-tja11xx: add *_reg_field functions Radu Pirea (NXP OSS)
2023-06-16 20:42   ` Andrew Lunn
2023-06-16 13:53 ` [PATCH net-next v1 05/14] net: phy: nxp-c45-tja11xx: prepare the ground for TJA1120 Radu Pirea (NXP OSS)
2023-06-16 19:35   ` Simon Horman
2023-06-19  7:53   ` Horatiu Vultur
2023-06-16 13:53 ` [PATCH net-next v1 06/14] net: phy: add 1000baseT1 to phy_basic_t1_features Radu Pirea (NXP OSS)
2023-06-16 20:49   ` Andrew Lunn
2023-06-19 11:01     ` Radu Pirea (OSS)
2023-06-16 13:53 ` [PATCH net-next v1 07/14] net: phy: nxp-c45-tja11xx: add TJA1120 support Radu Pirea (NXP OSS)
2023-06-16 13:53 ` [PATCH net-next v1 08/14] net: phy: nxp-c45-tja11xx: enable LTC sampling on both ext_ts edges Radu Pirea (NXP OSS)
2023-06-19  8:10   ` Horatiu Vultur
2023-06-19  8:36     ` Radu Pirea (OSS)
2023-06-16 13:53 ` [PATCH net-next v1 09/14] net: phy: nxp-c45-tja11xx: read egress ts on TJA1120 Radu Pirea (NXP OSS)
2023-06-16 13:53 ` [PATCH net-next v1 10/14] net: phy: nxp-c45-tja11xx: handle FUSA irq Radu Pirea (NXP OSS)
2023-06-16 20:55   ` Andrew Lunn
2023-06-19  6:31     ` Radu Pirea (OSS)
2023-06-16 13:53 ` [PATCH net-next v1 11/14] net: phy: nxp-c45-tja11xx: run cable test with the PHY in test mode Radu Pirea (NXP OSS)
2023-06-16 13:53 ` [PATCH net-next v1 12/14] net: phy: nxp-c45-tja11xx: read ext trig ts TJA1120 Radu Pirea (NXP OSS)
2023-06-19  8:49   ` Horatiu Vultur
2023-06-19 10:07     ` Radu Pirea (OSS)
2023-06-19 10:48       ` Horatiu Vultur
2023-06-20 14:31         ` Radu Pirea (OSS)
2023-06-16 13:53 ` [PATCH net-next v1 13/14] net: phy: nxp-c45-tja11xx: reset PCS if the link goes down Radu Pirea (NXP OSS)
2023-06-16 21:00   ` Andrew Lunn
2023-06-19  6:17     ` Radu Pirea (OSS)
2023-06-16 13:53 ` [PATCH net-next v1 14/14] net: phy: nxp-c45-tja11xx: timestamp reading workaround for TJA1120 Radu Pirea (NXP OSS)
2023-06-19  8:58   ` Horatiu Vultur
2023-06-19  9:46     ` Radu Pirea (OSS)

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.