aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorMatthew Slattery <mslattery@solarflare.com>2009-12-23 08:48:32 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-23 22:09:07 -0500
commit1a1284ef97ca79ba747d211b697e996a248a8555 (patch)
treed338e531d49433d84f1baeba1934a55e1942fcd9 /drivers/net
parent0d83b2f64c330ee3892cb3117ac5d56e97185ecf (diff)
sfc: QT2025C: Work around PHY firmware initialisation bug
The PHY's firmware very occasionally appears to lock up very early, but with the heartbeat update still running. Rebooting the microcontroller core seems to be sufficient to recover. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sfc/qt202x_phy.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index 0cd6eed02069..326ffa49fbd2 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -63,11 +63,16 @@ struct qt202x_phy_data {
63#define QT2022C2_MAX_RESET_TIME 500 63#define QT2022C2_MAX_RESET_TIME 500
64#define QT2022C2_RESET_WAIT 10 64#define QT2022C2_RESET_WAIT 10
65 65
66#define QT2025C_MAX_HEARTB_TIME (5 * HZ)
67#define QT2025C_HEARTB_WAIT 100
68#define QT2025C_MAX_FWSTART_TIME (25 * HZ / 10)
69#define QT2025C_FWSTART_WAIT 100
70
66#define BUG17190_INTERVAL (2 * HZ) 71#define BUG17190_INTERVAL (2 * HZ)
67 72
68static int qt2025c_wait_reset(struct efx_nic *efx) 73static int qt2025c_wait_heartbeat(struct efx_nic *efx)
69{ 74{
70 unsigned long timeout = jiffies + 10 * HZ; 75 unsigned long timeout = jiffies + QT2025C_MAX_HEARTB_TIME;
71 int reg, old_counter = 0; 76 int reg, old_counter = 0;
72 77
73 /* Wait for firmware heartbeat to start */ 78 /* Wait for firmware heartbeat to start */
@@ -84,9 +89,17 @@ static int qt2025c_wait_reset(struct efx_nic *efx)
84 break; 89 break;
85 if (time_after(jiffies, timeout)) 90 if (time_after(jiffies, timeout))
86 return -ETIMEDOUT; 91 return -ETIMEDOUT;
87 msleep(10); 92 msleep(QT2025C_HEARTB_WAIT);
88 } 93 }
89 94
95 return 0;
96}
97
98static int qt2025c_wait_fw_status_good(struct efx_nic *efx)
99{
100 unsigned long timeout = jiffies + QT2025C_MAX_FWSTART_TIME;
101 int reg;
102
90 /* Wait for firmware status to look good */ 103 /* Wait for firmware status to look good */
91 for (;;) { 104 for (;;) {
92 reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG); 105 reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
@@ -98,12 +111,44 @@ static int qt2025c_wait_reset(struct efx_nic *efx)
98 break; 111 break;
99 if (time_after(jiffies, timeout)) 112 if (time_after(jiffies, timeout))
100 return -ETIMEDOUT; 113 return -ETIMEDOUT;
101 msleep(100); 114 msleep(QT2025C_FWSTART_WAIT);
102 } 115 }
103 116
104 return 0; 117 return 0;
105} 118}
106 119
120static void qt2025c_restart_firmware(struct efx_nic *efx)
121{
122 /* Restart microcontroller execution of firmware from RAM */
123 efx_mdio_write(efx, 3, 0xe854, 0x00c0);
124 efx_mdio_write(efx, 3, 0xe854, 0x0040);
125 msleep(50);
126}
127
128static int qt2025c_wait_reset(struct efx_nic *efx)
129{
130 int rc;
131
132 rc = qt2025c_wait_heartbeat(efx);
133 if (rc != 0)
134 return rc;
135
136 rc = qt2025c_wait_fw_status_good(efx);
137 if (rc == -ETIMEDOUT) {
138 /* Bug 17689: occasionally heartbeat starts but firmware status
139 * code never progresses beyond 0x00. Try again, once, after
140 * restarting execution of the firmware image. */
141 EFX_LOG(efx, "bashing QT2025C microcontroller\n");
142 qt2025c_restart_firmware(efx);
143 rc = qt2025c_wait_heartbeat(efx);
144 if (rc != 0)
145 return rc;
146 rc = qt2025c_wait_fw_status_good(efx);
147 }
148
149 return rc;
150}
151
107static void qt2025c_firmware_id(struct efx_nic *efx) 152static void qt2025c_firmware_id(struct efx_nic *efx)
108{ 153{
109 struct qt202x_phy_data *phy_data = efx->phy_data; 154 struct qt202x_phy_data *phy_data = efx->phy_data;
@@ -229,10 +274,8 @@ static int qt2025c_select_phy_mode(struct efx_nic *efx)
229 efx_mdio_write(efx, 1, 0xc300, 0x0002); 274 efx_mdio_write(efx, 1, 0xc300, 0x0002);
230 msleep(20); 275 msleep(20);
231 276
232 /* Restart microcontroller execution from RAM */ 277 /* Restart microcontroller execution of firmware from RAM */
233 efx_mdio_write(efx, 3, 0xe854, 0x00c0); 278 qt2025c_restart_firmware(efx);
234 efx_mdio_write(efx, 3, 0xe854, 0x0040);
235 msleep(50);
236 279
237 /* Wait for the microcontroller to be ready again */ 280 /* Wait for the microcontroller to be ready again */
238 rc = qt2025c_wait_reset(efx); 281 rc = qt2025c_wait_reset(efx);