Message ID | 20170602234042.22782-7-paul.burton@imgtec.com |
---|---|
State | Changes Requested, archived |
Delegated to: | David Miller |
Headers | show |
Hi Paul, On 03.06.2017 01:40, Paul Burton wrote: > Resets of the EG20T MAC on the MIPS Boston development board take longer > than the 1000 loops that pch_gbe_wait_clr_bit was performing. Rather > than simply increasing the number of loops, switch to using > readl_poll_timeout_atomic() from linux/iopoll.h in order to provide some > independence from the speed of the CPU. > > #define DRV_VERSION "1.01" > @@ -318,13 +319,11 @@ s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw) > */ > static void pch_gbe_wait_clr_bit(void *reg, u32 bit) > { > + int err; > u32 tmp; > > - /* wait busy */ > - tmp = 1000; > - while ((ioread32(reg) & bit) && --tmp) > - cpu_relax(); > - if (!tmp) > + err = readl_poll_timeout_atomic(reg, tmp, !(tmp & bit), 10, 500); > + if (err) > pr_err("Error: busy bit is not cleared\n"); > } This new timeout value appears to be too low - I'm seeing plenty of timeout warnings now and ultimately the device fails to initialise: [ 7.541876] pch_gbe: EG20T PCH Gigabit Ethernet Driver - version 1.01 [ 7.566451] pch_gbe: Error: busy bit is not cleared [ 7.572654] pch_gbe: Error: busy bit is not cleared [ 7.578727] pch_gbe: Error: busy bit is not cleared [ 7.587814] pch_gbe 0000:02:00.1: Invalid MAC address, interface disabled. [ 7.595605] pch_gbe 0000:02:00.1: MAC address : 00:00:00:00:00:00 [ 7.606451] pch_gbe: Error: busy bit is not cleared [ 7.612572] pch_gbe: Error: busy bit is not cleared [ 7.618618] pch_gbe: Error: busy bit is not cleared <...> [ 10.063351] pch_gbe 0000:02:00.1 eth0: Error: Invalid MAC address [ 10.074713] pch_gbe: Error: busy bit is not cleared [ 10.081030] pch_gbe: Error: busy bit is not cleared [ 10.087178] pch_gbe: Error: busy bit is not cleared [ 10.093328] pch_gbe: Error: busy bit is not cleared [ 10.100883] pch_gbe 0000:02:00.1 eth0: Error End [ 10.106272] IP-Config: Failed to open eth0 My tests show that a timeout value as big as 20000 may be required to make it work reliably ... Marcin
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index f8791be7b3b5..3d0f4c8b1742 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -24,6 +24,7 @@ #include <linux/ptp_classify.h> #include <linux/gpio.h> #include <linux/gpio/consumer.h> +#include <linux/iopoll.h> #include <linux/of_gpio.h> #define DRV_VERSION "1.01" @@ -318,13 +319,11 @@ s32 pch_gbe_mac_read_mac_addr(struct pch_gbe_hw *hw) */ static void pch_gbe_wait_clr_bit(void *reg, u32 bit) { + int err; u32 tmp; - /* wait busy */ - tmp = 1000; - while ((ioread32(reg) & bit) && --tmp) - cpu_relax(); - if (!tmp) + err = readl_poll_timeout_atomic(reg, tmp, !(tmp & bit), 10, 500); + if (err) pr_err("Error: busy bit is not cleared\n"); }
Resets of the EG20T MAC on the MIPS Boston development board take longer than the 1000 loops that pch_gbe_wait_clr_bit was performing. Rather than simply increasing the number of loops, switch to using readl_poll_timeout_atomic() from linux/iopoll.h in order to provide some independence from the speed of the CPU. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: David S. Miller <davem@davemloft.net> Cc: Eric Dumazet <edumazet@google.com> Cc: Jarod Wilson <jarod@redhat.com> Cc: Tobias Klauser <tklauser@distanz.ch> Cc: linux-mips@linux-mips.org Cc: netdev@vger.kernel.org --- Changes in v3: - Switch to using readl_poll_timeout_atomic(). Changes in v2: None drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)