tnt has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-e1-hardware/+/26902 )
Change subject: icE1usb fw: Have usb_e1 handle the E1 polling and multi port
......................................................................
icE1usb fw: Have usb_e1 handle the E1 polling and multi port
The init already takes care of both port and also calling
e1_init, so it makes sense to have a usb_e1_poll() that
encapsulate both the actual e1 hardware poll and running
the usb stuff for both port.
Signed-off-by: Sylvain Munaut <tnt(a)246tNt.com>
Change-Id: Icf81efcdc5c8f13480ba2652bc6e7c1ca226ae4d
---
M firmware/ice40-riscv/icE1usb/fw_app.c
M firmware/ice40-riscv/icE1usb/usb_e1.c
M firmware/ice40-riscv/icE1usb/usb_e1.h
3 files changed, 14 insertions(+), 7 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-e1-hardware refs/changes/02/26902/1
diff --git a/firmware/ice40-riscv/icE1usb/fw_app.c b/firmware/ice40-riscv/icE1usb/fw_app.c
index 5e9812c..3fbec7c 100644
--- a/firmware/ice40-riscv/icE1usb/fw_app.c
+++ b/firmware/ice40-riscv/icE1usb/fw_app.c
@@ -158,9 +158,6 @@
usb_poll();
/* E1 poll */
- for (int port=0; port<2; port++) {
- e1_poll(port);
- usb_e1_run(port);
- }
+ usb_e1_poll();
}
}
diff --git a/firmware/ice40-riscv/icE1usb/usb_e1.c b/firmware/ice40-riscv/icE1usb/usb_e1.c
index 96ca72a..5d32924 100644
--- a/firmware/ice40-riscv/icE1usb/usb_e1.c
+++ b/firmware/ice40-riscv/icE1usb/usb_e1.c
@@ -96,8 +96,8 @@
}
-void
-usb_e1_run(int port)
+static void
+_usb_e1_run(int port)
{
struct usb_e1_state *usb_e1 = _get_state(port);
volatile struct usb_ep *ep_regs;
@@ -210,6 +210,16 @@
_usb_fill_feedback_ep(port);
}
+void
+usb_e1_poll(void)
+{
+ for (int i=0; i<2; i++) {
+ e1_poll(i);
+ _usb_e1_run(i);
+ }
+}
+
+
static enum usb_fnd_resp
_e1_set_conf(const struct usb_conf_desc *conf)
{
diff --git a/firmware/ice40-riscv/icE1usb/usb_e1.h b/firmware/ice40-riscv/icE1usb/usb_e1.h
index 06723ea..65ebb61 100644
--- a/firmware/ice40-riscv/icE1usb/usb_e1.h
+++ b/firmware/ice40-riscv/icE1usb/usb_e1.h
@@ -7,5 +7,5 @@
#pragma once
-void usb_e1_run(int port);
+void usb_e1_poll(void);
void usb_e1_init(void);
--
To view, visit https://gerrit.osmocom.org/c/osmo-e1-hardware/+/26902
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-e1-hardware
Gerrit-Branch: master
Gerrit-Change-Id: Icf81efcdc5c8f13480ba2652bc6e7c1ca226ae4d
Gerrit-Change-Number: 26902
Gerrit-PatchSet: 1
Gerrit-Owner: tnt <tnt(a)246tNt.com>
Gerrit-MessageType: newchange
tnt has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-e1-hardware/+/26901 )
Change subject: icE1usb fw: Fix the E1 shutdown process
......................................................................
icE1usb fw: Fix the E1 shutdown process
So, once BD are submitted to hw, we have to wait for them to get
back, and that's what the SHUTDOWN state is for. Now, this needs
to completete before we can call e1_start() again and so in case
it wasn't done in time, we just busy waited in e1_start().
Problem is that in the absence of a valid signal, the RX side won't
process anything and so we will wait forever.
For the TX side, if we are in remote tick config and we never had
any valid signal, this could also hang.
So we change this. There is actually no need to wait for the shutdown
to complete, we can resume where we left off.
For RX: We use the 'RECOVER' which basically waits for all pending BD
to be done, empty the fifo and auto-restarts. The only "side effect" is
that we'll loose up to 4 multiframe of data at the beginning but the
RX start is async anyway, no guarantee of where we pick up.
For TX: First we empty the FIFO from any data that wasn't already
submitted to the hardware (and is now stale) and we also use the
'RECOVER' state which will wait until the FIFO reaches nominal level
before starting feeding new data. The "side effect" here is we might
TX up to 4 multiframe of old data. Although this is rather unlikely
because the conditions for TX not to have transmitted those before
are unlikely (and hopefully go away completely with OS#5402)
Signed-off-by: Sylvain Munaut <tnt(a)246tNt.com>
Change-Id: I3f3de5491e0999f89a63f507fafdc4af8c22c905
---
M firmware/ice40-riscv/icE1usb/e1.c
1 file changed, 46 insertions(+), 14 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-e1-hardware refs/changes/01/26901/1
diff --git a/firmware/ice40-riscv/icE1usb/e1.c b/firmware/ice40-riscv/icE1usb/e1.c
index b1695a6..6597124 100644
--- a/firmware/ice40-riscv/icE1usb/e1.c
+++ b/firmware/ice40-riscv/icE1usb/e1.c
@@ -216,11 +216,17 @@
}
static void
-e1f_multiframe_empty(struct e1_fifo *fifo)
+e1f_multiframe_empty_tail(struct e1_fifo *fifo)
{
fifo->rptr[0] = fifo->rptr[1] = (fifo->wptr[0] & ~15);
}
+static void
+e1f_multiframe_empty_head(struct e1_fifo *fifo)
+{
+ fifo->wptr[0] = fifo->wptr[1] = ((fifo->rptr[1] + 15) & ~15);
+}
+
// Main logic
// ----------
@@ -364,21 +370,47 @@
volatile struct e1_core *e1_regs = _get_regs(port);
struct e1_state *e1 = _get_state(port);
- /* Checks */
- while ((e1->rx.state == SHUTDOWN) || (e1->tx.state == SHUTDOWN))
- e1_poll(port);
+ /* RX */
+ switch (e1->rx.state) {
+ case IDLE:
+ /* We're idle, clear fifo and normal start */
+ e1f_reset(&e1->rx.fifo);
+ e1->rx.state = STARTING;
+ break;
- if ((e1->rx.state != IDLE) || (e1->tx.state != IDLE))
- panic("Invalid E1 hardware state (port=%d, rxs=%d, txs=%d)",
- port, e1->rx.state, e1->tx.state);
+ case SHUTDOWN:
+ /* Shutdown is pending, go to recover which is basically
+ * a shutdown with auto-restart */
+ e1->rx.state = RECOVER;
+ break;
- /* Clear FIFOs */
- e1f_reset(&e1->rx.fifo);
- e1f_reset(&e1->tx.fifo);
+ default:
+ /* Huh ... hope for the best */
+ printf("[!] E1 RX start while not stopped ...\n");
+ }
- /* Flow state */
- e1->rx.state = STARTING;
- e1->tx.state = STARTING;
+ /* TX */
+ switch (e1->tx.state) {
+ case IDLE:
+ /* We're idle, clear fifo and normal start */
+ e1f_reset(&e1->tx.fifo);
+ e1->tx.state = STARTING;
+ break;
+
+ case SHUTDOWN:
+ /* Shutdown is pending, go to recover which is basically
+ * a shutdown with auto-restart */
+ e1->tx.state = RECOVER;
+
+ /* We also prune any pending data in FIFO that's not
+ * already queued to hw */
+ e1f_multiframe_empty_head(&e1->rx.fifo);
+ break;
+
+ default:
+ /* Huh ... hope for the best */
+ printf("[!] E1 TX start while not stopped ...\n");
+ }
/* Update CRs */
_e1_update_cr_val(port);
@@ -600,7 +632,7 @@
if (e1->rx.state == RECOVER) {
if (e1->rx.in_flight != 0)
goto done_rx;
- e1f_multiframe_empty(&e1->rx.fifo);
+ e1f_multiframe_empty_tail(&e1->rx.fifo);
}
/* Fill new RX BD */
--
To view, visit https://gerrit.osmocom.org/c/osmo-e1-hardware/+/26901
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-e1-hardware
Gerrit-Branch: master
Gerrit-Change-Id: I3f3de5491e0999f89a63f507fafdc4af8c22c905
Gerrit-Change-Number: 26901
Gerrit-PatchSet: 1
Gerrit-Owner: tnt <tnt(a)246tNt.com>
Gerrit-MessageType: newchange