---
name: "hdlcdrv"
section: "9"
platform: "linux"
package: "ax25-tools"
version: "0.0.10-rc5+git20230513+d3e6d4f-3"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/hdlcdrv"
---

# hdlcdrv(9)

HDLC amateur (AX.25) packet radio network driver

## NAME

hdlcdrv - HDLC amateur (AX.25) packet radio network driver

## SYNOPSIS

**#include \<linux/hdlcdrv.h\>**

**linux/drivers/net/hdlcdrv.c**

**extern inline void hdlcdrv\_putbits(struct hdlcdrv\_state \*** *s***, unsigned int** *bits***);**

**extern inline unsigned int hdlcdrv\_getbits(struct hdlcdrv\_state \*** *s***);**

**extern inline void hdlcdrv\_channelbit(struct hdlcdrv\_state \*** *s***, unsigned int** *bit***);**

**extern inline void hdlcdrv\_setdcd(struct hdlcdrv\_state \*** *s* **, int** *dcd***);**

**extern inline int hdlcdrv\_ptt(struct hdlcdrv\_state \*** *s***);**

**void hdlcdrv\_receiver(struct device \*, struct hdlcdrv\_state \*);**

**void hdlcdrv\_transmitter(struct device \*, struct hdlcdrv\_state \*);**

**void hdlcdrv\_arbitrate(struct device \*, struct hdlcdrv\_state \*);**

**int hdlcdrv\_register\_hdlcdrv(struct device \*** *dev***, struct hdlcdrv\_ops \*** *ops***, unsigned int** *privsize***, char \*** *ifname***, unsigned int** *baseaddr* **, unsigned int** *irq***, unsigned int** *dma***);**

**int hdlcdrv\_unregister\_hdlcdrv(struct device \*** *dev***);**

## DESCRIPTION

This driver should ease the implementation of simple AX.25 packet radio modems where the software is responsible for the HDLC encoding and decoding. Examples of such modems include the *baycom* family and the *soundcard* modems.

This driver provides a standard Linux network driver interface. It can even be compiled if Kernel AX.25 is not enabled in the Linux configuration. This allows this driver to be used even for userland AX.25 stacks such as *Wampes* or *TNOS*, with the help of the *net2kiss* utility.

This driver does not access any hardware; it is the responsibility of an additional hardware driver such as *baycom* or *soundmodem* to access the hardware and derive the bitstream to feed into this driver.

The hardware driver should store its state in a structure of the following form:

```
struct hwdrv_state {
	struct hdlc_state hdrv;
	... the drivers private state
};
```

A pointer to this structure will be stored in *dev-\>priv*.

**hdlcdrv\_register\_hdlcdrv** registers a hardware driver to the hdlc driver. *dev* points to storage for the *device* structure, which must be provided by the hardware driver, but gets initialized by this function call. *ops* provides information about the hardware driver and its calls. *privsize* should be *sizeof(struct hwdrv\_state)*. *ifname* specifies the name the interface should get. *baseaddr*, *irq* and *dma* are simply stored in the *device* structure. After this function succeeds, the interface is registered with the kernel. It is not running, however, this must be done with **ifconfig** *ifname* **up**.

**hdlcdrv\_unregister\_hdlcdrv** shuts the interface down and unregisters it with the kernel.

**hdlcdrv\_putbits** delivers 16 received bits for processing to the HDLC driver. This routine merely stores them in a buffer and does not process them. It is thus fast and can be called with interrupts off. The least significant bit should be the first one received.

**hdlcdrv\_getbits** requests 16 bits from the driver for transmission. The least significant bit should be transmitted first. This routine takes them from a buffer and is therefore fast. It can be called with interrupts off.

**hdlcdrv\_channelbit** puts a single bit into a buffer, which can be displayed with **sethdlc -s**. It is intended for driver debugging purposes.

**hdlcdrv\_setdcd** informs the HDLC driver about the channel state (i.e. if the hardware driver detected a data carrier). This information is used in the channel access algorithm, i.e. it prevents the driver from transmitting on a half duplex channel if there is already a transmitter on air.

**hdlcdrv\_ptt** should be called by the hardware driver to determine if it should start or stop transmitting. The hardware driver does not need to worry about keyup delays. This is done by the HDLC driver.

**hdlcdrv\_receiver** actually processes the received bits delivered by **hdlcdrv\_putbits**. It should be called with interrupts on. It guards itself against reentrance problems.

**hdlcdrv\_transmitter** actually prepares the bits to be transmitted. It should be called with interrupts on. It guards itself against reentrance problems.

**hdlcdrv\_arbitrate** does the channel access algorithm (p-persistent CSMA). It should be called once every 10ms. Note that the hardware driver **must** set the *hdrv.par.bitrate* field prior to starting operation so that **hdlcdrv** can calculate the transmitter keyup delay correctly.

## HARDWARE DRIVER ENTRY POINTS

The hardware driver should provide the following information to the HDLC driver:

```
struct hdlcdrv_ops {
	const char *drvname;
	const char *drvinfo;
	int (*open)(struct device *);
	int (*close)(struct device *);
	int (*ioctl)(struct device *, struct ifreq *, int);
};
```

**drvname** and **drvinfo** are just for informational purposes.

The following routines receive a pointer to the *device* structure, where they may find the io address, irq and dma channels.

**open** must be provided. It is called during **ifconfig** *ifname* **up** and should check for the hardware, grab it and initialize it. It usually installs an interrupt handler which then gets invoked by the hardware.

**close** must be provided. It is called during **ifconfig** *ifname* **down** and should undo all actions done by **open**, i.e. release io regions and irqs.

**ioctl** may be provided to implement device specific ioctl's.

## IOCTL CALLS

The driver only responds to *SIOCDEVPRIVATE*. Parameters are passed from and to the driver using the following struct:

```
struct hdlcdrv_ioctl {
	int cmd;
	union {
		struct hdlcdrv_params mp;
		struct hdlcdrv_channel_params cp;
		struct hdlcdrv_channel_state cs;
		unsigned int calibrate;
		unsigned char bits;
	} data;
};
```

Since the 16 private *ioctl request* numbers for network drivers were not enough, the driver implements its own *sub request* number with *cmd*. The following numbers are implemented:

- **HDLCDRVCTL\_GETMODEMPAR**

  returns the IO parameters of the modem in *data.mp*. This includes the io address, irq, eventually dma, and ports to output a PTT signal.

- **HDLCDRVCTL\_SETMODEMPAR**

  sets the modem parameters. Only superuser can do this. Parameters can only be changed if the interface is not running (i.e. down).

- **HDLCDRVCTL\_GETCHANNELPAR**

  returns the channel access parameters.

- **HDLCDRVCTL\_SETCHANNELPAR**

  sets the channel access parameters. Only superuser can do this. They may also be changed using the **kissparms** command if using kernel AX.25 or the **param** command of **\*NOS**.

- **HDLCDRVCTL\_GETSTAT**

  statistics and status information, such as if a carrier is detected on the channel and if the interface is currently transmitting.

- **HDLCDRVCTL\_CALIBRATE**

  instructs the driver to transmit a calibration pattern for the specified number of seconds.

- **HDLCDRVCTL\_GETSAMPLES**

  returns the bits delivered by the hardware driver with *hdlcdrv\_channelbit*. The bits are returned 8 at a time with the least significant bit the first one. This command may not be available, depending on debugging settings.

- **HDLCDRVCTL\_GETBITS**

  returns the bits delivered by the hardware driver to the HDLC decoder. The bits are returned 8 at a time with the least significant bit the first one. This command may not be available, depending on debugging settings.

## SEE ALSO

**baycom** (9), **soundmodem** (9), **sethdlc** (8),  linux/drivers/net/hdlcdrv.c,

## AUTHOR

hdlcdrv was written by Thomas Sailer, HB9JNX/AE4WA, (t.sailer@alumni.ethz.ch).
