// SPDX-License-Identifier: GPL-2.0-or-later /*****************************************************************************/ /* * hdlcdrv.c -- HDLC packet radio network driver. * * Copyright (C) 1996-2000 Thomas Sailer ([email protected]) * * Please note that the GPL allows you to use the driver, NOT the radio. * In order to use the radio, you need a license from the communications * authority of your country. * * The driver was derived from Donald Beckers skeleton.c * Written 1993-94 by Donald Becker. * * History: * 0.1 21.09.1996 Started * 18.10.1996 Changed to new user space access routines * (copy_{to,from}_user) * 0.2 21.11.1996 various small changes * 0.3 03.03.1997 fixed (hopefully) IP not working with ax.25 as a module * 0.4 16.04.1997 init code/data tagged * 0.5 30.07.1997 made HDLC buffers bigger (solves a problem with the * soundmodem driver) * 0.6 05.04.1998 add spinlocks * 0.7 03.08.1999 removed some old compatibility cruft * 0.8 12.02.2000 adapted to softnet driver interface */ /*****************************************************************************/ #include <linux/capability.h> #include <linux/compat.h> #include <linux/module.h> #include <linux/types.h> #include <linux/net.h> #include <linux/in.h> #include <linux/if.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/bitops.h> #include <linux/netdevice.h> #include <linux/if_arp.h> #include <linux/skbuff.h> #include <linux/hdlcdrv.h> #include <linux/random.h> #include <net/ax25.h> #include <linux/uaccess.h> #include <linux/crc-ccitt.h> /* --------------------------------------------------------------------- */ #define KISS_VERBOSE /* --------------------------------------------------------------------- */ #define PARAM_TXDELAY … #define PARAM_PERSIST … #define PARAM_SLOTTIME … #define PARAM_TXTAIL … #define PARAM_FULLDUP … #define PARAM_HARDWARE … #define PARAM_RETURN … /* --------------------------------------------------------------------- */ /* * the CRC routines are stolen from WAMPES * by Dieter Deyke */ /*---------------------------------------------------------------------------*/ static inline void append_crc_ccitt(unsigned char *buffer, int len) { … } /*---------------------------------------------------------------------------*/ static inline int check_crc_ccitt(const unsigned char *buf, int cnt) { … } /*---------------------------------------------------------------------------*/ #if 0 static int calc_crc_ccitt(const unsigned char *buf, int cnt) { unsigned int crc = 0xffff; for (; cnt > 0; cnt--) crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff]; crc ^= 0xffff; return crc & 0xffff; } #endif /* ---------------------------------------------------------------------- */ #define tenms_to_2flags(s,tenms) … /* ---------------------------------------------------------------------- */ /* * The HDLC routines */ static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits, int num) { … } static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s) { … } void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s) { … } /* ---------------------------------------------------------------------- */ static inline void do_kiss_params(struct hdlcdrv_state *s, unsigned char *data, unsigned long len) { … } /* ---------------------------------------------------------------------- */ void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s) { … } /* ---------------------------------------------------------------------- */ static void start_tx(struct net_device *dev, struct hdlcdrv_state *s) { … } /* ---------------------------------------------------------------------- */ void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s) { … } /* --------------------------------------------------------------------- */ /* * ===================== network driver interface ========================= */ static netdev_tx_t hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev) { … } /* --------------------------------------------------------------------- */ static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr) { … } /* --------------------------------------------------------------------- */ /* * Open/initialize the board. This is called (in the current kernel) * sometime after booting when the 'ifconfig' program is run. * * This routine should set everything up anew at each open, even * registers that "should" only need to be set once at boot, so that * there is non-reboot way to recover if something goes wrong. */ static int hdlcdrv_open(struct net_device *dev) { … } /* --------------------------------------------------------------------- */ /* * The inverse routine to hdlcdrv_open(). */ static int hdlcdrv_close(struct net_device *dev) { … } /* --------------------------------------------------------------------- */ static int hdlcdrv_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd) { … } /* --------------------------------------------------------------------- */ static const struct net_device_ops hdlcdrv_netdev = …; /* * Initialize fields in hdlcdrv */ static void hdlcdrv_setup(struct net_device *dev) { … } /* --------------------------------------------------------------------- */ struct net_device *hdlcdrv_register(const struct hdlcdrv_ops *ops, unsigned int privsize, const char *ifname, unsigned int baseaddr, unsigned int irq, unsigned int dma) { … } /* --------------------------------------------------------------------- */ void hdlcdrv_unregister(struct net_device *dev) { … } /* --------------------------------------------------------------------- */ EXPORT_SYMBOL(…); EXPORT_SYMBOL(…); EXPORT_SYMBOL(…); EXPORT_SYMBOL(…); EXPORT_SYMBOL(…); /* --------------------------------------------------------------------- */ static int __init hdlcdrv_init_driver(void) { … } /* --------------------------------------------------------------------- */ static void __exit hdlcdrv_cleanup_driver(void) { … } /* --------------------------------------------------------------------- */ MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; module_init(…) …; module_exit(hdlcdrv_cleanup_driver); /* --------------------------------------------------------------------- */