lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251130104222.63077-4-crescentcy.hsieh@moxa.com>
Date: Sun, 30 Nov 2025 18:41:54 +0800
From: Crescent Hsieh <crescentcy.hsieh@...a.com>
To: gregkh@...uxfoundation.org,
	jirislaby@...nel.org,
	ilpo.jarvinen@...ux.intel.com,
	andy.shevchenko@...il.com
Cc: linux-kernel@...r.kernel.org,
	linux-serial@...r.kernel.org,
	crescentcy.hsieh@...a.com
Subject: [PATCH v1 03/31] serial: 8250_mxupci: enable enhanced mode and custom FIFO trigger levels

Add support for enabling enhanced mode and configuring custom FIFO trigger
levels on Moxa UPCI serial boards.

Enhanced mode is activated via EFR, which also provides access to three
configuration pages selected through EFR[7:6].
These pages allow fine-tuning of advanced UART feature such as Rx/Tx
interrupt trigger levels and flow control thresholds.

Signed-off-by: Crescent Hsieh <crescentcy.hsieh@...a.com>
---
 drivers/tty/serial/8250/8250_mxupci.c | 65 +++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_mxupci.c b/drivers/tty/serial/8250/8250_mxupci.c
index d7a4b838ec1f..c4fa52de8962 100644
--- a/drivers/tty/serial/8250/8250_mxupci.c
+++ b/drivers/tty/serial/8250/8250_mxupci.c
@@ -43,6 +43,25 @@
 #define MOXA_UART_BASE_BAUD	921600
 #define MOXA_UART_OFFSET	8
 
+/* Enhanced Function Register (EFR) */
+/*
+ * EFR[7:6] - Enhanced Register Page Select:
+ *	00b (0x00) = Software flow control characters
+ *	01b (0x40) = FIFO trigger level
+ *	10b (0x80) = Clock, ID, reset
+ *	11b (0xC0) = Alias of Page 2 (same behavior as 10b)
+ */
+#define	MOXA_UART_EFR_PAGE_0		0x00	/* Software flow control characters */
+#define	MOXA_UART_EFR_PAGE_1		0x40	/* FIFO trigger level */
+#define	MOXA_UART_EFR_PAGE_2		0x80	/* Clock, ID, reset */
+#define MOXA_UART_EFR_PAGE_MASK		GENMASK(7, 6)
+
+/* Enhanced Registers Page 1 */
+#define MOXA_UART_RBRTL	0x04	/* Flow Control Low Trigger Level */
+#define MOXA_UART_RBRTH	0x05	/* Flow Control High Trigger Level */
+#define MOXA_UART_RBRTI	0x06	/* Rx Interrupt Trigger Level */
+#define MOXA_UART_THRTL	0x07	/* Tx Interrupt Trigger Level */
+
 struct mxupci8250 {
 	struct pci_dev *pdev;
 	unsigned int num_ports;
@@ -59,6 +78,49 @@ static unsigned short mxupci8250_get_nports(unsigned short device)
 	return FIELD_GET(0x00F0, device);
 }
 
+static int mxupci8250_startup(struct uart_port *port)
+{
+	struct uart_8250_port *up = up_to_u8250p(port);
+	int ret;
+	u8 efr;
+
+	ret = serial8250_do_startup(port);
+
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+	efr = serial_in(up, UART_EFR);
+	efr |= UART_EFR_ECB;
+	serial_out(up, UART_EFR, efr);
+
+	efr &= ~MOXA_UART_EFR_PAGE_MASK;
+	efr |= MOXA_UART_EFR_PAGE_1;
+	serial_out(up, UART_EFR, efr);
+
+	serial_out(up, MOXA_UART_THRTL, 0);
+	serial_out(up, MOXA_UART_RBRTI, 96);
+	serial_out(up, MOXA_UART_RBRTL, 32);
+	serial_out(up, MOXA_UART_RBRTH, 96);
+
+	serial_out(up, UART_LCR, up->lcr);
+
+	return ret;
+}
+
+static void mxupci8250_shutdown(struct uart_port *port)
+{
+	struct uart_8250_port *up = up_to_u8250p(port);
+	u8 efr;
+
+	serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+	efr = serial_in(up, UART_EFR);
+	serial_out(up, UART_EFR, efr & ~UART_EFR_ECB);
+
+	serial_out(up, UART_LCR, up->lcr);
+
+	serial8250_do_shutdown(port);
+}
+
 static int mxupci8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct uart_8250_port up;
@@ -90,6 +152,9 @@ static int mxupci8250_probe(struct pci_dev *pdev, const struct pci_device_id *id
 	up.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
 	up.port.type = PORT_MU860;
 
+	up.port.startup = mxupci8250_startup;
+	up.port.shutdown = mxupci8250_shutdown;
+
 	for (i = 0; i < num_ports; i++) {
 		if (serial8250_pci_setup_port(pdev, &up, FL_GET_BASE(FL_BASE2), i * MOXA_UART_OFFSET, 0))
 			break;
-- 
2.45.2


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ