linux/drivers/net/hamradio/6pack.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * 6pack.c	This module implements the 6pack protocol for kernel-based
 *		devices like TTY. It interfaces between a raw TTY and the
 *		kernel's AX.25 protocol layers.
 *
 * Authors:	Andreas Könsgen <[email protected]>
 *              Ralf Baechle DL5RB <[email protected]>
 *
 * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
 *
 *		Laurence Culhane, <[email protected]>
 *		Fred N. van Kempen, <[email protected]>
 */

#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/bitops.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <net/ax25.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/spinlock.h>
#include <linux/if_arp.h>
#include <linux/init.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/semaphore.h>
#include <linux/refcount.h>

#define SIXPACK_VERSION

/* sixpack priority commands */
#define SIXP_SEOF
#define SIXP_TX_URUN
#define SIXP_RX_ORUN
#define SIXP_RX_BUF_OVL

#define SIXP_CHKSUM

/* masks to get certain bits out of the status bytes sent by the TNC */

#define SIXP_CMD_MASK
#define SIXP_CHN_MASK
#define SIXP_PRIO_CMD_MASK
#define SIXP_STD_CMD_MASK
#define SIXP_PRIO_DATA_MASK
#define SIXP_TX_MASK
#define SIXP_RX_MASK
#define SIXP_RX_DCD_MASK
#define SIXP_LEDS_ON
#define SIXP_LEDS_OFF
#define SIXP_CON
#define SIXP_STA

#define SIXP_FOUND_TNC
#define SIXP_CON_ON
#define SIXP_DCD_MASK
#define SIXP_DAMA_OFF

/* default level 2 parameters */
#define SIXP_TXDELAY
#define SIXP_PERSIST
#define SIXP_SLOTTIME
#define SIXP_INIT_RESYNC_TIMEOUT
#define SIXP_RESYNC_TIMEOUT

/* 6pack configuration. */
#define SIXP_NRUNIT
#define SIXP_MTU

enum sixpack_flags {};

struct sixpack {};

#define AX25_6PACK_HEADER_LEN

static void sixpack_decode(struct sixpack *, const unsigned char[], int);
static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);

/*
 * Perform the persistence/slottime algorithm for CSMA access. If the
 * persistence check was successful, write the data to the serial driver.
 * Note that in case of DAMA operation, the data is not sent here.
 */

static void sp_xmit_on_air(struct timer_list *t)
{}

/* ----> 6pack timer interrupt handler and friends. <---- */

/* Encapsulate one AX.25 frame and stuff into a TTY queue. */
static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
{}

/* Encapsulate an IP datagram and kick it into a TTY queue. */

static netdev_tx_t sp_xmit(struct sk_buff *skb, struct net_device *dev)
{}

static int sp_open_dev(struct net_device *dev)
{}

/* Close the low-level part of the 6pack channel. */
static int sp_close(struct net_device *dev)
{}

static int sp_set_mac_address(struct net_device *dev, void *addr)
{}

static const struct net_device_ops sp_netdev_ops =;

static void sp_setup(struct net_device *dev)
{}

/* Send one completely decapsulated IP datagram to the IP layer. */

/*
 * This is the routine that sends the received data to the kernel AX.25.
 * 'cmd' is the KISS command. For AX.25 data, it is zero.
 */

static void sp_bump(struct sixpack *sp, char cmd)
{}


/* ----------------------------------------------------------------------- */

/*
 * We have a potential race on dereferencing tty->disc_data, because the tty
 * layer provides no locking at all - thus one cpu could be running
 * sixpack_receive_buf while another calls sixpack_close, which zeroes
 * tty->disc_data and frees the memory that sixpack_receive_buf is using.  The
 * best way to fix this is to use a rwlock in the tty struct, but for now we
 * use a single global rwlock for all ttys in ppp line discipline.
 */
static DEFINE_RWLOCK(disc_data_lock);
                                                                                
static struct sixpack *sp_get(struct tty_struct *tty)
{}

static void sp_put(struct sixpack *sp)
{}

/*
 * Called by the TTY driver when there's room for more data.  If we have
 * more packets to send, we send them here.
 */
static void sixpack_write_wakeup(struct tty_struct *tty)
{}

/* ----------------------------------------------------------------------- */

/*
 * Handle the 'receiver data ready' interrupt.
 * This function is called by the tty module in the kernel when
 * a block of 6pack data has been received, which can now be decapsulated
 * and sent on to some IP layer for further processing.
 */
static void sixpack_receive_buf(struct tty_struct *tty, const u8 *cp,
				const u8 *fp, size_t count)
{}

/*
 * Try to resync the TNC. Called by the resync timer defined in
 * decode_prio_command
 */

#define TNC_UNINITIALIZED
#define TNC_UNSYNC_STARTUP
#define TNC_UNSYNCED
#define TNC_IN_SYNC

static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
{}

static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
{}

static void resync_tnc(struct timer_list *t)
{}

static inline int tnc_init(struct sixpack *sp)
{}

/*
 * Open the high-level part of the 6pack channel.
 * This function is called by the TTY module when the
 * 6pack line discipline is called for.  Because we are
 * sure the tty line exists, we only have to link it to
 * a free 6pcack channel...
 */
static int sixpack_open(struct tty_struct *tty)
{}


/*
 * Close down a 6pack channel.
 * This means flushing out any pending queues, and then restoring the
 * TTY line discipline to what it was before it got hooked to 6pack
 * (which usually is TTY again).
 */
static void sixpack_close(struct tty_struct *tty)
{}

/* Perform I/O control on an active 6pack channel. */
static int sixpack_ioctl(struct tty_struct *tty, unsigned int cmd,
		unsigned long arg)
{}

static struct tty_ldisc_ops sp_ldisc =;

/* Initialize 6pack control device -- register 6pack line discipline */

static const char msg_banner[]  __initconst =;
static const char msg_regfail[] __initconst =;

static int __init sixpack_init_driver(void)
{}

static void __exit sixpack_exit_driver(void)
{}

/* encode an AX.25 packet into 6pack */

static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
	int length, unsigned char tx_delay)
{}

/* decode 4 sixpack-encoded bytes into 3 data bytes */

static void decode_data(struct sixpack *sp, unsigned char inbyte)
{}

/* identify and execute a 6pack priority command byte */

static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
{}

/* identify and execute a standard 6pack command byte */

static void decode_std_command(struct sixpack *sp, unsigned char cmd)
{}

/* decode a 6pack packet */

static void
sixpack_decode(struct sixpack *sp, const unsigned char *pre_rbuff, int count)
{}

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_ALIAS_LDISC();

module_init();
module_exit(sixpack_exit_driver);