How to resolve communication issues affecting Sealevel’s XR17V35X based serial devices (7xxxec serial cards, 7106e, Relio R1)?

This article is known to apply to the following Sealevel devices:

  • 7xxxec cards
  • 7106e
  • Relio R1

This article is known to apply to the following kernel versions:

  • 4.11.0-4.14.189
  • 4.15.0-4.19.134
  • 4.20.0-5.4.53
  • 5.4.0-5.7.8

Symptoms:

  • Unable to communicate on any port, loopback test fails, etc.
  • D1-D4 card status LEDs are blinking.
  • All serial ports (/dev/ttyS* devices) appear on the system.
  • dmesg reports no errors related to 8250_exar, XR17C35X, or the /dev/ttyS* devices.

Cause:

Sealevel serial cards based on XR17V35X are supported by the 8250_exar kernel driver. Kernel version 4.11 introduced a change to the default GPIO configuration in the 8250_exar driver which applied an invalid electrical interface mode to our cards, rendering them inoperable.

Resolution:

This issue is resolved by the kernel patch titled “serial: exar: Fix GPIO configuration for cards based on XR17V35X” (commit ID 5fdbe136ae19ab751daaa4d08d9a42f3e30d17f9).

This patch is known to be included in kernel versions 4.14.190, 4.19.135, 5.4.54, and all kernels above 5.7.9.

Notice to RHEL 8 and RHEL 9 users: The steps below are not applicable due to changes made by Red Hat. Please refer to FAQ: “How do you patch the 8250_exar driver in RHEL 8 and 9 for Sealevel XR17V35X cards?

Option 1: Configure UART MPIO using gpioset command

You may work around this issue by setting the GPIO configuration from user-space using the gpioset command from libgpiod.

Notice to RHEL users: libgpiod does not detect our cards on at least RHEL and 9.

  1. Install the libgpiod utility.
    • It may be available as a package in your distribution. If not, it must be compiled manually using the build procedure outlined in the link above.
  2. Run gpiodetect to find the gpiochip associated with the XR17V35X. It should contain exar in the name.
  3. Reconfigure GPIO pins 12, 13, 14, and 15 to 0 using gpioset
    For example, if the Exar GPIO chip is gpiochip0 the commands would be:
    gpioset gpiochip0 12=0 
    gpioset gpiochip0 13=0
    gpioset gpiochip0 14=0
    gpioset gpiochip0 15=0
  4. Your Sealevel card should now be functional. Please be aware that you need to run the commands in step 3 on every boot. You might consider automating this using common Linux utilities such as cron, service files, etc

Option 2: Apply the patch to the 8250_exar driver

This is more involved than using libgpiod, but addresses the root-cause of the issue in the driver.

Note: These instructions may not work for every kernel version or distribution. Please contact Sealevel Tech Support if you have any questions.

  1. Download and extract your kernel source from https://mirrors.edge.kernel.org/pub/linux/kernel/Hint: You can determine your kernel version by running cat /proc/version
  2. Navigate to drivers/tty/serial/8250 in the kernel source.
  3. Apply changes shown in patch 30d17f9 to 8250_exar.c. The diff is shown below for convenience.
    --- linux/drivers/tty/serial/8250/8250_exar.c.orig 2020-07-09 11:05:03.920060577 -0400 
    +++ linux/drivers/tty/serial/8250/8250_exar.c 2020-07-22 14:08:27.494512202 -0400
    @@ -326,7 +326,17 @@ static void setup_gpio(struct pci_dev *p
    * devices will export them as GPIOs, so we pre-configure them safely
    * as inputs.
    */
    - u8 dir = pcidev->vendor == PCI_VENDOR_ID_EXAR ? 0xff : 0x00;
    +
    + u8 dir = 0x00;
    +
    + if ((pcidev->vendor == PCI_VENDOR_ID_EXAR) &&
    + (pcidev->subsystem_vendor != PCI_VENDOR_ID_SEALEVEL)) {
    + // Configure GPIO as inputs for Commtech adapters + dir = 0xff;
    + } else {
    + // Configure GPIO as outputs for SeaLevel adapters
    + dir = 0x00;
    + }

    writeb(0x00, p + UART_EXAR_MPIOINT_7_0);
    writeb(0x00, p + UART_EXAR_MPIOLVL_7_0);
  4. Replace the contents of Makefile with
    # SPDX-License-Identifier: GPL-2.0 
    #
    # Makefile for the 8250 serial device drivers.
    #
    obj-m. += 8250_exar.o
    obj-m += 8250_exar_sealevel.o

    all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
  5. Build the driver
    make
  6. Unload the current driver
    rmmod 8250_exar
  7. Load the patched driver
    insmod 8250_exar.ko

Verify functionality of the serial device

You can verify the GPIO configuration is correct and that the card is working by using a loopback adapter and following the steps below.

  1. Find the current ttyS ports for the serial card
    • Run cat /proc/tty/driver/serial and look for uart:XR17V35X
  2. Run sudo stty -F /dev/ttyS* raw -echo -onlcr on each port, where * is replaced by the port numbers from the previous step.
    • Note: This may clean up the output in step 5, but isn’t always required
  3. Run sudo cat /dev/ttyS*, where * is the port with the loopback adapter.
  4. Open up another terminal and enter sudo echo 'hello' > /dev/ttyS*
  5. You should see hello printed in the terminal window