mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-21 18:27:22 +00:00
ntb_hw_plx: Workaround read-only scratchpad registers
On several systems we've noticed that when NTB link goes down, the Physical Layer User Test Pattern registers we use as additional scratchpad registers (that is explicitly allowed by the chip specs) become read-only for about 100us. I see no explanation for this in the chip specs, neither why it was not seen before, may be a race. Since we do need these registers, workaround it by repeating writes until we succeed or 1ms timeout expire. MFC after: 1 week
This commit is contained in:
parent
5c38ea60a0
commit
3883c6fbf2
|
@ -279,7 +279,7 @@ int ntb_mw_set_wc(device_t ntb, unsigned mw_idx, vm_memattr_t mode);
|
|||
uint8_t ntb_spad_count(device_t ntb);
|
||||
|
||||
/*
|
||||
* ntb_get_max_spads() - zero local scratch registers
|
||||
* ntb_spad_clear() - zero local scratch registers
|
||||
* @ntb: pointer to ntb_softc instance
|
||||
*
|
||||
* This functions overwrites all local scratchpad registers with zeroes.
|
||||
|
|
|
@ -879,17 +879,33 @@ static int
|
|||
ntb_plx_spad_write(device_t dev, unsigned int idx, uint32_t val)
|
||||
{
|
||||
struct ntb_plx_softc *sc = device_get_softc(dev);
|
||||
u_int off;
|
||||
u_int off, t;
|
||||
|
||||
if (idx >= sc->spad_count1 + sc->spad_count2)
|
||||
return (EINVAL);
|
||||
|
||||
if (idx < sc->spad_count1)
|
||||
if (idx < sc->spad_count1) {
|
||||
off = sc->spad_off1 + idx * 4;
|
||||
else
|
||||
bus_write_4(sc->conf_res, off, val);
|
||||
return (0);
|
||||
} else {
|
||||
off = sc->spad_off2 + (idx - sc->spad_count1) * 4;
|
||||
bus_write_4(sc->conf_res, off, val);
|
||||
return (0);
|
||||
/*
|
||||
* For some reason when link goes down Test Pattern registers
|
||||
* we use as additional scratchpad become read-only for about
|
||||
* 100us. I see no explanation in specs, so just wait a bit.
|
||||
*/
|
||||
for (t = 0; t <= 1000; t++) {
|
||||
bus_write_4(sc->conf_res, off, val);
|
||||
if (bus_read_4(sc->conf_res, off) == val)
|
||||
return (0);
|
||||
DELAY(1);
|
||||
}
|
||||
device_printf(dev,
|
||||
"Can't write Physical Layer User Test Pattern (0x%x)\n",
|
||||
off);
|
||||
return (EIO);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in a new issue