diff mbox series

[1/1] net: phy: microchip_t1s: enable lan865x revb1

Message ID 20240524140706.359537-2-ramon.nordin.rodriguez@ferroamp.se (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series phy: microchip_t1s: lan865x rev.b1 support | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present fail Series targets non-next tree, but doesn't contain any Fixes tags
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 45 this patch: 45
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 7 of 7 maintainers
netdev/build_clang fail Errors and warnings before: 36 this patch: 36
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 45 this patch: 45
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns WARNING: line length of 82 exceeds 80 columns WARNING: line length of 84 exceeds 80 columns WARNING: line length of 85 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 87 exceeds 80 columns WARNING: line length of 88 exceeds 80 columns WARNING: line length of 90 exceeds 80 columns WARNING: line length of 92 exceeds 80 columns
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Ramón Nordin Rodriguez May 24, 2024, 2:07 p.m. UTC
The microchip_t1s module is extended with support for lan865x rev.b1,
prior to this commit support for rev.b0 already exists.

Some of the operations performed in the hw probe and init of the phy
require access to registers only accessible via the macphy spi
interface (lan865x is an integrated phy), meaning the init call has
to interop with layers above, namely via read/write_c45.

Signed-off-by: Ramón Nordin Rodriguez <ramon.nordin.rodriguez@ferroamp.se>
---
 drivers/net/phy/microchip_t1s.c | 189 ++++++++++++++++++++++++++++----
 1 file changed, 166 insertions(+), 23 deletions(-)

Comments

Russell King (Oracle) May 24, 2024, 3:11 p.m. UTC | #1
On Fri, May 24, 2024 at 04:07:06PM +0200, Ramón Nordin Rodriguez wrote:
> +/* this func is copy pasted from Parthibans ongoing work with oa_tc6
> + * see https://lore.kernel.org/netdev/20240418125648.372526-7-Parthiban.Veerasooran@microchip.com/
> + */

Oh dear...

> +static int lan865x_phy_read_mmd(struct phy_device *phydev, int devnum,
> +				u16 regnum)
> +{
> +	struct mii_bus *bus = phydev->mdio.bus;
> +	int addr = phydev->mdio.addr;
> +
> +	return bus->read_c45(bus, addr, devnum, regnum);
> +}
> +
> +/* this func is copy pasted from Parthibans ongoing work with oa_tc6
> + * see https://lore.kernel.org/netdev/20240418125648.372526-7-Parthiban.Veerasooran@microchip.com/
> + */
> +static int lan865x_phy_write_mmd(struct phy_device *phydev, int devnum,
> +				 u16 regnum, u16 val)
> +{
> +	struct mii_bus *bus = phydev->mdio.bus;
> +	int addr = phydev->mdio.addr;
> +
> +	return bus->write_c45(bus, addr, devnum, regnum, val);
> +}

So you need both of these to (dangerously) read and write the C45
address using a devnum with bit 31 set. Please at the very least
take the MDIO bus lock so the locking of these operations remains
consistent.

I'm not sure that abusing the interface by setting bit 31 in the
device address, which is supposed to be between 0 and 31 is
something we're prepared to entertain.
Sai Krishna Gajula May 27, 2024, 5:37 a.m. UTC | #2
> -----Original Message-----
> From: Ramón Nordin Rodriguez <ramon.nordin.rodriguez@ferroamp.se>
> Sent: Friday, May 24, 2024 7:37 PM
> To: andrew@lunn.ch; hkallweit1@gmail.com; linux@armlinux.org.uk;
> davem@davemloft.net; edumazet@google.com; kuba@kernel.org;
> pabeni@redhat.com; netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Cc: parthiban.veerasooran@microchip.com; Ramón Nordin Rodriguez
> <ramon.nordin.rodriguez@ferroamp.se>
> Subject: [EXTERNAL] [PATCH 1/1] net: phy: microchip_t1s: enable lan865x
> revb1
> 
> Prioritize security for external emails: Confirm sender and content safety
> before clicking links or opening attachments
> 
> ----------------------------------------------------------------------
> The microchip_t1s module is extended with support for lan865x rev.b1, prior
> to this commit support for rev.b0 already exists.
> 
> Some of the operations performed in the hw probe and init of the phy require
> access to registers only accessible via the macphy spi interface (lan865x is an
> integrated phy), meaning the init call has to interop with layers above, namely
> via read/write_c45.
> 
> Signed-off-by: Ramón Nordin Rodriguez
> <ramon.nordin.rodriguez@ferroamp.se>

Fixes tag is required if the patch is for NET tree. Also, it seems like build for 32 bit seems to be failing. Please check.

> ---
>  drivers/net/phy/microchip_t1s.c | 189 ++++++++++++++++++++++++++++-
> ---
>  1 file changed, 166 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/net/phy/microchip_t1s.c
> b/drivers/net/phy/microchip_t1s.c index 534ca7d1b061..3c5153aa5c7a
> 100644
> --- a/drivers/net/phy/microchip_t1s.c
> +++ b/drivers/net/phy/microchip_t1s.c
> @@ -5,6 +5,7 @@
>   * Support: Microchip Phys:
>   *  lan8670/1/2 Rev.B1
>   *  lan8650/1 Rev.B0 Internal PHYs
> + *  lan8650/1 Rev.B1 Internal PHYs
>   */
> 
>  #include <linux/kernel.h>
> @@ -12,7 +13,7 @@
>  #include <linux/phy.h>
> 
>  #define PHY_ID_LAN867X_REVB1 0x0007C162 -#define
> PHY_ID_LAN865X_REVB0 0x0007C1B3
> +#define PHY_ID_LAN865X 0x0007C1B3
> 
>  #define LAN867X_REG_STS2 0x0019
> 
> @@ -22,6 +23,7 @@
>  #define LAN865X_REG_CFGPARAM_DATA 0x00D9  #define
> LAN865X_REG_CFGPARAM_CTRL 0x00DA  #define LAN865X_REG_STS2
> 0x0019
> +#define LAN865X_REG_DEVID 0x94
> 
>  #define LAN865X_CFGPARAM_READ_ENABLE BIT(1)
> 
> @@ -84,6 +86,65 @@ static const u16 lan865x_revb0_fixup_cfg_regs[5] = {
>  	0x0084, 0x008A, 0x00AD, 0x00AE, 0x00AF  };
> 
> +enum lan865x_revision {
> +	REV_B0 = 0x1,
> +	REV_B1 = 0x2,
> +};
> +
> +struct lan865x_revb1_fixup_op {
> +	u16 mms;
> +	u16 addr;
> +	u16 value;
> +};
> +
> +static const struct lan865x_revb1_fixup_op lan865x_revb1_fixup_cfg[20]
> += {
> +	{.mms = 4, .addr = 0x00d0, .value = 0x3f31},
> +	{.mms = 4, .addr = 0x00e0, .value = 0xc000},
> +	{.mms = 4, .addr = 0x0084, .value = 0x0000},
> +	{.mms = 4, .addr = 0x008a, .value = 0x0000},
> +	{.mms = 4, .addr = 0x00e9, .value = 0x9e50},
> +	{.mms = 4, .addr = 0x00f5, .value = 0x1cf8},
> +	{.mms = 4, .addr = 0x00f4, .value = 0xc020},
> +	{.mms = 4, .addr = 0x00f8, .value = 0x9b00},
> +	{.mms = 4, .addr = 0x00f9, .value = 0x4e53},
> +	{.mms = 4, .addr = 0x0081, .value = 0x0080},
> +	{.mms = 4, .addr = 0x0091, .value = 0x9660},
> +	{.mms = 1, .addr = 0x0077, .value = 0x0028},
> +	{.mms = 4, .addr = 0x0043, .value = 0x00ff},
> +	{.mms = 4, .addr = 0x0044, .value = 0xffff},
> +	{.mms = 4, .addr = 0x0045, .value = 0x0000},
> +	{.mms = 4, .addr = 0x0053, .value = 0x00ff},
> +	{.mms = 4, .addr = 0x0054, .value = 0xffff},
> +	{.mms = 4, .addr = 0x0055, .value = 0x0000},
> +	{.mms = 4, .addr = 0x0040, .value = 0x0002},
> +	{.mms = 4, .addr = 0x0050, .value = 0x0002} };
> +
> +/* this func is copy pasted from Parthibans ongoing work with oa_tc6
> + * see
> +https://urldefense.proofpoint.com/v2/url?u=https-3A__lore.kernel.org_ne
> +tdev_20240418125648.372526-2D7-2DParthiban.Veerasooran-
> 40microchip.com_
> +&d=DwIDaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=c3MsgrR-U-
> HFhmFd6R4MWRZG-8QeikJn5P
> +kjqMTpBSg&m=XjkUpKCoT2lM06i5fF3KdqFf-notCV0B-
> LT0mcLVMbPDQ29Vs7R3Ek2zHA7
> +0BlwP&s=rNsk2zP8m89VjgtwQo3jL-STsPKU5S7Ig8TGr0IsZTY&e=
> + */
> +static int lan865x_phy_read_mmd(struct phy_device *phydev, int devnum,
> +				u16 regnum)
> +{
> +	struct mii_bus *bus = phydev->mdio.bus;
> +	int addr = phydev->mdio.addr;
> +
> +	return bus->read_c45(bus, addr, devnum, regnum); }
> +
> +/* this func is copy pasted from Parthibans ongoing work with oa_tc6
> + * see
> +https://urldefense.proofpoint.com/v2/url?u=https-3A__lore.kernel.org_ne
> +tdev_20240418125648.372526-2D7-2DParthiban.Veerasooran-
> 40microchip.com_
> +&d=DwIDaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=c3MsgrR-U-
> HFhmFd6R4MWRZG-8QeikJn5P
> +kjqMTpBSg&m=XjkUpKCoT2lM06i5fF3KdqFf-notCV0B-
> LT0mcLVMbPDQ29Vs7R3Ek2zHA7
> +0BlwP&s=rNsk2zP8m89VjgtwQo3jL-STsPKU5S7Ig8TGr0IsZTY&e=
> + */
> +static int lan865x_phy_write_mmd(struct phy_device *phydev, int devnum,
> +				 u16 regnum, u16 val)
> +{
> +	struct mii_bus *bus = phydev->mdio.bus;
> +	int addr = phydev->mdio.addr;
> +
> +	return bus->write_c45(bus, addr, devnum, regnum, val); }
> +
>  /* Pulled from AN1760 describing 'indirect read'
>   *
>   * write_register(0x4, 0x00D8, addr)
> @@ -112,7 +173,7 @@ static int lan865x_revb0_indirect_read(struct
> phy_device *phydev, u16 addr)
>  /* This is pulled straight from AN1760 from 'calculation of offset 1' &
>   * 'calculation of offset 2'
>   */
> -static int lan865x_generate_cfg_offsets(struct phy_device *phydev, s8
> offsets[2])
> +static int lan865x_revb0_generate_cfg_offsets(struct phy_device
> +*phydev, s8 offsets[2])
>  {
>  	const u16 fixup_regs[2] = {0x0004, 0x0008};
>  	int ret;
> @@ -130,7 +191,41 @@ static int lan865x_generate_cfg_offsets(struct
> phy_device *phydev, s8 offsets[2]
>  	return 0;
>  }
> 
> -static int lan865x_read_cfg_params(struct phy_device *phydev, u16
> cfg_params[])
> +static int lan865x_revb1_gen_cfgparams(struct phy_device *phydev, u16
> +params[2]) {
> +	const u16 fixup_regs[2] = {0x0004, 0x0008};
> +	int ret;
> +
> +	// this loop attempts to de-weirdify the method described in AN1760
> +	for (int i = 0; i < ARRAY_SIZE(fixup_regs); i++) {
> +		// only the lower 8 bits of the results here are used
> +		ret = lan865x_revb0_indirect_read(phydev, fixup_regs[i]);
> +		if (ret < 0)
> +			return ret;
> +		// The AN states that the readback value is in the range [-5,
> 15]
> +		// and that it uses 5 bits, bit wonky of a description, it really
> only
> +		// makes sense if the read is sign extended.
> +		// Since the regs are part of the reserved range there is no way
> +		// of telling how this really works though.
> +		if (ret & BIT(4))
> +			// The AN specifies 'ret - 0x20' which is again pretty
> weird
> +			// the addition here gives the same result on a s8
> (with overflow)
> +			// the assignment here are downcasting to s8 for sign
> extension
> +			params[i] = (s8)(ret + 0xE0);
> +		else
> +			params[i] = (s8)ret;
> +	}
> +
> +	// And now for the really weird part, there's no explanation to what
> any of this
> +	// means, just that we need these results written to magic regs.
> +	// Since these ops shift a lot, the previous sign extension is probably
> meaningless.
> +	params[0] = (((params[0] + 9) & 0x3F) << 10) | ((params[0] + 14) &
> 0x3f) << 4 | 0x3;
> +	params[1] = ((params[1] + 40) & 0x3F) << 10;
> +
> +	return 0;
> +}
> +
> +static int lan865x_revb0_read_cfg_params(struct phy_device *phydev, u16
> +cfg_params[])
>  {
>  	int ret;
> 
> @@ -145,7 +240,7 @@ static int lan865x_read_cfg_params(struct
> phy_device *phydev, u16 cfg_params[])
>  	return 0;
>  }
> 
> -static int lan865x_write_cfg_params(struct phy_device *phydev, u16
> cfg_params[])
> +static int lan865x_revb0_write_cfg_params(struct phy_device *phydev,
> +u16 cfg_params[])
>  {
>  	int ret;
> 
> @@ -160,18 +255,29 @@ static int lan865x_write_cfg_params(struct
> phy_device *phydev, u16 cfg_params[])
>  	return 0;
>  }
> 
> -static int lan865x_setup_cfgparam(struct phy_device *phydev)
> +static int lan865x_revb0_setup_cfgparam(struct phy_device *phydev)
>  {
>  	u16 cfg_params[ARRAY_SIZE(lan865x_revb0_fixup_cfg_regs)];
>  	u16 cfg_results[5];
>  	s8 offsets[2];
>  	int ret;
> 
> -	ret = lan865x_generate_cfg_offsets(phydev, offsets);
> +	/* Reference to AN1760
> +	 * https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__ww1.microchip.com_downloads_aemDocuments_documents_AIS_Prod
> uctDocuments_SupportingCollateral_AN-2DLAN8650-2D1-2DConfiguration-
> 2D60001760.pdf&d=DwIDaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=c3MsgrR-U-
> HFhmFd6R4MWRZG-8QeikJn5PkjqMTpBSg&m=XjkUpKCoT2lM06i5fF3KdqFf-
> notCV0B-
> LT0mcLVMbPDQ29Vs7R3Ek2zHA70BlwP&s=9lbQcePQzdtdyNZYMB_GAniwOj
> qhUp3KA0VBMaGmi6M&e=
> +	 */
> +	for (int i = 0; i < ARRAY_SIZE(lan865x_revb0_fixup_registers); i++) {
> +		ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
> +				    lan865x_revb0_fixup_registers[i],
> +				    lan865x_revb0_fixup_values[i]);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	ret = lan865x_revb0_generate_cfg_offsets(phydev, offsets);
>  	if (ret)
>  		return ret;
> 
> -	ret = lan865x_read_cfg_params(phydev, cfg_params);
> +	ret = lan865x_revb0_read_cfg_params(phydev, cfg_params);
>  	if (ret)
>  		return ret;
> 
> @@ -190,27 +296,64 @@ static int lan865x_setup_cfgparam(struct
> phy_device *phydev)
>  			  FIELD_PREP(GENMASK(15, 8), 17 + offsets[0]) |
>  			  (22 + offsets[0]);
> 
> -	return lan865x_write_cfg_params(phydev, cfg_results);
> +	return lan865x_revb0_write_cfg_params(phydev, cfg_results);
>  }
> 
> -static int lan865x_revb0_config_init(struct phy_device *phydev)
> +static int lan865x_revb1_setup_cfgparam(struct phy_device *phydev)
>  {
> +	const struct lan865x_revb1_fixup_op *op;
> +	u16 generated_params[2];
> +	u16 fixup_val;
>  	int ret;
> 
> -	/* Reference to AN1760
> -	 * https://urldefense.proofpoint.com/v2/url?u=https-
> 3A__ww1.microchip.com_downloads_aemDocuments_documents_AIS_Prod
> uctDocuments_SupportingCollateral_AN-2DLAN8650-2D1-2DConfiguration-
> 2D60001760.pdf&d=DwIDaQ&c=nKjWec2b6R0mOyPaz7xtfQ&r=c3MsgrR-U-
> HFhmFd6R4MWRZG-8QeikJn5PkjqMTpBSg&m=XjkUpKCoT2lM06i5fF3KdqFf-
> notCV0B-
> LT0mcLVMbPDQ29Vs7R3Ek2zHA70BlwP&s=9lbQcePQzdtdyNZYMB_GAniwOj
> qhUp3KA0VBMaGmi6M&e=
> -	 */
> -	for (int i = 0; i < ARRAY_SIZE(lan865x_revb0_fixup_registers); i++) {
> -		ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
> -				    lan865x_revb0_fixup_registers[i],
> -				    lan865x_revb0_fixup_values[i]);
> +	ret = lan865x_revb1_gen_cfgparams(phydev, generated_params);
> +	if (ret)
> +		return ret;
> +
> +	for (int i = 0; i < ARRAY_SIZE(lan865x_revb1_fixup_cfg); i++) {
> +		op = &lan865x_revb1_fixup_cfg[i];
> +		fixup_val = op->value;
> +		if (i == 2)
> +			fixup_val = generated_params[0];
> +		else if (i == 3)
> +			fixup_val = generated_params[1];
> +		/* All of the regs locatd in mms 4 could use phy_write_mmd
> as these are
> +		 * accessible via MDIO_MMD_VEND2, but mms 1 not 'indirect
> accessible'.
> +		 * Less conditionals are favored here by doing the set in just
> one way.
> +		 */
> +		ret = lan865x_phy_write_mmd(phydev, op->mms | BIT(31),
> op->addr,
> +fixup_val);
>  		if (ret)
>  			return ret;
>  	}
> -	/* Function to calculate and write the configuration parameters in the
> -	 * 0x0084, 0x008A, 0x00AD, 0x00AE and 0x00AF registers (from
> AN1760)
> +	return 0;
> +}
> +
> +static int lan865x_config_init(struct phy_device *phydev) {
> +	u32 rev_mask = GENMASK(1, 0);
> +	enum lan865x_revision rev;
> +	u32 mms10 = 10;
> +	u32 devid;
> +
> +	/* The standard reg OA_PHYID (mms 0, addr 0x1) does not contain
> any
> +	 * information that distinguishes hardware revisions.
> +	 * HW rev can be read from the vendor specific DEVID reg mms 10,
> addr
> +0x94
>  	 */
> -	return lan865x_setup_cfgparam(phydev);
> +	devid = lan865x_phy_read_mmd(phydev, mms10 | BIT(31),
> +LAN865X_REG_DEVID);
> +
> +	if (devid < 0)
> +		return devid;
> +
> +	rev = devid & rev_mask;
> +	switch (rev) {
> +	case REV_B0:
> +		return lan865x_revb0_setup_cfgparam(phydev);
> +	case REV_B1:
> +		return lan865x_revb1_setup_cfgparam(phydev);
> +	}
> +
> +	dev_err(&phydev->mdio.dev, "unsupported chip rev: 0x%x", rev);
> +	return -ENODEV;
>  }
> 
>  static int lan867x_revb1_config_init(struct phy_device *phydev) @@ -280,10
> +423,10 @@ static struct phy_driver microchip_t1s_driver[] = {
>  		.get_plca_status    = genphy_c45_plca_get_status,
>  	},
>  	{
> -		PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB0),
> -		.name               = "LAN865X Rev.B0 Internal Phy",
> +		PHY_ID_MATCH_EXACT(PHY_ID_LAN865X),
> +		.name               = "LAN865X Rev.B0/1 Internal Phy",
>  		.features           = PHY_BASIC_T1S_P2MP_FEATURES,
> -		.config_init        = lan865x_revb0_config_init,
> +		.config_init        = lan865x_config_init,
>  		.read_status        = lan86xx_read_status,
>  		.get_plca_cfg	    = genphy_c45_plca_get_cfg,
>  		.set_plca_cfg	    = genphy_c45_plca_set_cfg,
> @@ -295,7 +438,7 @@ module_phy_driver(microchip_t1s_driver);
> 
>  static struct mdio_device_id __maybe_unused tbl[] = {
>  	{ PHY_ID_MATCH_EXACT(PHY_ID_LAN867X_REVB1) },
> -	{ PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB0) },
> +	{ PHY_ID_MATCH_EXACT(PHY_ID_LAN865X) },
>  	{ }
>  };
> 
> --
> 2.43.0
>
diff mbox series

Patch

diff --git a/drivers/net/phy/microchip_t1s.c b/drivers/net/phy/microchip_t1s.c
index 534ca7d1b061..3c5153aa5c7a 100644
--- a/drivers/net/phy/microchip_t1s.c
+++ b/drivers/net/phy/microchip_t1s.c
@@ -5,6 +5,7 @@ 
  * Support: Microchip Phys:
  *  lan8670/1/2 Rev.B1
  *  lan8650/1 Rev.B0 Internal PHYs
+ *  lan8650/1 Rev.B1 Internal PHYs
  */
 
 #include <linux/kernel.h>
@@ -12,7 +13,7 @@ 
 #include <linux/phy.h>
 
 #define PHY_ID_LAN867X_REVB1 0x0007C162
-#define PHY_ID_LAN865X_REVB0 0x0007C1B3
+#define PHY_ID_LAN865X 0x0007C1B3
 
 #define LAN867X_REG_STS2 0x0019
 
@@ -22,6 +23,7 @@ 
 #define LAN865X_REG_CFGPARAM_DATA 0x00D9
 #define LAN865X_REG_CFGPARAM_CTRL 0x00DA
 #define LAN865X_REG_STS2 0x0019
+#define LAN865X_REG_DEVID 0x94
 
 #define LAN865X_CFGPARAM_READ_ENABLE BIT(1)
 
@@ -84,6 +86,65 @@  static const u16 lan865x_revb0_fixup_cfg_regs[5] = {
 	0x0084, 0x008A, 0x00AD, 0x00AE, 0x00AF
 };
 
+enum lan865x_revision {
+	REV_B0 = 0x1,
+	REV_B1 = 0x2,
+};
+
+struct lan865x_revb1_fixup_op {
+	u16 mms;
+	u16 addr;
+	u16 value;
+};
+
+static const struct lan865x_revb1_fixup_op
+lan865x_revb1_fixup_cfg[20] = {
+	{.mms = 4, .addr = 0x00d0, .value = 0x3f31},
+	{.mms = 4, .addr = 0x00e0, .value = 0xc000},
+	{.mms = 4, .addr = 0x0084, .value = 0x0000},
+	{.mms = 4, .addr = 0x008a, .value = 0x0000},
+	{.mms = 4, .addr = 0x00e9, .value = 0x9e50},
+	{.mms = 4, .addr = 0x00f5, .value = 0x1cf8},
+	{.mms = 4, .addr = 0x00f4, .value = 0xc020},
+	{.mms = 4, .addr = 0x00f8, .value = 0x9b00},
+	{.mms = 4, .addr = 0x00f9, .value = 0x4e53},
+	{.mms = 4, .addr = 0x0081, .value = 0x0080},
+	{.mms = 4, .addr = 0x0091, .value = 0x9660},
+	{.mms = 1, .addr = 0x0077, .value = 0x0028},
+	{.mms = 4, .addr = 0x0043, .value = 0x00ff},
+	{.mms = 4, .addr = 0x0044, .value = 0xffff},
+	{.mms = 4, .addr = 0x0045, .value = 0x0000},
+	{.mms = 4, .addr = 0x0053, .value = 0x00ff},
+	{.mms = 4, .addr = 0x0054, .value = 0xffff},
+	{.mms = 4, .addr = 0x0055, .value = 0x0000},
+	{.mms = 4, .addr = 0x0040, .value = 0x0002},
+	{.mms = 4, .addr = 0x0050, .value = 0x0002}
+};
+
+/* this func is copy pasted from Parthibans ongoing work with oa_tc6
+ * see https://lore.kernel.org/netdev/20240418125648.372526-7-Parthiban.Veerasooran@microchip.com/
+ */
+static int lan865x_phy_read_mmd(struct phy_device *phydev, int devnum,
+				u16 regnum)
+{
+	struct mii_bus *bus = phydev->mdio.bus;
+	int addr = phydev->mdio.addr;
+
+	return bus->read_c45(bus, addr, devnum, regnum);
+}
+
+/* this func is copy pasted from Parthibans ongoing work with oa_tc6
+ * see https://lore.kernel.org/netdev/20240418125648.372526-7-Parthiban.Veerasooran@microchip.com/
+ */
+static int lan865x_phy_write_mmd(struct phy_device *phydev, int devnum,
+				 u16 regnum, u16 val)
+{
+	struct mii_bus *bus = phydev->mdio.bus;
+	int addr = phydev->mdio.addr;
+
+	return bus->write_c45(bus, addr, devnum, regnum, val);
+}
+
 /* Pulled from AN1760 describing 'indirect read'
  *
  * write_register(0x4, 0x00D8, addr)
@@ -112,7 +173,7 @@  static int lan865x_revb0_indirect_read(struct phy_device *phydev, u16 addr)
 /* This is pulled straight from AN1760 from 'calculation of offset 1' &
  * 'calculation of offset 2'
  */
-static int lan865x_generate_cfg_offsets(struct phy_device *phydev, s8 offsets[2])
+static int lan865x_revb0_generate_cfg_offsets(struct phy_device *phydev, s8 offsets[2])
 {
 	const u16 fixup_regs[2] = {0x0004, 0x0008};
 	int ret;
@@ -130,7 +191,41 @@  static int lan865x_generate_cfg_offsets(struct phy_device *phydev, s8 offsets[2]
 	return 0;
 }
 
-static int lan865x_read_cfg_params(struct phy_device *phydev, u16 cfg_params[])
+static int lan865x_revb1_gen_cfgparams(struct phy_device *phydev, u16 params[2])
+{
+	const u16 fixup_regs[2] = {0x0004, 0x0008};
+	int ret;
+
+	// this loop attempts to de-weirdify the method described in AN1760
+	for (int i = 0; i < ARRAY_SIZE(fixup_regs); i++) {
+		// only the lower 8 bits of the results here are used
+		ret = lan865x_revb0_indirect_read(phydev, fixup_regs[i]);
+		if (ret < 0)
+			return ret;
+		// The AN states that the readback value is in the range [-5, 15]
+		// and that it uses 5 bits, bit wonky of a description, it really only
+		// makes sense if the read is sign extended.
+		// Since the regs are part of the reserved range there is no way
+		// of telling how this really works though.
+		if (ret & BIT(4))
+			// The AN specifies 'ret - 0x20' which is again pretty weird
+			// the addition here gives the same result on a s8 (with overflow)
+			// the assignment here are downcasting to s8 for sign extension
+			params[i] = (s8)(ret + 0xE0);
+		else
+			params[i] = (s8)ret;
+	}
+
+	// And now for the really weird part, there's no explanation to what any of this
+	// means, just that we need these results written to magic regs.
+	// Since these ops shift a lot, the previous sign extension is probably meaningless.
+	params[0] = (((params[0] + 9) & 0x3F) << 10) | ((params[0] + 14) & 0x3f) << 4 | 0x3;
+	params[1] = ((params[1] + 40) & 0x3F) << 10;
+
+	return 0;
+}
+
+static int lan865x_revb0_read_cfg_params(struct phy_device *phydev, u16 cfg_params[])
 {
 	int ret;
 
@@ -145,7 +240,7 @@  static int lan865x_read_cfg_params(struct phy_device *phydev, u16 cfg_params[])
 	return 0;
 }
 
-static int lan865x_write_cfg_params(struct phy_device *phydev, u16 cfg_params[])
+static int lan865x_revb0_write_cfg_params(struct phy_device *phydev, u16 cfg_params[])
 {
 	int ret;
 
@@ -160,18 +255,29 @@  static int lan865x_write_cfg_params(struct phy_device *phydev, u16 cfg_params[])
 	return 0;
 }
 
-static int lan865x_setup_cfgparam(struct phy_device *phydev)
+static int lan865x_revb0_setup_cfgparam(struct phy_device *phydev)
 {
 	u16 cfg_params[ARRAY_SIZE(lan865x_revb0_fixup_cfg_regs)];
 	u16 cfg_results[5];
 	s8 offsets[2];
 	int ret;
 
-	ret = lan865x_generate_cfg_offsets(phydev, offsets);
+	/* Reference to AN1760
+	 * https://ww1.microchip.com/downloads/aemDocuments/documents/AIS/ProductDocuments/SupportingCollateral/AN-LAN8650-1-Configuration-60001760.pdf
+	 */
+	for (int i = 0; i < ARRAY_SIZE(lan865x_revb0_fixup_registers); i++) {
+		ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
+				    lan865x_revb0_fixup_registers[i],
+				    lan865x_revb0_fixup_values[i]);
+		if (ret)
+			return ret;
+	}
+
+	ret = lan865x_revb0_generate_cfg_offsets(phydev, offsets);
 	if (ret)
 		return ret;
 
-	ret = lan865x_read_cfg_params(phydev, cfg_params);
+	ret = lan865x_revb0_read_cfg_params(phydev, cfg_params);
 	if (ret)
 		return ret;
 
@@ -190,27 +296,64 @@  static int lan865x_setup_cfgparam(struct phy_device *phydev)
 			  FIELD_PREP(GENMASK(15, 8), 17 + offsets[0]) |
 			  (22 + offsets[0]);
 
-	return lan865x_write_cfg_params(phydev, cfg_results);
+	return lan865x_revb0_write_cfg_params(phydev, cfg_results);
 }
 
-static int lan865x_revb0_config_init(struct phy_device *phydev)
+static int lan865x_revb1_setup_cfgparam(struct phy_device *phydev)
 {
+	const struct lan865x_revb1_fixup_op *op;
+	u16 generated_params[2];
+	u16 fixup_val;
 	int ret;
 
-	/* Reference to AN1760
-	 * https://ww1.microchip.com/downloads/aemDocuments/documents/AIS/ProductDocuments/SupportingCollateral/AN-LAN8650-1-Configuration-60001760.pdf
-	 */
-	for (int i = 0; i < ARRAY_SIZE(lan865x_revb0_fixup_registers); i++) {
-		ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
-				    lan865x_revb0_fixup_registers[i],
-				    lan865x_revb0_fixup_values[i]);
+	ret = lan865x_revb1_gen_cfgparams(phydev, generated_params);
+	if (ret)
+		return ret;
+
+	for (int i = 0; i < ARRAY_SIZE(lan865x_revb1_fixup_cfg); i++) {
+		op = &lan865x_revb1_fixup_cfg[i];
+		fixup_val = op->value;
+		if (i == 2)
+			fixup_val = generated_params[0];
+		else if (i == 3)
+			fixup_val = generated_params[1];
+		/* All of the regs locatd in mms 4 could use phy_write_mmd as these are
+		 * accessible via MDIO_MMD_VEND2, but mms 1 not 'indirect accessible'.
+		 * Less conditionals are favored here by doing the set in just one way.
+		 */
+		ret = lan865x_phy_write_mmd(phydev, op->mms | BIT(31), op->addr, fixup_val);
 		if (ret)
 			return ret;
 	}
-	/* Function to calculate and write the configuration parameters in the
-	 * 0x0084, 0x008A, 0x00AD, 0x00AE and 0x00AF registers (from AN1760)
+	return 0;
+}
+
+static int lan865x_config_init(struct phy_device *phydev)
+{
+	u32 rev_mask = GENMASK(1, 0);
+	enum lan865x_revision rev;
+	u32 mms10 = 10;
+	u32 devid;
+
+	/* The standard reg OA_PHYID (mms 0, addr 0x1) does not contain any
+	 * information that distinguishes hardware revisions.
+	 * HW rev can be read from the vendor specific DEVID reg mms 10, addr 0x94
 	 */
-	return lan865x_setup_cfgparam(phydev);
+	devid = lan865x_phy_read_mmd(phydev, mms10 | BIT(31), LAN865X_REG_DEVID);
+
+	if (devid < 0)
+		return devid;
+
+	rev = devid & rev_mask;
+	switch (rev) {
+	case REV_B0:
+		return lan865x_revb0_setup_cfgparam(phydev);
+	case REV_B1:
+		return lan865x_revb1_setup_cfgparam(phydev);
+	}
+
+	dev_err(&phydev->mdio.dev, "unsupported chip rev: 0x%x", rev);
+	return -ENODEV;
 }
 
 static int lan867x_revb1_config_init(struct phy_device *phydev)
@@ -280,10 +423,10 @@  static struct phy_driver microchip_t1s_driver[] = {
 		.get_plca_status    = genphy_c45_plca_get_status,
 	},
 	{
-		PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB0),
-		.name               = "LAN865X Rev.B0 Internal Phy",
+		PHY_ID_MATCH_EXACT(PHY_ID_LAN865X),
+		.name               = "LAN865X Rev.B0/1 Internal Phy",
 		.features           = PHY_BASIC_T1S_P2MP_FEATURES,
-		.config_init        = lan865x_revb0_config_init,
+		.config_init        = lan865x_config_init,
 		.read_status        = lan86xx_read_status,
 		.get_plca_cfg	    = genphy_c45_plca_get_cfg,
 		.set_plca_cfg	    = genphy_c45_plca_set_cfg,
@@ -295,7 +438,7 @@  module_phy_driver(microchip_t1s_driver);
 
 static struct mdio_device_id __maybe_unused tbl[] = {
 	{ PHY_ID_MATCH_EXACT(PHY_ID_LAN867X_REVB1) },
-	{ PHY_ID_MATCH_EXACT(PHY_ID_LAN865X_REVB0) },
+	{ PHY_ID_MATCH_EXACT(PHY_ID_LAN865X) },
 	{ }
 };