#define PHY_ID_LAN867X_REVB1 0x0007C162 #define PHY_ID_LAN867X_REVC1 0x0007C164 #define PHY_ID_LAN867X_REVC2 0x0007C165 /* Both Rev.B0 and B1 clause 22 PHYID's are same due to B1 chip limitation */ #define PHY_ID_LAN865X_REVB 0x0007C1B3
/* The arrays below are pulled from the following table from AN1699 *AccessMMDAddressValueMask *RMW0x1F0x00D00x00020x0E03 *RMW0x1F0x00D10x00000x0300 *RMW0x1F0x00840x33800xFFC0 *RMW0x1F0x00850x00060x000F *RMW0x1F0x008A0xC0000xF800 *RMW0x1F0x00870x801C0x801C *RMW0x1F0x00880x033F0x1FFF *W0x1F0x008B0x0404------ *RMW0x1F0x00800x06000x0600 *RMW0x1F0x00F10x24000x7F00 *RMW0x1F0x00960x20000x2000 *W0x1F0x00990x7F80------
*/
/* This is pulled straight from AN1760 from 'calculation of offset 1' & *'calculationofoffset2'
*/ staticint lan865x_generate_cfg_offsets(struct phy_device *phydev, s8 offsets[])
{ const u16 fixup_regs[2] = {0x0004, 0x0008}; int ret;
for (int i = 0; i < ARRAY_SIZE(fixup_regs); i++) {
ret = lan865x_revb_indirect_read(phydev, fixup_regs[i]); if (ret < 0) return ret;
/* 5-bit signed value, sign extend */
ret &= GENMASK(4, 0); if (ret & BIT(4))
offsets[i] = ret | 0xE0; else
offsets[i] = ret;
}
staticint lan865x_revb_config_init(struct phy_device *phydev)
{
s8 offsets[2]; int ret;
/* Reference to AN1760 *https://ww1.microchip.com/downloads/aemDocuments/documents/AIS/ProductDocuments/SupportingCollateral/AN-LAN8650-1-Configuration-60001760.pdf
*/
ret = lan865x_generate_cfg_offsets(phydev, offsets); if (ret) return ret;
for (int i = 0; i < ARRAY_SIZE(lan865x_revb_fixup_registers); i++) {
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
lan865x_revb_fixup_registers[i],
lan865x_revb_fixup_values[i]); if (ret) return ret;
if (i == 1) {
ret = lan865x_setup_cfgparam(phydev, offsets); if (ret) return ret;
}
}
ret = lan865x_setup_sqi_cfgparam(phydev, offsets); if (ret) return ret;
for (int i = 0; i < ARRAY_SIZE(lan865x_revb_sqi_fixup_regs); i++) {
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
lan865x_revb_sqi_fixup_regs[i],
lan865x_revb_sqi_fixup_values[i]); if (ret) return ret;
}
return0;
}
staticint lan867x_check_reset_complete(struct phy_device *phydev)
{ int err;
/* The chip completes a reset in 3us, we might get here earlier than *that,asanaddedmarginwe'llconditionallysleep5us.
*/
err = phy_read_mmd(phydev, MDIO_MMD_VEND2, LAN867X_REG_STS2); if (err < 0) return err;
if (!(err & LAN867x_RESET_COMPLETE_STS)) {
udelay(5);
err = phy_read_mmd(phydev, MDIO_MMD_VEND2, LAN867X_REG_STS2); if (err < 0) return err; if (!(err & LAN867x_RESET_COMPLETE_STS)) {
phydev_err(phydev, "PHY reset failed\n"); return -ENODEV;
}
}
return0;
}
staticint lan867x_revc_config_init(struct phy_device *phydev)
{
s8 offsets[2]; int ret;
ret = lan867x_check_reset_complete(phydev); if (ret) return ret;
ret = lan865x_generate_cfg_offsets(phydev, offsets); if (ret) return ret;
/* LAN867x Rev.C1/C2 configuration settings are equal to the first 9 *configurationsettingsandallthesqifixupsettingsfromLAN865x *Rev.B0/B1.SothesamefixupregistersandvaluesfromLAN865x *Rev.B0/B1areusedforLAN867xRev.C1/C2toavoidduplication. *Referthebelowlinksforthecomparison. *https://www.microchip.com/en-us/application-notes/an1760 *RevisionF(DS60001760G-June2024) *https://www.microchip.com/en-us/application-notes/an1699 *RevisionE(DS60001699F-June2024)
*/ for (int i = 0; i < 9; i++) {
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
lan865x_revb_fixup_registers[i],
lan865x_revb_fixup_values[i]); if (ret) return ret;
if (i == 1) {
ret = lan865x_setup_cfgparam(phydev, offsets); if (ret) return ret;
}
}
ret = lan865x_setup_sqi_cfgparam(phydev, offsets); if (ret) return ret;
for (int i = 0; i < ARRAY_SIZE(lan865x_revb_sqi_fixup_regs); i++) {
ret = phy_write_mmd(phydev, MDIO_MMD_VEND2,
lan865x_revb_sqi_fixup_regs[i],
lan865x_revb_sqi_fixup_values[i]); if (ret) return ret;
}
return0;
}
staticint lan867x_revb1_config_init(struct phy_device *phydev)
{ int err;
err = lan867x_check_reset_complete(phydev); if (err) return err;
/* Reference to AN1699 *https://ww1.microchip.com/downloads/aemDocuments/documents/AIS/ProductDocuments/SupportingCollateral/AN-LAN8670-1-2-config-60001699.pdf *AN1699saysRead,Modify,Write,buttheWriteisnotrequiredifthe *registeralreadyhastherequiredvalue.Soitissafetouse *phy_modify_mmdhere.
*/ for (int i = 0; i < ARRAY_SIZE(lan867x_revb1_fixup_registers); i++) {
err = phy_modify_mmd(phydev, MDIO_MMD_VEND2,
lan867x_revb1_fixup_registers[i],
lan867x_revb1_fixup_masks[i],
lan867x_revb1_fixup_values[i]); if (err) return err;
}
return0;
}
/* As per LAN8650/1 Rev.B0/B1 AN1760 (Revision F (DS60001760G - June 2024)) and *LAN8670/1/2Rev.C1/C2AN1699(RevisionE(DS60001699F-June2024)),under *normaloperation,thedeviceshouldbeoperatedinPLCAmode.Disabling *collisiondetectionisrecommendedtoallowthedevicetooperateinnoisy *environmentsorwhenreflectionsandotherinherenttransmissionline *distortioncausepoorsignalquality.Collisiondetectionmustbere-enabled *ifthedeviceisconfiguredtooperateinCSMA/CDmode. * *AN1760:https://www.microchip.com/en-us/application-notes/an1760 *AN1699:https://www.microchip.com/en-us/application-notes/an1699
*/ staticint lan86xx_plca_set_cfg(struct phy_device *phydev, conststruct phy_plca_cfg *plca_cfg)
{ int ret;
ret = genphy_c45_plca_set_cfg(phydev, plca_cfg); if (ret) return ret;
if (plca_cfg->enabled) return phy_modify_mmd(phydev, MDIO_MMD_VEND2,
LAN86XX_REG_COL_DET_CTRL0,
COL_DET_CTRL0_ENABLE_BIT_MASK,
COL_DET_DISABLE);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.