/*****************************************************************************/
/*
* yam.c -- YAM radio modem driver.
*
* Copyright (C) 1998 Frederic Rible F1OAT (frible@teaser.fr)
* Adapted from baycom.c driver written by Thomas Sailer (sailer@ife.ee.ethz.ch)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 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.
*
*
* History:
* 0.0 F1OAT 06.06.98 Begin of work with baycom.c source code V 0.3
* 0.1 F1OAT 07.06.98 Add timer polling routine for channel arbitration
* 0.2 F6FBB 08.06.98 Added delay after FPGA programming
* 0.3 F6FBB 29.07.98 Delayed PTT implementation for dupmode=2
* 0.4 F6FBB 30.07.98 Added TxTail, Slottime and Persistance
* 0.5 F6FBB 01.08.98 Shared IRQs, /proc/net and network statistics
* 0.6 F6FBB 25.08.98 Added 1200Bds format
* 0.7 F6FBB 12.09.98 Added to the kernel configuration
* 0.8 F6FBB 14.10.98 Fixed slottime/persistence timing bug
* OK1ZIA 2.09.01 Fixed "kfree_skb on hard IRQ"
* using dev_kfree_skb_any(). (important in 2.4 kernel)
*
*/
/*****************************************************************************/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/if.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/system.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
/* prototypes for ax25_encapsulate and ax25_rebuild_header */
#include <net/ax25.h>
#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
/* make genksyms happy */
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/tcp.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/yam.h>
#include "yam9600.h"
#include "yam1200.h"
/* --------------------------------------------------------------------- */
static const char yam_drvname[] = "yam";
static char yam_drvinfo[] __initdata = KERN_INFO "YAM driver version 0.8 by F1OAT/F6FBB\n";
/* --------------------------------------------------------------------- */
#define YAM_9600 1
#define YAM_1200 2
#define NR_PORTS 4
#define YAM_MAGIC 0xF10A7654
/* Transmitter states */
#define TX_OFF 0
#define TX_HEAD 1
#define TX_DATA 2
#define TX_CRC1 3
#define TX_CRC2 4
#define TX_TAIL 5
#define YAM_MAX_FRAME 1024
#define DEFAULT_BITRATE 9600 /* bps */
#define DEFAULT_HOLDD 10 /* sec */
#define DEFAULT_TXD 300 /* ms */
#define DEFAULT_TXTAIL 10 /* ms */
#define DEFAULT_SLOT 100 /* ms */
#define DEFAULT_PERS 64 /* 0->255 */
struct yam_port {
int magic;
int bitrate;
int baudrate;
int iobase;
int irq;
int dupmode;
struct net_device *dev;
/* Stats section */
struct net_device_stats stats;
int nb_rxint;
int nb_mdint;
/* Parameters section */
int txd; /* tx delay */
int holdd; /* duplex ptt delay */
int txtail; /* txtail delay */
int slot; /* slottime */
int pers; /* persistence */
/* Tx section */
int tx_state;
int tx_count;
int slotcnt;
unsigned char tx_buf[YAM_MAX_FRAME];
int tx_len;
int tx_crcl, tx_crch;
struct sk_buff_head send_queue; /* Packets awaiting transmission */
/* Rx section */
int dcd;
unsigned char rx_buf[YAM_MAX_FRAME];
int rx_len;
int rx_crcl, rx_crch;
};
struct yam_mcs {
unsigned char bits[YAM_FPGA_SIZE];
int bitrate;
struct yam_mcs *next;
};
static struct net_device *yam_devs[NR_PORTS];
static struct yam_mcs *yam_data;
static char ax25_bcast[7] =
{'Q' << 1, 'S' <<