BBB (cpsw(4)) seems to be broken in the latest 11-current
Luiz Otavio O Souza
loos.br at gmail.com
Mon Jun 20 15:57:04 UTC 2016
On Sun, Jun 19, 2016 at 1:11 AM, Maxim Sobolev wrote:
> Jim, some update from here. Running r283287 of the driver, I still see the
> same "watchdog timeout" messages, but they do not lead to the interface
> lockout. The traffic resumes momentarily. Which is probably why I never paid
> much attention to those warnings before. Therefore, I suspect that the new
> MAC code does not deal with watchdog-triggered interface reset as good as
> the old code. Does it give you any ideas about what could be wrong there by
> any chance?
Hi Maxim,
My recent changes contributed somehow to expose the bug more frequently.
There was a condition in tx packet reclamation where we aren't
restarting the tx queue in one of the possible stall conditions.
Please try the attached patch and let me know if it works for you.
Luiz
-------------- next part --------------
Index: sys/arm/ti/cpsw/if_cpsw.c
===================================================================
--- sys/arm/ti/cpsw/if_cpsw.c (revision 301975)
+++ sys/arm/ti/cpsw/if_cpsw.c (working copy)
@@ -1874,6 +1874,7 @@
return;
} else if (last_old_slot == NULL) {
/* Start a fresh queue. */
+ sc->swsc->last_hdp = cpsw_cpdma_bd_paddr(sc->swsc, first_new_slot);
cpsw_write_hdp_slot(sc->swsc, &sc->swsc->tx, first_new_slot);
} else {
/* Add buffers to end of current queue. */
@@ -1882,6 +1883,7 @@
/* If underrun, restart queue. */
if (cpsw_cpdma_read_bd_flags(sc->swsc, last_old_slot) &
CPDMA_BD_EOQ) {
+ sc->swsc->last_hdp = cpsw_cpdma_bd_paddr(sc->swsc, first_new_slot);
cpsw_write_hdp_slot(sc->swsc, &sc->swsc->tx,
first_new_slot);
}
@@ -1897,6 +1899,7 @@
cpsw_tx_dequeue(struct cpsw_softc *sc)
{
struct cpsw_slot *slot, *last_removed_slot = NULL;
+ struct cpsw_cpdma_bd bd;
uint32_t flags, removed = 0;
slot = STAILQ_FIRST(&sc->tx.active);
@@ -1931,7 +1934,8 @@
}
/* TearDown complete is only marked on the SOP for the packet. */
- if (flags & CPDMA_BD_TDOWNCMPLT) {
+ if ((flags & (CPDMA_BD_SOP | CPDMA_BD_TDOWNCMPLT)) ==
+ (CPDMA_BD_EOP | CPDMA_BD_TDOWNCMPLT)) {
CPSW_DEBUGF(sc, ("TX teardown in progress"));
cpsw_write_cp(sc, &sc->tx, 0xfffffffc);
// TODO: Increment a count of dropped TX packets
@@ -1938,6 +1942,16 @@
sc->tx.running = 0;
break;
}
+
+ if ((flags & CPDMA_BD_EOP) == 0)
+ flags = cpsw_cpdma_read_bd_flags(sc, last_removed_slot);
+ if ((flags & (CPDMA_BD_EOP | CPDMA_BD_EOQ)) ==
+ (CPDMA_BD_EOP | CPDMA_BD_EOQ)) {
+ cpsw_cpdma_read_bd(sc, last_removed_slot, &bd);
+ if (bd.next != 0 && bd.next != sc->last_hdp)
+ /* Restart the queue. */
+ cpsw_write_4(sc, sc->tx.hdp_offset, bd.next);
+ }
}
if (removed != 0) {
Index: sys/arm/ti/cpsw/if_cpswvar.h
===================================================================
--- sys/arm/ti/cpsw/if_cpswvar.h (revision 301975)
+++ sys/arm/ti/cpsw/if_cpswvar.h (working copy)
@@ -83,6 +83,7 @@
/* RX and TX buffer tracking */
struct cpsw_queue rx, tx;
+ uint32_t last_hdp;
/* We expect 1 memory resource and 4 interrupts from the device tree. */
int mem_rid;
More information about the freebsd-current
mailing list