/*****************************************************************************/
/*
* baycom_epp.c -- baycom epp radio modem driver.
*
* Copyright (C) 1998-2000
* 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.1 xx.xx.1998 Initial version by Matthias Welwarsky (dg2fef)
* 0.2 21.04.1998 Massive rework by Thomas Sailer
* Integrated FPGA EPP modem configuration routines
* 0.3 11.05.1998 Took FPGA config out and moved it into a separate program
* 0.4 26.07.1999 Adapted to new lowlevel parport driver interface
* 0.5 03.08.1999 adapt to Linus' new __setup/__initcall
* removed some pre-2.2 kernel compatibility cruft
* 0.6 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts
* 0.7 12.02.2000 adapted to softnet driver interface
*
*/
/*****************************************************************************/
#include <linux/crc-ccitt.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/workqueue.h>
#include <linux/fs.h>
#include <linux/parport.h>
#include <linux/if_arp.h>
#include <linux/hdlcdrv.h>
#include <linux/baycom.h>
#include <linux/jiffies.h>
#include <linux/random.h>
#include <net/ax25.h>
#include <asm/uaccess.h>
/* --------------------------------------------------------------------- */
#define BAYCOM_DEBUG
#define BAYCOM_MAGIC 19730510
/* --------------------------------------------------------------------- */
static const char paranoia_str[] = KERN_ERR
"baycom_epp: bad magic number for hdlcdrv_state struct in routine %s\n";
static const char bc_drvname[] = "baycom_epp";
static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"
"baycom_epp: version 0.7\n";
/* --------------------------------------------------------------------- */
#define NR_PORTS 4
static struct net_device *baycom_device[NR_PORTS];
/* --------------------------------------------------------------------- */
/* EPP status register */
#define EPP_DCDBIT 0x80
#define EPP_PTTBIT 0x08
#define EPP_NREF 0x01
#define EPP_NRAEF 0x02
#define EPP_NRHF 0x04
#define EPP_NTHF 0x20
#define EPP_NTAEF 0x10
#define EPP_NTEF EPP_PTTBIT
/* EPP control register */
#define EPP_TX_FIFO_ENABLE 0x10
#define EPP_RX_FIFO_ENABLE 0x08
#define EPP_MODEM_ENABLE 0x20
#define EPP_LEDS 0xC0
#define EPP_IRQ_ENABLE 0x10
/* LPT registers */
#define LPTREG_ECONTROL 0x402
#define LPTREG_CONFIGB 0x401
#define LPTREG_CONFIGA 0x400
#define LPTREG_EPPDATA 0x004
#define LPTREG_EPPADDR 0x003
#define LPTREG_CONTROL 0x002
#define LPTREG_STATUS 0x001
#define LPTREG_DATA 0x000
/* LPT control register */
#define LPTCTRL_PROGRAM 0x04 /* 0 to reprogram */
#define LPTCTRL_WRITE 0x01
#define LPTCTRL_ADDRSTB 0x08
#define LPTCTRL_DATASTB 0x02
#define LPTCTRL_INTEN 0x10
/* LPT status register */
#define LPTSTAT_SHIFT_NINTR 6
#define LPTSTAT_WAIT 0x80
#define LPTSTAT_NINTR (1<<LPTSTAT_SHIFT_NINTR)
#define LPTSTAT_PE 0x20
#define LPTSTAT_DONE 0x10
#define LPTSTAT_NERROR 0x08
#define LPTSTAT_EPPTIMEOUT 0x01
/* LPT data register */
#define LPTDATA_SHIFT_TDI 0
#define LPTDATA_SHIFT_TMS 2
#define LPTDATA_TDI (1<<LPTDATA_SHIFT_TDI)
#define LPTDATA_TCK 0x02
#define LPTDATA_TMS (1<<LPTDATA_SHIFT_TMS)
#define LPTDATA_INITBIAS 0x80
/* EPP modem config/status bits */
#define EPP_DCDBIT 0x80
#define EPP_PTTBIT 0x08
#define EPP_RXEBIT 0x01
#define EPP_RXAEBIT 0x02
#define EPP_RXHFULL 0x04
#define EPP_NTHF 0x20
#define EPP_NTAEF 0x10
#define EPP_NTEF EPP_PTTBIT
#define EPP_TX_FIFO_ENABLE 0x10
#define EPP_RX_FIFO_ENABLE 0x08
#define EPP_MODEM_ENABLE 0x20
#define EPP_LEDS 0xC0
#define EPP_IRQ_ENABLE 0x10
/* Xilinx 4k JTAG instructions */
#define XC4K_IRLENGTH 3
#define XC4K_EXTEST 0
#define XC4K_PRELOAD 1
#define XC4K_CONFIGURE 5
#define XC4K_BYPASS 7
#define EPP_CONVENTIONAL 0
#define EPP_FPGA 1
#define EPP_FPGAEXTSTATUS 2
#define TXBUFFER_SIZE ((HDLCDRV_MAXFLEN*6/5)+8)
/* ---------------------------------------------------------------------- */
/*
* Information that need to be kept for each board.
*/
struct baycom_state {
int magic;
struct pardevice *pdev;
struct net_device *dev;
unsigned int work_running;
struct delayed_work run_work;
unsigned int modem;
unsigned