Linux Dscc4+HDLC Mini-HOWTO

Frantisek Rysanek

docbook janitoring and content sanity enforcement: François Romieu



Revision History
Revision 0.22003-07-21
Included comments/corrections from Krzysztof Halasa.
Revision 0.1.22003-07-09
Corrections based on comments from reviewers
Revision 0.1.12003-06-14
Initial docbook conversion


There is a popular belief that PC hardware and telco sync serial WAN techologies don't mix.

In contrast to that belief, sync serial adapter boards for the PC have been around for quite some time now, with many interface types, from a number of vendors.

There's a common sync serial chip by Infineon called PEB20534 or DSCC4, that is used by several manufacturers of sync serial hardware. The Linux kernel contains an open-source driver for this chip. The Linux kernel has recently been enhanced with generic HDLC functionality. This is more than enough to run IP over sync serial WAN links.

This mini-HOWTO is an attempt to shed some light on the area, based on author's own (limited) experience. The goal is to get you started with IP over sync serial using DSCC4-based hardware.

Table of Contents

Dscc4/Cisco-HDLC jump-start
Hardware and layer 2
Vocabulary - obvious questions
What are all the buzzwords about? Etinc, PEB20534 and "DSCC4"?
What's this DCE and DTE stuff ?
What's the Xtal frequency? Why is it different from the clock rate?
Sync serial formats and PC hardware
Sync serial software support in Linux
In general
Wan router configuration option
Interfaces section
Configuration for PEB20534
PPP and sync PPP
PEB20534 - history and current status
Proprietary drivers
Open-source drivers
Hardware bugs
DCE operation
Tests performed
More on link status - detection, reporting & usage
In general and in human language
Under the hood - references to kernel guts
Struct net_device
Generic HDLC and syncppp.c
Appendices - links and pinouts
Software authors' homepages
Connector pinouts
Wiring of Cisco cables
X.21 DTE to V.35 DCE conversion cable



This is a mini-HOWTO. Read: far from comprehensive.

If you have related information, please send it to me. Eventually, this might become a more generic Linux Sync Serial HOWTO :)

For a start, I merely wanted to sum up my findings while I was trying to get my setup to work, so that other people wouldn't have to do the whole research allover again. Namely, I had a sync serial PCI card based on the Infineon PEB20534 chip, that I wanted to make work for IP in back-to-back configurations and against Cisco routers.

In the process, I have also learned a thing or two about the Generic HDLC Layer in Linux.

My attempts have been essentially successful.

Dscc4/Cisco-HDLC jump-start

  • Get a Linux with a kernel with generic HDLC and dscc4 drivers/modules. (Note that dscc4.o can only be a module.) My proven-to-work kernels are 2.4.21 and 2.4.21-rc1. Linux kernel source can be downloaded from

    The distro doesn't matter much - I've tried RedHat 9 and RedHat 8.0.

  • Get the sethdlc util from Krzysztof Halasa's page. Or, perhaps you'd better get my own cut - a modified sethdlc and dscc4.c, that were kindly provided by Francois Romieu during our debugging talks, plus some other goodies.

  • if your board can do both DTE and DCE, set its jumpers (if any)

insmod hdlc
insmod dscc4
sethdlc hdlc0 clock ext                # not even necessary
sethdlc hdlc0 cisco
ifconfig hdlc0 pointopoint netmask up
# echo "1" > /proc/sys/net/ipv4/ip_forward

insmod hdlc
insmod dscc4 quartz=24000000           # onboard Xtal freq in Hz
sethdlc hdlc0 clock int rate 512000    # clock_rate_in_bps
sethdlc hdlc0 cisco
ifconfig hdlc0 pointopoint netmask up
# sysctl -w net.ipv4.ip_forward=1


Hardware and layer 2

Vocabulary - obvious questions

What are all the buzzwords about? Etinc, PEB20534 and "DSCC4"?

  • PEB20534 is a four-channel async/sync serial chip with PCI bus interface, manufactured by Infineon (formerly Siemens Semiconductors), capable of 4x 10 Mbps.

  • DSCC4 is a name that Infineon uses for the silicon core or architecture of their sync serial chip. There were earlier chips with the DSCC architecture. That's where the open-source hardware driver by Francois Romieu got its name.

  • Etinc is a manufacturer of networking gear - they have a PEB20534-based board called Etinc PCIsync. They have been there for quite some time now: just go googling for Dennis and Etinc.

What's this DCE and DTE stuff ?

  • DTE = Data Terminal Equipment

    • runs along clock received from the link

    • usually an L3+ box like a PC or router

  • DCE = Data Communications Equipment

    • provides reference clock signal to the DTE

    • usually a modem or a PDH converter

With X.21/V.35, the difference between DCE and DTE is really about who generates the clock and who listens to it. You can have two PC's connected back-to-back, set up as DTE and DCE.

Both devices transmit and receive their data as a stream of bits, running at a particular clock frequency. The clock signal has a separate twisted pair channel in the electrical interface (connector pinout).

DCE is the party that generates this clock signal, latches RX and TX bits in and out along its edges, and sends the bare clock signal across the dedicated clock line - for the DTE to receive it and use it as a reference for latching the RX/TX data in/out.

In simple router/PC back-to-back cases, the "DCE" device has to generate the clock using its internal clock oscillator.

In complex telco data networks, the PDH/SDH network cloud itself is providing the clock, and both (or all) our L3 devices at the ends are set to DTE operation, receiving clock from their respective CPE modem/DTU/converter box. Somewhere at the heart of the SDH/PDH network, there's a central clock source - a dedicated high-precision oscillator box, providing clock sync to the core SDH/PDH multiplexers. The clock is then distributed throughout the network hierarchy via numerous master/slave relationships down to the CPE devices.

If it's just two base-band modems connected back to back on a dry copper line, then it's the modems (read: the lower layer) providing clock to DTE's at both ends. The modems themselves have the master/slave relationship sorted out among themselves.

Krzysztof Halasa notes that there's more to DTE vs. DCE at the Frame Relay layer: "the DCE is a 'network side' (usually a FR switch but could be a router as well) and DTE is a 'user side' (usually a router but could be, for example, an end computer or something-over-FR bridge). This assumes 'UNI' or User to Network link, as there are 'NNI' connections which are not (yet?) supported by FR code in the Generic HDLC." This FR-layer aspect is not necessarily hard-wired to the physical-layer DTE/DCE - theoretically the two layers are unrelated.

What's the Xtal frequency? Why is it different from the clock rate?

When our PC's sync serial board is set for DCE operation, it has to generate the clock signal internally - using a reasonably precise oscillator.

There's a single quartz oscillator per board (per four channels). It has a specific constant frequency that must be divided/multiplied to provide the desired per-channel sync clock rate. Tell the dscc4.o driver at insmod what its crystal's frequency is and tell `sethdlc' what clock rate you want at the particular line - the divider ratio is then calculated by the software and set into the hardware. Read on for details if interested.

In modern electronics, the general-purpose device of choice for generating precise carriers in radio equipment and clock signals in computing equipment is a "quartz crystal" - a miniature slice of the quartz mineral (or some other ceramic material) with two metallic electrodes deposited on its surfaces. Such a device has two important features:

  • it has a specific mechanical resonant frequency

  • when electric voltage is applied across its electrodes, it shrinks, and vice versa - it produces electricity when mechanically stressed.

If hooked up into an electronic feedback loop circuit, the quartz crystal oscillates at its specific frequency.

The quartz alone has one specific frequency that cannot be changed or adjusted at runtime. In fact the crystal's specific frequency is printed on its package - it's so precise. Crystals are mass-manufactured for certain standard tabulated frequencies, just like resistors or capacitors. The crystal is usually enclosed in a vaguely rectangular or oblong shiny metallic package, that is very prominent on any electronics circuit board among all the black plastic semiconductor packages, colorful resistors and capacitors in insulating sleeves.

So the crystal has a specific frequency, given by its manufacturing process, that can't be changed once mounted in an electronic device. Now we need to set our clock frequency in software. So what?

So we use a high-frequency crystal and a programmable frequency divider chip. A classic divider can provide integer parts of the crystal's main frequency, but there's yet another circuit called a PLL (Phase-Locked Loop) that can releave us of the integer divisor restriction. A PLL-based clock source consists of (again) a constant-frequency crystal oscillator, a variable-frequency voltage-tuned oscillator that's feeding a programmable divider, and a phase comparator, precisely comparing the two, adjusting the voltage-controlled oscillator to achieve precise match. Thus, the divider dividing the VCO's signal is effectively turned into a multiplier - integer multiples of some reference frequency are much more comprehensible than integer division products. Such a circuit can provide precise yet programmable clock frequency. Depending on the precise hookup of one or multiple programmable dividers and the two oscillators (constant and variable), the circuit can be tuned below as well as above the crystal's single frequency, getting quite close to the crystal's own accuracy and stability. Remember "digital tuning" radioes or CPU/FSB clock setting on modern motherboards or the adjustable VGA pixel clock.

It's like a manual gearbox in a car. Just imagine that the car has a constant-RPM engine :)

But back to dscc4 and its quartz vs. clock. The PEB20534-based PCI boards are manufactured with various crystals with different nominal frequencies. Some cards are manufactured without a crystal (intended for DTE-only operation) and some true die-hard users add crystals on their own.

There's no easy way of detecting the crystal's frequency in software. That's why, if our PEB20534 is to work as a DCE device, the card's driver (dscc4.o) needs to be told what is the crystal's own frequency. As for the programmable divider (the gearbox), the driver knows well how to control that - all it needs to know is our intended CLOCK RATE on that particular line. It then shifts the gears accordingly to meet that intention.

Our Linux driver software is divided into two parts: the generic HDLC driver and the card's low-level driver. In the current implementation, the generic HDLC layer is able to instruct the particular low-level driver about the desired clock rate and clock source setup (DCE/DTE). That's why the particular line's clock rate is set using the generic sethdlc util.

The generic hdlc layer doesn't care about the particular card's clock generator implementation. The Xtal frequency uncertainty is specific to this particular hardware. Therefore the local Xtal frequency is required by the dscc4.o module at insmod.

Sync serial formats and PC hardware

In the world of telecommunications, there are many kinds of synchronous serial links in everyday use - let's name a few examples:

  • X.21/V.35

  • E1/T1 (G.703), higher-order PDH (nowadays mainly E3/T3)

  • STM1/OC3, higher-order SDH/Sonet (STM4, STM16, STM64)

  • HSSI


This mini-HOWTO is about the sort of raw sync serial links that are commonly used used as a physical layer for HDLC-framed L2 protocols - we're speaking of X.21 and V.35 interfaces.

The X.21 and V.35 use a number of signals: apart from basic TXD and RXD, these two interfaces have lines for RTS/CTS and a separate clock line. In other words, e.g. a single X.21 link has six twisted pairs to conduct signals, three in each direction.

In the practical WAN/telco world, the most common bitrates for X.21/V.35 are Nx64kbps up to 2 Mbps, as these can easily be converted/transported over bundled timeslots in a PDH hierarchy (structured T1's/E1's and above). Nevertheless, where there are two X.21 ports on L3 devices connected back to back, there's no such a strict 64k granularity and 2Meg ceiling - the PEB20534 supports any bitrate up to 10 Mbps that can be derived from its local Xtal oscillator using the chip's internal divider&PLL. Similarly, e.g. Cisco serial ports (some models) are supposed to support rates up to 4 Mbps, can sync to any bitrate (DTE mode) and can provide clock for selected bit rates in that range (DCE mode).

AFAIK the PEB20534 can't do E1/T1 (G.703), balanced or unbalanced, not even in "unframed" mode (raw sync data, no G.704 channelized structure on it). E1/T1 interfaces run at a single possible bitrate of 2Mbps (E1) or 1,5 Mbps (T1) and do not use any other signals apart from just RX and TX - clock is recovered from the base band signal. In other words, a single E1/T1 link uses just two twisted conductor pairs or coax cables, one in each direction.

There are other sync serial technologies, such as higher-order PDH/SDH links, HSSI, native MPEG2-TS physical media formats etc. There are many brands and models of sync serial addon boards for various busses that are often combined with the PC architecture (PCI, C-PCI, ISA, other industrial/embedded busses derived from PCI or ISA etc.) and many of them now have Linux support in some form - scarcely in the vanilla kernel, more often as binary-only closed-source driver modules.

There are many addon boards that can do X.21/V.35, most of them have support in the vanilla kernel: Comtrol, COSA, MultiGate, EtincPCIsync (all PEB20534-based boards), Moxa, Farsync etc.

Fewer cards can do G.703 E1/T1 - I know of Sangoma and LanMedia products, Krzysztof Halasa adds "I believe PC300TE cards from Cyclades can do T1/E1 as well, framed and unframed".

There might be some cards out there that can do a G.704 channelized structure for data. There are also special-purpose cards (coming with proprietary Linux software) equipped with structured E1/T1/ISDN_PRI ports, for talking to DSS7 telco signaling networks, high-volume automated voice/fax prrocessing etc. - the only such vendor that I know of is Dialogic, recently acquired by Intel, but reportedly there are others.

There are E3/T3 cards and even HSSI products - the only vendor I know of is LanMedia.

I don't know of any Sonet/SDH (OC3/STM1 and above) cards for the PC. There are ATM interface cards for the PC, usually with STM1 or E3/T3 physical media. Although ATM doesn't really belong here, let's mention the vendors: Efficient Networks, Fujitsu, ZeitNet, IDT, Madge Networks, Interphase and Fore Systems.

Back to my equipment: the PEB20534 chip can do four channels of up to 10 Mbps each. The most famous card with this chip is perhaps the Etinc PCIsync, but there are others - there are hobbyist designs, there are embedded "port adapters", the particular model that I am using is standard-form-factor PCI card manufactured by my employer.

Please note that the PCI bus can be used and is used by other architectures besides X86/IBM PC and its embedded derivatives - there's Mac/PowerPC, Cisco/MIPS, Sun/Sparc and perhaps others.


Sync serial software support in Linux

In general

From the basic documents from Francois Romieu about dscc4.o and from Krzysztof Halasa about hdlc.o, I knew that I was after the "Generic HDLC Layer" and its dependencies.

In the kernel configuration, there are a number of options that claim pertinence to the sync serial, HDLC and sync PPP topics. Just try walking the menus of `make menuconfig':

->Networking options
 - WAN router                    [wanrouter.o]
 - X.25 packet layer             (apparently compatible with Generic HDLC)
 - LAPB data link driver         (needed for the X.25 support in Generic HDLC)
->Network device support
 - PPP support                   [ppp_generic.o] - for cooperation with pppd
  - PPP support for async serial [ppp_async.o]   - self-contained
  - PPP support for sync tty's   [ppp_synctty.o] - self-contained
 ->Wan interfaces
  - Comtrol Hostess SV-11      (HW specific)
  - COSA/SRP                   (HW specific)
  - Multigate (COMX)           (HW specific)
  - Etinc PCIsync              (HW specific) - uses the Gen.HDLC Layer
  - LanMedia adapters          (HW specific)
  - Aurora Technology adapters (HW specific)
  - SeaLevel Systems 4021      (HW specific)
  - SyncLink HDLC/SYNCPPP      (HW specific, just a supplement)
  - Generic HDLC layer
   - raw HDLC                  (encapsulation)
   - Cisco HDLC                (encapsulation)
   - Frame Relay               (encapsulation)
   - Sync PPP                  (encapsulation) - uses [syncppp.o]
   - X.25 protocol support     (encapsulation) - depends on LAPB
   - SDL RISCom/N2 support     (HW specific)
   - Moxa C101                 (HW specific)
   - FarSync T-Series          (HW specific)
  - Frame relay DLCI support     [dlci.o]
  ->WAN router drivers
   - Sangoma WANPIPE(tm)       (HW specific)
  - Granch SBNI12              (HW specific)
->ISDN subsystem
  - support synchronous PPP    [isdn_ppp.o]


By the help entries, all of the components above might be useful. Especially the "wan router" support seems to be necessary - as if without this module you couldn't do any WAN routing, being restricted to Ethernet rug chewing.

After re-reading the menuconfig help and kernel Documentation, some shallow study of the source code and googling around at dejanews, the picture turns out to be quite different.

Before actually discussing the individual items of the list above, let me reiterate that my goal in this mini-HOWTO is to set up a very basic IP-over-sync-serial functionality.

Wan router configuration option

The "wan router" support indeed seems to be quite generic and hardware-independent, with some interesting features. Nevertheless, it was programmed by Sangoma people and is supported by no hardware drivers except Sangoma's own and also Cyclades'.

As the help says, in order to configure and use the "wan router" infrastructure in the kernel, you need to download a package containing the necessary userland utilities from the Sangoma website. This userland package claims dependency on the latest version of Sangoma hardware drivers...

The "WAN router" contains its own HDLC/SyncPPP/netdev/etc. stack, is completely independent of the "Generic HDLC Layer" and incompatible with it.

So much for the hardware independence of wanrouter.o.


The X.25/LAPB entries in "Networking options" are a slightly weird bunch. Their menuconfig help seems to be out of date where it talks about X.25/LAPB being only supported over Ethernet. This is not true anymore - the "Generic HDLC Layer" does support X.25, at least that's what drivers/net/wan/ suggests. The X.25 "encapsulation" entry under the "Generic HDLC Layer" is dependent on the LAPB support from "Networking options". I do not know whether or not the X.25 from "Networking options" is required too, or at least compatible (if enabled), or completely irrelevant. Does it perhaps provide X.25 routing support? I'm not familiar with X.25, please elucidate me if you know for sure. Another possible point of view is that we don't really need X.25/LAPB for basic IP-over-sync-serial => you can safely skip the related menuconfig entries, thus giving up X.25 for the moment.

Interfaces section

In the "Wan Interfaces" section, there are a number of hardware-dependent drivers - for particular sync serial board models or product families from various vendors.

There are six or seven menu items for drivers supporting particular vendors (product families) from the lowest hardware layer through raw HDLC, IP encaps, up to the kernel/user interface (userland-manageable network devices). The "WAN router drivers" foldable subsection should really be called "Sangoma hardware drivers" and pretty much belongs into this category.

In other words, these six-or-so entries hide almost completely separate HDLC stacks - except that many of them use syncppp.o for the PPP encap (see the chapter on PPP below). Consequently, the different stacks support different sets of the common IP-over-sync-serial encapsulations, possibly with different bugs and features.

The Sangoma "WAN router" seems to be a particularly advanced package - the HDLC stack is just a central part, the wanrouter module and user-space utilities seem to comprise complex FR PVC management, maybe redundant IP backup routing according to the detected WAN interface status (just like Cisco does it) etc. Didn't have a chance to test it though.

That "SyncLink HDLC/SYNCPPP" menu item is not really a "dangerously dedicated" hardware driver (not this item alone). The Synclink board by Microgate is really a tty-style sync serial board, with its main hardware driver listed under "Character devices". Normally, it uses the "normal" PPP support and is interoperable with pppd. This menu item makes the card use syncppp.o instead of the tty-style PPP subsystems. More on this in the chapter on PPP below. In other words, the "Synclink HDLC/SYNCPPP" doesn't have anything to do with the "Generic HDLC Layer".

The Generic HDLC Layer by Krzysztof Halasa is compatible with hardware drivers for a few particular cards, whose authors decided that Mr. Halasa did a good job of separating the various HDLC-based sync encapsulations and generic network device operations from their low-level hardware stuff - PCI DMA mappings, passing buffers and raw link frames back'n'forth, specific ioctl()'s, hardware configuration and interfacing, hardware intelligence etc. Compared to others, the "Generic HDLC Layer" seems to have a fairly complete set of encapsulations. The PPP encap relies on syncppp.o (see the PPP chapter for more information).

The hardware drivers compliant with the "Generic HDLC Layer" are listed in the "Generic HDLC Layer" foldable subsection. One notable exception is the "Etinc PCIsync" driver (dscc4.o) by Francois Romieu, that really belongs into this category too, but is listed among the "dangerously-dedicated" drivers, apparently for historical reasons.

The "Frame Relay DLCI" menu item seems to be irrelevant, too - it is not interdependent in any way with the FR encap in the "Generic HDLC Layer". An early hint is, that hdlc.o + sethdlc works with FR DLCI's quite well even without this option compiled in.

The menuconfig help doesn't provide much information, the contents of seem to append this entry to the Generic HDLC Layer (at least optically). Nevertheless, the source code comments in dlci.c strongly suggest that this is an entirely stand-alone implementation of the Frame Relay layer - I'm not quite sure what hardware drivers and HDLC stack are supposed to be compatible with it. Would it perhaps add some FR bridging functionality to the system? Are there any relevant user-space config tools?

For any hardware compatible with the generic HDLC layer, the ISDN stuff is irrelevant, too. The ISDN stack is completely separate - see the PPP section on ISDN sync PPP support.

And, the "PPP support" under "Network device support" is not needed for the Generic HDLC layer, either - see the chapter on PPP.

To sum up, the whole Sync Serial & HDLC scene in Linux is actually quite fragmented, despite how much the on-line help, bundled with most of the seemingly relevant drivers, preaches universal love.

Configuration for PEB20534

To be able to use your PEB20534 for IP, you need the "Etinc PCISync" menu item (dscc4.o), the "Generic HDLC Layer" (hdlc.o) and its nested menu items referring to the relevant encapsulations - I recommend that you compile in at least PPP, HDLC and Cisco-HDLC (or just the single encap that you plan to be using). If you want to terminate FR PVC's, enabling the FR "encap" should be enough. If you want to terminate X.25 PVC's, enable LAPB under "Networking options" (an experimental feature) and then the X.25 "encap" under "Generic HDLC Layer". No other menu items here or elsewehere seem to be relevant (PPP,FR,X.25 etc.).

PPP and sync PPP

There are three separate PPP implementations in a standard Linux kernel:

  • the kernel-space PPP support, as visible in the "menuconfig" under "network devices", cooperating with the user-space `pppd' to run PPP over async serial lines (AKA character-class or TTY-style devices)

  • the syncppp.c - a kernel-space sync PPP driver, not visible in the "menuconfig" but included implicitly/automagically when needed by the different sync serial hardware drivers

  • the kernel-space PPP support in the ISDN subsystem, cooperating with the user-space `ipppd'. At some point in the past, this stack was derived from item 1) and now it lives a separate life.

Now how come that the "sethdlc" util also supports a "ppp" encapsulation? Where does PPP come in?

You probably know async PPP very well. There's the `pppd', a user-space daemon that attaches to a serial TTY (/dev/something) and does the LCP/AUTH/IPCP negotiation. It can talk to a modem and can dial out to call the dial-in party, or can be set for null-modem connections using the "local" keyword. Its auth parameters are set in a file. It uses some black magic interfacing towards the kernel to create ppp<x> network devices at runtime. There's even a note in `man pppd` that it can be set for sync operation with tty-style sync serial cards, namely Microgate Synclink.

There's also the ipppd used for ISDN (synchronous dialup). The kernel options around ISDN do seem to mention sync PPP, and LAPB might also seem relevant, right?

In the USENET archive at DejaNews (now, you can find numerous but vague references and talks about tighter integration of the user-space `pppd' with some generic kernel-space PPP driver stuff, talking to each other via /dev/ppp, thus allowing for multilink PPP operation, better runtime dynamic setup/shutdown of PPP network interfaces and whatnot. I.e., /dev/ppp is definitely not a serial-port-style TTY and the stock `pppd' doesn't even admit knowing about it (didn't check with strace though).

Now dscc4.o doesn't export any /dev/ttyXYZ device. Reasonable as it may sound at a first look, it certainly doesn't work to launch pppd at /dev/ppp to make it process the sync ppp frames coming from dscc4.o.

Hmm. Just where does all of that meet? How do we combine sethdlc with its PPP option (really setting the hdlc.o kernel-space driver) with the user-space pppd?

The answer is: we don't.

Forget about user-space pppd in the first place. The pppd daemon works with TTY's - character-class devices with a special set of ioctl()s, that are directly attached to their respective serial links. There *are* sync serial boards with drivers that make the sync link accessible as a character-class TTY (the Microgate Synclink). This is not the case with dscc4 though. The pppd daemon cooperates with kernel-space "generic PPP" support, visible in the menuconfig menu right here:

->Network device support
 - PPP support                   [ppp_generic.o] - for cooperation with pppd
  - PPP support for async serial [ppp_async.o]   - self-contained
  - PPP support for sync tty's   [ppp_synctty.o] - self-contained

In other words, we DO NOT NEED these menu items for sync PPP on a PEB20534.

There's an entirely separate kernel-mode sync PPP implementation. The respective driver file is drivers/net/wan/syncppp.c, by Serge Vakulenko of Cronyx, ported to Linux by Yenya Kasprzak (the author of COSA sync serial board's hardware drivers). This code module is called by the Generic HDLC Layer to provide PPP functionality when a particular hdlc<x> device is set to PPP encapsulation. This same code snippet (module) is used by many of the "dangerously-dedicated" hardware-specific drivers, namely COSA and Sangoma/Wanrouter (and others). In effect, the reference to syncppp.c is the only meeting point between the many incompatible hardware-specific HDLC stacks.

Don't get confused by the fact that, unlike the traditional PPP support, syncppp.o doesn't have its own menuconfig entry - it's created automatically by `make` if needed, based on the respective dependency (detected upon `make dep`) from any of the host of HDLC stacks.

BTW, the syncppp.c also claims to support Cisco HDLC. To that note, Krzysztof Halasa confirms that "there is a separate implementation of Cisco HDLC in Generic HDLC. This is because I have/there are plans to merge the new PPP code with syncppp (and possibly with ISDN PPP) thus rendering syncppp obsolete."

From a user-space point of view, you just set the hdlc<x> interface to "mode ppp" and that's it - attach a peer box set up for sync PPP and you get an established PPP link. The interface running PPP is still called hdlc<x> - I've already told you to forget about pppd and its ppp<x> interface naming convention.

The ISDN PPP support seems to be an entirely separate stack, too. The user-space ipppd is a mod of the original pppd, now a separate development branch. It's using a different kernel-space support module (isdn_ppp.o) that doesn't seem to link to ppp_generic.o anymore and certainly not to syncppp.o. Optionally, you can launch a legacy pppd on user-space TTY-style devices (/dev/ttyI*). At least, that's what the kernel documentation on ISDN seems to say. In other words, the ISDN stuff has nothing to do with the "Generic HDLC layer" and PEB20534.

The syncppp.c implementation seems fairly rudimentary - good enough for leased lines (permanent circuits) but lacking some features required with dial-up PPP, such as PAP/CHAP authentication. In other words, if you want PPP on your sync serial WAN link, the PPP will have to be left unauthenticated.

PEB20534 - history and current status

Proprietary drivers

Etinc corp. have their own, closed-source drivers, including a complete HDLC stack and a "bandwidth manager" - a software solution for traffic shaping and monitoring that also handles Ethernet interfaces, intended e.g. for WiFi hotspot transmitters or corporate networks. The software ships with a modified dev.c (a part of the Linux Net3 subsystem) with proprietary hooks for the bandwidth manager. The Etinc software seems to have decent link state handling. Unfortunately, due to the closed-source (binary-only) nature of the driver modules, you are restricted to about three selected kernel versions from the 2.4 branch, with module versioning turned off. I don't have hands-on experience - reportedly it works fine.

Please note that there are no universal Windows drivers for the PEB20534 - there's just some example C source code from Infineon, for DOS or some even more obscure platform.

Open-source drivers

Open-source drivers for Linux have been written by Francois Romieu and Krzysztof Halasa.

As for the border line (interface) between dscc4.o and hdlc.o: the dscc4.o is responsible for interfacing to the hardware, and hdlc.o does the encapsulation of higher-layer protocols, especially IP.

The PEB20534 parses the RX bitstream in hardware and the driver works with data already broken down into frames. The dscc4 driver essentially just passes these frames straight to the generic HDLC layer. I.e., there's no CPU-intensive parsing of the raw bitstream to find the HDLC frames' preambles, calculate the CRC etc. With TX frames, it works the other way around - the driver doesn't have to deal directly with the sync streaming of bits, it just passes HDLC frames to the hardware.

In the Linux 2.2 and earlier Linux 2.4 kernels, the dscc4.o driver did exist and was accompanied by a util called scctool to set the clock rate and other paraphernalia. Apparently it did work for some people under some circumstances. In Linux 2.5, Krzysztof Halasa implemented the Generic HDLC Layer. Later it was back-ported to Linux 2.4 - first in the form of Krzysztof's patches, then the hdlc.o driver made it to the standard vanilla kernel.

The first 2.4 kernel to feature a mutually compatible and positively operational dscc4.o and hdlc.o was 2.4.21-rc1. Mr. Romieu has provided his own mod of Mr. Halasa's sethdlc v1.12. I have installed all this on a system running RedHat 9, thus replacing its stock 2.4.20-something kernel. Then we applied a patch or two, to prevent some misbehavior when issuing "sethdlc hdlc<x> clock ext" in DTE mode (which is really the default setting, hence an unnecessary command). And such is my first proven-to-work testbed.

The modified dscc4.c and sethdlc.c that worked for me in this setup are available here. This package should also be used with 2.4.21 (release). The changes to dscc4.c have already been submitted for approval to the vanilla kernel.

A note on the modified version of sethdlc v1.12: Francois Romieu has "cut some non-compiling functionality". In other words, some parts are missing from this modified sethdlc. According to Krzysztof Halasa, the missing parts address Ethernet emulation/bridging over HDLC. The compile-time problem with sethdlc v.1.12 used to occur with kernels that did not have the Ethernet over HDLC bridging capability - which is the case with the early Generic HDLC backport in 2.4.21. With newer versions of sethdlc, such as 1.15, the compile-time problem is solved in a more appropriate way - the Ethernet-over-HDLC bridging capability in the kernel is automatically detected and excluded from sethdlc if absent in the kernel.

I don't have any information about the earlier releases of kernels, patches and utils (scctool&sethdlc). The first combination I tried was a RedHat8.0 with a stock 2.4.18-14, where it didn't seem to work at all. I'm not so much of a historian and therefore I carried out no further research of the earlier versions.

A quote from Francois Romieu: "Historically it happened that Krzysztof published his first new code for the hdlc layer just when I pushed the first versions of dscc4 and wondered where I would find the time to write a FR stack. Lucky day."

I don't have a problem to install a reasonably current kernel on a dedicated firewall-style box that's installed from scratch at the time of installing the PEB20534 PCI card. If you have some success stories with the older versions of all the software, feel free to send me precise descriptions of how you arrived at your operational setup - I'll include your instructions here.


There are only a few things that you can change compared to the jump-start chapter.

  • At the DCE, you can set a different per-channel sync clock rate.

  • At both DCE and DTE, you can change encapsulation. I've tested "cisco" (Cisco HDLC), plain "hdlc" and PPP (yes, PPP, just like that, type "sethdlc mode ppp" and it works - see the chapter on PPP).

  • With plain hdlc, you can also try several different CRC options (AKA "parity")

Essentially, all of the funny encaps work just the same - you only have to set the same parameters at the two devices that you have connected back to back.

Hardware bugs

Due to some hardware bugs in the PEB20534, it's impossible to fully reset or re-init a single channel (not even the whole chip) without a cold reset of the whole PC. Thus, it's impossible to change clock rate at runtime. It is possible to switch encapsulations (when the hdlc<x> interface is ifconfigged down). The clock rate can only be set once for each channel after cold boot or reset (after the PEB20534 has received the PCI reset signal).

Francois Romieu seems to suggest that some cards have the chip's reset pin connected to one of its own general-purpose IO pins (OR'ed with the PCI reset), so that it's effectively possible to do a software reset of the whole chip (all four channels together) at runtime. Commtech card seems to offer this feature. The latest dscc4 driver provides an option to use it. Please report success to the maintainer.

DCE operation

The Etinc PCIsync doesn't have a crystal for DCE operation. The PEB20534-based boards from my employer do have a crystal. One jumper cap per channel has to be installed to allow DCE operation on that channel.

Another note on DTE vs. DCE: Consider two PC's with PEB20534 connected back-to-back. Using simple math, you can come up with essentially three different combinations of DTE/DCE that can be set up on the boxes:

  • DTE <==> DCE

    This is the only correct combination with a chance for perfect operation. Both devices run along the same clock signal and have a chance to properly align the clock and data signal edges for proper latching.

  • DTE <==> DTE

    This will not work at all. Noone is sending the clock, both parties are listening. Both devices will likely get stuck - the hardware won't report successful clock sync, the FIFO's will not latch in any data.

  • DCE <==> DCE

    This works to a degree. Both parties run along their respective internal clock, no party listens to the other party's clock reference signal. If both parties have the clock rate set to the same value, theoretically there shouldn't be a problem.

    The trouble is that the data and clock edges will not be aligned properly. Moreover, the crystals are not infinitely precise - their manufacturing precision is perhaps 10^^-4 to 10^^-5, their stability is perhaps 10^^-6 or better, depending on long-term/short-term and temperature handling. In other words, the two clocks never tick exactly the same, there will always be a clock skew, resulting in missed bits. If one bit in a million is lost, at MTU=1500B = 12000b, there will be a frame CRC error rate (ping packet loss) of about 1 per cent. I've tried this configuration in practice (when `sethdlc clock ext` didn't work) and my ping error rate was 10 to 15 per cent or sometimes even more. To quote Francois Romieu: "Don't EVER use that setup."

The DTE-vs-DCE rules apply to any setup, not just DSCC4 back-to-back.

Tests performed

The first tests were done in a DSCC4 back-to-back configuration. I have experienced reasonable ping round trips. With long packets (1500B), the packet loss was about 0.5% (not quite a zero, but still OK). FTP transfer rates were running at 80 to 90 per cent of the nominal link bitrate (single transfer, FTP kBps compared to link kbps/8). With multiple simultaneous TCP transfers, the efficiency seemed even better.

I have also verified the "cisco" and "ppp" encaps in a few Cisco-to-PC setups:

  • DSCC4 DCE <=X.21=> Cisco 805 DTE

    The maximum bitrate of the Cisco 805's serial port is 512k. The ping packet loss was a zero, regardless of packet size etc.

  • DSCC4 DTE <=X.21/V.35 kludge=> <=CAB-V35FC=> Cisco WIC-1T DCE

    Unfortunately I didn't have a proper X.21 DCE cable (CAB-X21FC) for the Cisco and I didn't have a V.35 interface on my DSCC4-based serial board, so I had to use an X.21/V.35 conversion hack - see the appendices for a schematic. The maximum bitrate of the WIC-1T is 8 Mbps - of course I tried it :) Surprisingly, despite the ugly conversion hack, the ping packet loss was a zero, regardless of packet size etc.

  • DSCC4 DTE <=X.21=> RAD FCD-E1 DCE <=E1 bal.=> Cisco VWIC-2MFT

    The maximum bitrate of a channel-group in a structured E1 is 1984 kbps. The ping packet loss was a zero, regardless of packet size etc.

  • DSCC4 DTE <=X.21/V.35 kludge=> <=RAD V35 cable=> RAD FCD-E1 DCE <=E1 bal.=> Cisco VWIC-2MFT

    Once again I tried the conversion hack. This time it did not work at all - there was a horrible packet loss: about 50 per cent. Perhaps the FCD really needs the flow control lines, or perhaps something else needs to be loopbacked in my conversion plug.

In all setups, the ping roundtrips were just fine, corresponding to the expected serialization delay.

The setups with RAD FCD were sensitive to correct setting of clock source (internal/line) on the E1. If both the E1 ports were misconfigured to "clock source internal", the setup worked, but tended to yield random clusters of lost packets (as the two internal clocks wandered).

Interestingly, the setups involving Cisco devices were flawless, as compared to the 0.5 per cent packet loss in the DSCC4 back-to-back setup. Francois Romieu suggests that the dual-DSCC4 setups suffer from poor grounding. The X.21 line drivers/receivers are symmetrical, but the signal and shield grounds can indeed introduce a ground loop. He says that his setup suffers from the same problem.

Summary: all test setups with Cisco and RAD hardware, that did not involve the suspicious conversion cable or misconfigured E1 clock, worked flawlessly. In DSCC4 back-to-back setups, the grounding involved would use further attention. If you use the DSCC4 against quality telco hardware, with proper cabling and interface matching, you're likely on the safe side.

I would expect that a PC with DSCC4 set up as a DTE, connected to a central-office Cisco via a PDH network, should work just fine, too. I'll add a proven success story in this respect when I have one.

More on link status - detection, reporting & usage

In general and in human language

In this section, I'm not quite sure what Linux is or is not capable of. Please send corrections if you have some.

In WAN networking, line outages are something you have to deal with on automatic basis. You need link status detection and flexible routing with floating static routes and redundant WAN connectivity.

Imagine that you are a medium-size company connected to your ISP via two lines using different geographical routes, thus minimizing the risk of both lines going down at the same time due to cable cut or so.

In Cisco IOS for instance, this is not a problem - you configure two static default routes to the two WAN interfaces and your redundant topology is hereby finished. You even don't need a dynamic routing protocol/daemon.

Cisco distinguishes three different up/down attributes of an IP interface:

  • administratively UP/DOWN

  • L2 protocol UP/DOWN (PPP or HDLC etc) - relies on handshaking and keepalives

  • physical link UP/DOWN (DCD, or framing in sync)

In Cisco IOS, only interfaces with all the three attributes "UP" take part in realtime packet switching. When a link goes down on a particular interface, any static routes pointing to that interface remain in the master config table, but are excluded from the preprocessed real-time switching tables.

This scenario is typical for sync serial WAN links such as X.21, V.35 or E1 circuits. The three attributes may behave different with other media types, subinterfaces at al, but the concept is always the same. Note: the one interface that may have problems detecting end-to-end L2 integrity is Ethernet (no keepalives at L2) - but we're not speaking Ethernet here, Ethernet is not a traditional WAN technology.

On Linux, there are only two attributes: UP and RUNNING. These two attributes are either present or absent in the output of ifconfig.

UP means "administratively UP" - this is what you influence by ifconfig up/down. If an interface is "down", it simply vanishes from an ifconfig listing - you have to add the "-a" option to see all the interfaces, including those that are administratively down.

RUNNING means that the interface appears to have a "carrier", "link up" or whatever we call that. This is a real-time property that signals whether the underlying link layer is in perfect order or not, end-to-end. Arguably, with sync serial point-to-point WAN links, we really care about whether or not the IP-over-L2 encapsulation protocol is ultimately up or down.

And this is where Linux seems to have a problem.

All the Ethernet hardware drivers responsibly report link state to the appropriate status flags in the respective kernel-space `struct net_device'. In contrast, almost none of the host of HDLC stacks take care, two notable exceptions being the drivers for 8253x and Farsync. The dscc4.c only sets the RUNNING attribute once at interface startup (at `ifconfig up').

In terms of encapsulations within the "Generic HDLC Layer", the PPP and Cisco HDLC encaps do have a proprietary flag in their per-interface data structs that holds exactly this information, based on state-machine status and based on whether or not keepalives are coming back. Their proprietary status flags are nevertheless not reported up, to the appropriate flag in the generic struct net_device, and there are no IOCTLs to retrieve this information. Thus, no generic kernel-space let alone user-space software can use this information for routing decisions.

The generic HDLC doesn't even have such a proprietary status flag, perhaps because it doesn't have keepalives (?). The FrameRelay base interface does have a "reliable" flag and the FR PVC does have an "active" flag, but I doubt that these would hold anything resembling the link integrity status that we're after.

It would only be desirable if the WAN interfaces could report the RUNNING status to facilitate routing decisions, just like most all Ethernet drivers do.

Another comment from Krzysztof Halasa: "Correct. I'm currently testing a patch adding IFF_RUNNING support for generic HDLC (not only FR) - it will be available soon. Still, it will only change the RUNNING flag and will not alter routing decisions."

As mentioned earlier, Cisco IOS reports physical carrier status separate from protocol-layer status (derived from handshaking and keepalives). Some interfaces, such as structured PDH ports or ATM with OAM-managed PVC's, report even more - apart from the encapsulation protocol keepalives at a particular subinterface and the physical link carrier presence, there's also the low-level frame sync status and a number of possible PDH/SDH network errors (AIS, FERF etc). Cisco IOS is able to aggregate all these status bits into two relevant per-interface flags: link up/down and protocol up/down. Obviously, when the link is down, the protocol goes down too, automatically. This allows for fastest possible re-routing of IP traffic.

Arguably, such error flags aggregation should also take place in Linux - for the purposes of IP routing, at the generic interface level, the single RUNNING flag is IMO good enough to indicate runtime link failures of any kind. This implies that low-level hardware drivers would have to watch physical link status (if the hardware is capable of that) and report it to upper-level encapsulation/multiplexing subsystems, affecting their per-channel interface up/down bits or even resetting their protocol state-machines. Alternatively, the gathering of such information could be implemented via nested function calls, that would aggregate (logically AND) all the status flags at the different network sublayers involved.

So much for link status detection and reporting. For now, let's suppose that the RUNNING flag is updated correctly. Let's take a look at how IP routing can respond to this information.

As mentioned above, Cisco IOS can do it using a semi-dynamic concept called "floating static routes", without requiring a full-fledged routing demon (RIP,OSPF et al). In Linux terms, this would correspond to a basic Linux kernel doing the routing based on a static table as set up by /sbin/route.

The question is: can the ipv4 routing engine in the Linux kernel respond to the RUNNING flag? Alone, without the help of a user-space demon managing its routing table? The answer is: NO, most certainly it can not!

In the simple dual-backup scenario, if one of the two links failed, the natural result in Linux would be a 50% packet loss, as one of the two equal-cost default routes would keep forwarding packets to a defunct interface.

An obvious counter-argument is that perhaps the performace-tuned kernel-space packet scheduling engine is not the right place to preprocess the routing table based on link state. In that case, there should probably be a simple daemon, user-space or kernel-space, doing the simple job of suppressing routes pointing to interfaces that are not "RUNNING".

As for routed, gated et al, another obvious suggestion is: "Run routed or gated with no peers defined, so that it just watches the link states." I don't have any personal experience with these - do they watch the RUNNING flag? Or do they rely strictly on their IGP/EGP handshaking?

Ultimately, running a full IGP or EGP setup would surely do the job even without link state monitoring - except that it might mean a considerable waste of resources on your ISP's PE boxes. Your ISP would have to choose between starting another dedicated session of the routing demon or enlarging his backbone routing domain by your Linux CE box (thus also allowing you to litter his backbone routing with your own misconfigurations etc.). Compared to the basic floating static routes setup, this also entails significant configuration complexity on both the CE and the PE.

Under the hood - references to kernel guts

As mentioned above, if the link is OK, `ifconfig' shows the RUNNING flag on the respective interface. In addition to the UP flag, meaning that the interface is administratively up.

Struct net_device

In kernel space, each network device is managed using a generic block of data called 'struct net_device'. The two aforementioned attributes are hidden in two _different_ member bitmasks in the 'struct net_device':

   unsigned long state;
   unsigned short flags;

state: __LINK_STATE_NOCARRIER     (= link UP/DOWN)
flags: IFF_UP                     (= administratively UP/DOWN)


The __LINK_STATE_NOCARRIER bit flag is really private to include/linux/netdevice.h - any code accessing this flag is using the netif_carrier_...() family of inline functions.

Even these manipulator functions are kernel-space-only - user-space stuff has to use and ioctl() command SIOCGIFFLAGS to retrieve a derived flag called IFF_RUNNING. Try stracing /sbin/ifconfig to see exactly how this is done - ifconfig gets a dummy PF_INET socket using 'int socket()' and unleashes ioctl() on that.

Exactly the same IFF_RUNNING flag is also available via the Netlink socket interface.

There are also some interesting-looking entries in the /proc directory tree, such as /proc/net/dev or /proc/net/dev_stat (now called /proc/net/softnet_stat). Besides being poorly documented, at a closer inspection they don't seem to provide the generic RUNNING flag.

Generic HDLC and syncppp.c

The sync serial and HDLC drivers (except for 8253x and farsync) do not call the netif_carrier_...() functions on the generic device. Thus, the RUNNING flag reported by /sbin/ifconfig is completely bogus.

The hardware-flavoured interface data at sync serial interfaces is usually managed using a specific struct hooked up to `void* net_device::priv'.

See the following simplified code snippets.

The Cisco-HDLC encap in the "Generic HDLC Layer": in file hdlc.h:

struct hdlc_device
      struct cisco
  int up;
   } state;

1 = up
0 = down


The Sync PPP driver, used by many sync serial hardware drivers: in file syncppp.h:

struct sppp
   int pp_link_state;

#define SPPP_LINK_UP    1       = up
#define SPPP_LINK_DOWN  0       = down



The Sangoma WanRouter: in file wanrouter.h:

struct wan_device {
   char state;

enum wan_states {
 ...(state-machine states)...,
}; // heavily used by the Sangoma's encap-specific drivers/net/wan/sdla*.c


Unfortunately, this hardware-specific link state information in the various sync serial drivers is not accessible from user space in any consistent way, and perhaps not accessible at all.


A few notes on Ethernet:

As mentioned above, virtually all Ethernet hardware drivers responsibly call the netif_carrier_...() functions - thus, the RUNNING flag on your eth<x> interfaces indeed follows the link status LEDs on your Ethernet cards.

Note: unfortunately, this doesn't have much value for WAN routing, if your Metro/Wan ethernet is a switched network, rather than a single stretch of metallic or fiber ethernet, or if your metal/fiber media converters don't re-transmit the fiber link indication... This is one of the multiple reasons why, despite its current bloom, metro Ethernet it is not yet a grown-up WAN technology.

Unlike the sync serial and HDLC drivers, Ethernet drivers don't seem to use much private data - there's no such thing as a 'struct eth_device' to hold the link status.

Besides the generic IFF_RUNNING flag, updated by interrupt servicing routines and available to the user-space via the SIOCGIFFLAGS ioctl(), with Ethernet there's one other hardware-independent way of retrieving the link status: the ethertool API, available via the SIOCETHTOOL ioctl(). Specifically the ETHTOOL_GLINK command yields the current hardware link status. This ioctl() is handled by the individual hardware drivers. The driver either translates this directly to a specific hardware query or, if the card is equipped with an MII-compliant transceiver, to the generic mii_link_ok(). The mii_link_ok() checks the BMSR_LSTATUS flag in the respective MII register.

The ethtool is both a kernel-space IOCTL API and a corresponding user-space util. The link state information is one of its minor capabilities. Its major capability is setting interface speed/duplex at runtime. This is something that was missing in Linux until recently (you had to do it via kernel/insmod parameters) and that e.g. the FreeBSD's ifconfig can do since the dawning days. There's an ethtool rpm distributed as part of RedHat 8.0 and higher.


To sum up, the generic way to find out the link state of a particular network interface is by looking for the RUNNING flag in 'ifconfig' listing or using the right ioctl(). In kernel space, this results in a call to netif_carrier_ok().

If you grep the kernel sources of the ipv4 routing subsystem for occurences of "netif_carrier_" or "__LINK_STATE_NOCARRIER", you find none. Or, yes there is one call to netif_carrier_ok(), but that particular call seems irrelevant to routing decisions. The bottom line is that the kernel ipv4 routing subsystem doesn't care about the IFF_RUNNING flag.


Thanks to all the people who have created and manage Linux.

Specifically, thanks to Krzysztof Halasa for writing the Generic HDLC Layer and for providing comments to my HOWTO, and thanks to Mr. Vakulenko and Mr. Kasprzak for providing the sync PPP driver.

Most importantly, thanks to Mr. Francois Romieu for writing dscc4.c and for providing instant e-mail response, helping me to set up and debug his dscc4 driver on my hardware.

Last but not least, thanks to my employer for providing all the PC hardware and for paying me to get ever up the Linux learning curve on a full-time basis. Thanks to Martin Bisko of Pragonet for allowing me to test interoperability with his Cisco hardware.

Appendices - links and pinouts

Software authors' homepages

Francois Romieu is the author of the DSCC4 hardware driver.

Krzysztof Halasa is the author of the Generic HDLC Layer.

Connector pinouts

An excellent source of connector pinouts is the Hardware Book page. Originally I was planning to cut'n'paste their information here, their copyright policy would surely permit me to do that - but then again, why dilute the excellent original. Especially given that the site is stable and doesn't change topology too often.

Wiring of Cisco cables

The wirings can be found on the Cisco web - specifically here.

Cisco is quite liberal about putting documentation about its products on the web, most of it even in the public zone, rather than in the password-protected partner access zone. Maybe the most liberal vendor in the industry. The downside is, that their web is huge and changing topology every once in a while. When this happens, not only do any external links go dead - even the internal structure of the web gets messed up, with useful documents possibly vanishing, known paths to excellent information being turned into dead ends, some password-protected pages becoming unreachable etc.

Therefore I was planning to cut'n'paste their wiring tables here - except that after reading their copyright policy I didn't dare to do that. To sum up, if you're in trouble getting the document referenced above, try searching for it using "V.35 X.21 Smart Cable Pinout" for keywords, or send me an e-mail and I'll attach my local copy to the reply.

X.21 DTE to V.35 DCE conversion cable

This is a slight modification of a schematic posted to USENET by Mr. Nigel Ramsey in 1996. (Good job on part of Google/DejaNews.)

Beware - this DTE cable is quite a poor hack. A last resort solution. For production use, remember to order the right CPE interface from the telco operator, to match your DSCC4 hardware.

Here's the wiring diagram:

     V.35                              X.21
(34pin Winchester male)            (DB15 female)
pin#, meaning                      meaning, pin#
C    RTS -----                 ------ C(A)     3
             |                 |
D    CTS -----                 ------ I(A)     5
E    DSR -----                 ------ C(B)    10
F    DCD -----                 ------ I(B)    12
H    DTR -----

V    RXCLK(A) ----------------------- CLK(A)   6
Y    TXCLK(A) ----
U    TERMCLK(A) --

X    RXCLK(B) ----------------------- CLK(B)  13
AA   TXCLK(B) ----
W    TERMCLK(B) --

P    TX(A) -------------------------- TX(A)    2
S    TX(B) -------------------------- TX(B)    9

R    RX(A) -------------------------- RX(A)    4
T    RX(B) -------------------------- RX(B)   11

B    GND ---------------------------- GND      8
A    SHIELD ------------------------- SHIELD   1