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:
Alexander Motin 2024-01-27 16:51:46 -05:00
parent 5c38ea60a0
commit 3883c6fbf2
2 changed files with 22 additions and 6 deletions

View file

@ -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.

View file

@ -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