aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSylvain Munaut <tnt@246tNt.com>2024-04-28 09:30:05 +0200
committerSylvain Munaut <tnt@246tNt.com>2024-04-30 00:31:37 +0200
commit240cf59581cd06f5febf0f7fa253259583ff3432 (patch)
treef5107c50c2403f4de8d8d9421f7d0d01588da337 /src
parentff2c7ebc5c8780b9f8e3b039c868e8b62232a70f (diff)
iCE1usb: Add support to configure CRC4 mode for TX/RX
Signed-off-by: Sylvain Munaut <tnt@246tNt.com> Change-Id: I9b627a9617af4ae9ed98214d672c7d0391f801eb
Diffstat (limited to 'src')
-rw-r--r--src/e1d.h13
-rw-r--r--src/usb.c17
-rw-r--r--src/vty.c43
3 files changed, 72 insertions, 1 deletions
diff --git a/src/e1d.h b/src/e1d.h
index bf1cbdf..55e5415 100644
--- a/src/e1d.h
+++ b/src/e1d.h
@@ -78,6 +78,11 @@ enum e1_ts_mode {
};
extern const struct value_string e1_ts_mode_names[];
+enum e1_framing_mode {
+ E1_FRAMING_MODE_CRC4 = 0,
+ E1_FRAMING_MODE_NO_CRC4,
+};
+
struct e1_ts {
struct e1_line *line;
uint8_t id;
@@ -160,6 +165,14 @@ struct e1_line {
uint32_t rx_bytes;
} watchdog;
+ /* driver specific data */
+ struct {
+ struct {
+ enum e1_framing_mode tx;
+ enum e1_framing_mode rx;
+ } framing;
+ } usb;
+
void *e1gen_priv;
};
diff --git a/src/usb.c b/src/usb.c
index 8d431f5..3b77b94 100644
--- a/src/usb.c
+++ b/src/usb.c
@@ -1036,14 +1036,29 @@ _e1_usb_open_device(struct e1_daemon *e1d, struct libusb_device *dev, bool is_tr
goto next_interface;
}
- /* Create data flows and start the line */
+ /* Configure, create data flows and start the line */
/* all supported devices have an IN endpoint */
+ e1_usb_ctrl_set_rx_cfg(line,
+ (line->usb.framing.rx == E1_FRAMING_MODE_CRC4) ?
+ ICE1USB_RX_MODE_MULTIFRAME :
+ ICE1USB_RX_MODE_FRAME
+ );
+
line_data->flow_in = e1uf_create(line, e1_usb_xfer_in, line_data->ep_in, 4, line_data->pkt_size, 4);
e1uf_start(line_data->flow_in);
/* e1-tracer has no OUT or FEEDBACK endpoint */
if (!is_tracer) {
+ e1_usb_ctrl_set_tx_cfg(line,
+ (line->usb.framing.tx == E1_FRAMING_MODE_CRC4) ?
+ ICE1USB_TX_MODE_TS0_CRC4_E :
+ ICE1USB_TX_MODE_TS0,
+ ICE1USB_TX_TIME_SRC_LOCAL,
+ ICE1USB_TX_EXT_LOOPBACK_OFF,
+ 0x00
+ );
+
line_data->flow_out = e1uf_create(line, e1_usb_xfer_out, line_data->ep_out, 4, line_data->pkt_size, 4);
e1uf_start(line_data->flow_out);
line_data->flow_fb = e1uf_create(line, e1_usb_xfer_fb, line_data->ep_fb, 2, 3, 1);
diff --git a/src/vty.c b/src/vty.c
index 5b4ca47..3e80204 100644
--- a/src/vty.c
+++ b/src/vty.c
@@ -168,6 +168,12 @@ const struct value_string e1_line_mode_names[] = {
{ 0, NULL }
};
+const struct value_string e1_framing_mode_names[] = {
+ { E1_FRAMING_MODE_CRC4, "crc4" },
+ { E1_FRAMING_MODE_NO_CRC4, "no-crc4" },
+ { 0, NULL }
+};
+
static void vty_dump_line(struct vty *vty, const struct e1_line *line)
{
unsigned int tn;
@@ -424,12 +430,47 @@ DEFUN(cfg_e1d_if_line_mode, cfg_e1d_if_line_mode_cmd,
return CMD_SUCCESS;
}
+DEFUN(cfg_e1d_if_line_framing, cfg_e1d_if_line_framing_cmd,
+ "framing (no-crc4|crc4)",
+ NO_STR "Sets the E1 framing mode for both TX and RX\n")
+{
+ struct e1_line *line = vty->index;
+
+ if (line->intf->drv != E1_DRIVER_USB)
+ return CMD_WARNING;
+
+ if ((argc == 1) || (argv[0][0] == 't')) {
+ enum e1_framing_mode new_mode = get_string_value(e1_framing_mode_names, argv[argc-1]);
+ line->usb.framing.tx = new_mode;
+ }
+
+ if ((argc == 1) || (argv[0][0] == 'r')) {
+ enum e1_framing_mode new_mode = get_string_value(e1_framing_mode_names, argv[argc-1]);
+ line->usb.framing.rx = new_mode;
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN_CMD_ELEMENT(cfg_e1d_if_line_framing, cfg_e1d_if_line_framing_txrx_cmd,
+ "framing (tx|rx) (no-crc4|crc4)",
+ NO_STR "Sets the E1 framing mode for TX or RX independently\n", 0, 0)
+
static int config_write_line(struct vty *vty, struct e1_line *line)
{
vty_out(vty, " line %u%s", line->id, VTY_NEWLINE);
vty_out(vty, " mode %s%s", get_value_string(e1_line_mode_names, line->mode), VTY_NEWLINE);
+ if (line->intf->drv == E1_DRIVER_USB) {
+ if (line->usb.framing.tx != line->usb.framing.rx) {
+ vty_out(vty, " framing tx %s%s", get_value_string(e1_framing_mode_names, line->usb.framing.tx), VTY_NEWLINE);
+ vty_out(vty, " framing rx %s%s", get_value_string(e1_framing_mode_names, line->usb.framing.rx), VTY_NEWLINE);
+ } else {
+ vty_out(vty, " framing %s%s", get_value_string(e1_framing_mode_names, line->usb.framing.tx), VTY_NEWLINE);
+ }
+ }
+
return 0;
}
@@ -521,4 +562,6 @@ void e1d_vty_init(struct e1_daemon *e1d)
install_node(&line_node, NULL);
install_element(LINE_NODE, &cfg_e1d_if_line_mode_cmd);
+ install_element(LINE_NODE, &cfg_e1d_if_line_framing_cmd);
+ install_element(LINE_NODE, &cfg_e1d_if_line_framing_txrx_cmd);
}