From c75e6931adbd669b757f8fb60243a0164bbd3d8f Mon Sep 17 00:00:00 2001 From: Jani Paalijarvi Date: Wed, 28 Aug 2024 08:55:37 +0300 Subject: [PATCH] drivers/net/ksz9477: Custom errata fixes Setup OLD configuration which seems to work --- drivers/net/ksz9477.c | 164 +++++++++++++++++++++++++++++++++++++- drivers/net/ksz9477_reg.h | 2 + 2 files changed, 164 insertions(+), 2 deletions(-) diff --git a/drivers/net/ksz9477.c b/drivers/net/ksz9477.c index 117feb3b9f236..4bc1a96944984 100644 --- a/drivers/net/ksz9477.c +++ b/drivers/net/ksz9477.c @@ -341,6 +341,166 @@ static int ksz9477_mmd_write_indirect(ksz9477_port_t port, uint8_t dev, return ret; } +#if 1 +static int ksz9477_custom_error_fixes(ksz9477_port_t port) +{ + int ret = OK; + int j; + uint16_t regval16; + struct errata err1[11]; + struct errata err2[4]; + struct errata err3[18]; + struct errata mod9[12]; + + /* First turn off autoneg */ + + ret = ksz9477_reg_write16(KSZ9477_PHY_CONTROL(port), 0x2100); + + if (ret != OK) + { + nerr("PHY Control register write failure, ret %d\n", ret); + return ret ? ret : -EINVAL; + } + + /* Set Remote Loopback register */ + + ret = ksz9477_reg_write16(KSZ9477_PHY_REMOTE_LP(port), 0x00F0); + if (ret != OK) + { + nerr("PHY Remote Loopback register write failure, ret %d\n", ret); + return ret ? ret : -EINVAL; + } + + /* Needed configurations for MMD Signal Quality */ + + err1[0].reg = 0xCE; + err1[0].value = 0x0100; + err1[1].reg = 0xCC; + err1[1].value = 0x0FF0; + err1[2].reg = 0xCA; + err1[2].value = 0x0141; + err1[3].reg = 0xCB; + err1[3].value = 0x0FCF; + err1[4].reg = 0xC8; + err1[4].value = 0x0010; + err1[5].reg = 0xD9; + err1[5].value = 0x0100; + err1[6].reg = 0xC9; + err1[6].value = 0x0280; + err1[7].reg = 0x8F; + err1[7].value = 0x6032; + err1[8].reg = 0x9D; + err1[8].value = 0x248C; + err1[9].reg = 0x75; + err1[9].value = 0x0060; + err1[10].reg = 0xD3; + err1[10].value = 0x7777; + + for (j = 0; ret == OK && j < 11; j++) + { + ret = ksz9477_mmd_write_indirect(port, KSZ9477_MMD_DEV_SIGNAL_QUALITY, + err1[j].reg, &(err1[j].value), 1); + } + + /* Needed configurations for MMD Quiet-WIRE */ + + err2[0].reg = 0x0; + err2[0].value = 0x9400; + err2[1].reg = 0x4; + err2[1].value = 0x00E2; + err2[2].reg = 0x6; + err2[2].value = 0x3100; + err2[3].reg = 0x9; + err2[3].value = 0xE01C; + + for (j = 0; ret == OK && j < 4; j++) + { + ret = ksz9477_mmd_write_indirect(port, KSZ9477_MMD_DEV_QUIET_WIRE, + err2[j].reg, &(err2[j].value), 1); + } + + /* More configurations for MMD Signal Quality */ + + err3[0x0].reg = 0x79; + err3[0x0].value = 0x010A; + err3[0x1].value = 0x00ED; + err3[0x2].value = 0x00D3; + err3[0x3].value = 0x00BC; + err3[0x4].value = 0x00A8; + err3[0x5].value = 0x0096; + err3[0x6].value = 0x0085; + err3[0x7].value = 0x0077; + err3[0x8].value = 0x006A; + err3[0x9].value = 0x005E; + err3[0xA].value = 0x0054; + err3[0xB].value = 0x004B; + err3[0xC].value = 0x0043; + err3[0xD].value = 0x003C; + err3[0xE].value = 0x0035; + err3[0xF].value = 0x002F; + err3[0x10].value = 0x002A; + err3[0x11].value = 0x0026; + + for (j = 0x0; ret == OK && j < 0x12; j++) + { + ret = ksz9477_mmd_write_indirect(port, KSZ9477_MMD_DEV_SIGNAL_QUALITY, + err3[0].reg + j, &(err3[j].value), 1); + } + + /* Module 9: Set various registers to get correct supply current values */ + + mod9[0].reg = 0x13; + mod9[0].value = 0x6EFF; + mod9[1].reg = 0x14; + mod9[1].value = 0xE6FF; + mod9[2].reg = 0x15; + mod9[2].value = 0x6EFF; + mod9[3].reg = 0x16; + mod9[3].value = 0xE6FF; + mod9[4].reg = 0x17; + mod9[4].value = 0x00FF; + mod9[5].reg = 0x18; + mod9[5].value = 0x43FF; + mod9[6].reg = 0x19; + mod9[6].value = 0xC3FF; + mod9[7].reg = 0x1A; + mod9[7].value = 0x6FFF; + mod9[8].reg = 0x1B; + mod9[8].value = 0x07FF; + mod9[9].reg = 0x1C; + mod9[9].value = 0x0FFF; + mod9[10].reg = 0x1D; + mod9[10].value = 0xE7FF; + mod9[11].reg = 0x1E; + mod9[11].value = 0xEFFF; + + for (j = 0; ret == OK && j < 12; j++) + { + ret = ksz9477_mmd_write_indirect(port, KSZ9477_MMD_DEV_QUIET_WIRE, + mod9[j].reg, &(mod9[j].value), 1); + } + + /* Disable EEE */ + + regval16 = 0x0; + ret = ksz9477_mmd_write_indirect(port, KSZ9477_MMD_DEV_EEE_ADVERTISEMENT, + 0x3C, ®val16, 1); + + /* Turn on autoneg */ + + ret = ksz9477_reg_write16(KSZ9477_PHY_CONTROL(port), 0x1140); + + if (ret != OK) + { + nerr("PHY Control register write failure, ret %d\n", ret); + return ret ? ret : -EINVAL; + } + + return ret; +} +#endif + +#if 0 static int ksz9477_handle_erratas(ksz9477_port_t port) { int ret; @@ -442,7 +602,7 @@ static int ksz9477_handle_erratas(ksz9477_port_t port) return ret; } - +#endif /**************************************************************************** * Public Functions @@ -625,7 +785,7 @@ int ksz9477_init(ksz9477_port_t master_port) for (i = KSZ9477_PORT_PHY1; i <= KSZ9477_PORT_PHY5; i++) { - ret = ksz9477_handle_erratas(i); + ret = ksz9477_custom_error_fixes(i); } if (ret != OK) diff --git a/drivers/net/ksz9477_reg.h b/drivers/net/ksz9477_reg.h index 3d897fd874778..c9ba41f985968 100644 --- a/drivers/net/ksz9477_reg.h +++ b/drivers/net/ksz9477_reg.h @@ -62,6 +62,8 @@ #define KSZ9477_PHY_MMD_SETUP(p) KSZ9477_PORT_REG(p, 0x11A) #define KSZ9477_PHY_MMD_DATA(p) KSZ9477_PORT_REG(p, 0x11C) +#define KSZ9477_PHY_REMOTE_LP(p) KSZ9477_PORT_REG(p, 0x122) + /* Note! Unlike in data sheet, the indirect data register reads and * writes must be done with 32-bit accesses and the address is * 0x204