Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
1051
drivers/net/hamradio/6pack.c
Normal file
1051
drivers/net/hamradio/6pack.c
Normal file
File diff suppressed because it is too large
Load Diff
191
drivers/net/hamradio/Kconfig
Normal file
191
drivers/net/hamradio/Kconfig
Normal file
@@ -0,0 +1,191 @@
|
||||
config MKISS
|
||||
tristate "Serial port KISS driver"
|
||||
depends on AX25 && BROKEN_ON_SMP
|
||||
---help---
|
||||
KISS is a protocol used for the exchange of data between a computer
|
||||
and a Terminal Node Controller (a small embedded system commonly
|
||||
used for networking over AX.25 amateur radio connections; it
|
||||
connects the computer's serial port with the radio's microphone
|
||||
input and speaker output).
|
||||
|
||||
Although KISS is less advanced than the 6pack protocol, it has
|
||||
the advantage that it is already supported by most modern TNCs
|
||||
without the need for a firmware upgrade.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called mkiss.
|
||||
|
||||
config 6PACK
|
||||
tristate "Serial port 6PACK driver"
|
||||
depends on AX25 && BROKEN_ON_SMP
|
||||
---help---
|
||||
6pack is a transmission protocol for the data exchange between your
|
||||
PC and your TNC (the Terminal Node Controller acts as a kind of
|
||||
modem connecting your computer's serial port to your radio's
|
||||
microphone input and speaker output). This protocol can be used as
|
||||
an alternative to KISS for networking over AX.25 amateur radio
|
||||
connections, but it has some extended functionality.
|
||||
|
||||
Note that this driver is still experimental and might cause
|
||||
problems. For details about the features and the usage of the
|
||||
driver, read <file:Documentation/networking/6pack.txt>.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called 6pack.
|
||||
|
||||
config BPQETHER
|
||||
tristate "BPQ Ethernet driver"
|
||||
depends on AX25
|
||||
help
|
||||
AX.25 is the protocol used for computer communication over amateur
|
||||
radio. If you say Y here, you will be able to send and receive AX.25
|
||||
traffic over Ethernet (also called "BPQ AX.25"), which could be
|
||||
useful if some other computer on your local network has a direct
|
||||
amateur radio connection.
|
||||
|
||||
config DMASCC
|
||||
tristate "High-speed (DMA) SCC driver for AX.25"
|
||||
depends on ISA && AX25 && BROKEN_ON_SMP
|
||||
---help---
|
||||
This is a driver for high-speed SCC boards, i.e. those supporting
|
||||
DMA on one port. You usually use those boards to connect your
|
||||
computer to an amateur radio modem (such as the WA4DSY 56kbps
|
||||
modem), in order to send and receive AX.25 packet radio network
|
||||
traffic.
|
||||
|
||||
Currently, this driver supports Ottawa PI/PI2, Paccomm/Gracilis
|
||||
PackeTwin, and S5SCC/DMA boards. They are detected automatically.
|
||||
If you have one of these cards, say Y here and read the AX25-HOWTO,
|
||||
available from <http://www.tldp.org/docs.html#howto>.
|
||||
|
||||
This driver can operate multiple boards simultaneously. If you
|
||||
compile it as a module (by saying M instead of Y), it will be called
|
||||
dmascc. If you don't pass any parameter to the driver, all
|
||||
possible I/O addresses are probed. This could irritate other devices
|
||||
that are currently not in use. You may specify the list of addresses
|
||||
to be probed by "dmascc=addr1,addr2,..." (when compiled into the
|
||||
kernel image) or "io=addr1,addr2,..." (when loaded as a module). The
|
||||
network interfaces will be called dmascc0 and dmascc1 for the board
|
||||
detected first, dmascc2 and dmascc3 for the second one, and so on.
|
||||
|
||||
Before you configure each interface with ifconfig, you MUST set
|
||||
certain parameters, such as channel access timing, clock mode, and
|
||||
DMA channel. This is accomplished with a small utility program,
|
||||
dmascc_cfg, available at
|
||||
<http://cacofonix.nt.tuwien.ac.at/~oe1kib/Linux/>. Please be sure to
|
||||
get at least version 1.27 of dmascc_cfg, as older versions will not
|
||||
work with the current driver.
|
||||
|
||||
config SCC
|
||||
tristate "Z8530 SCC driver"
|
||||
depends on ISA && AX25
|
||||
---help---
|
||||
These cards are used to connect your Linux box to an amateur radio
|
||||
in order to communicate with other computers. If you want to use
|
||||
this, read <file:Documentation/networking/z8530drv.txt> and the
|
||||
AX25-HOWTO, available from
|
||||
<http://www.tldp.org/docs.html#howto>. Also make sure to say Y
|
||||
to "Amateur Radio AX.25 Level 2" support.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called scc.
|
||||
|
||||
config SCC_DELAY
|
||||
bool "additional delay for PA0HZP OptoSCC compatible boards"
|
||||
depends on SCC
|
||||
help
|
||||
Say Y here if you experience problems with the SCC driver not
|
||||
working properly; please read
|
||||
<file:Documentation/networking/z8530drv.txt> for details.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config SCC_TRXECHO
|
||||
bool "support for TRX that feedback the tx signal to rx"
|
||||
depends on SCC
|
||||
help
|
||||
Some transmitters feed the transmitted signal back to the receive
|
||||
line. Say Y here to foil this by explicitly disabling the receiver
|
||||
during data transmission.
|
||||
|
||||
If in doubt, say Y.
|
||||
|
||||
config BAYCOM_SER_FDX
|
||||
tristate "BAYCOM ser12 fullduplex driver for AX.25"
|
||||
depends on AX25
|
||||
select CRC_CCITT
|
||||
---help---
|
||||
This is one of two drivers for Baycom style simple amateur radio
|
||||
modems that connect to a serial interface. The driver supports the
|
||||
ser12 design in full-duplex mode. In addition, it allows the
|
||||
baudrate to be set between 300 and 4800 baud (however not all modems
|
||||
support all baudrates). This is the preferred driver. The next
|
||||
driver, "BAYCOM ser12 half-duplex driver for AX.25" is the old
|
||||
driver and still provided in case this driver does not work with
|
||||
your serial interface chip. To configure the driver, use the sethdlc
|
||||
utility available in the standard ax25 utilities package. For
|
||||
information on the modems, see <http://www.baycom.de/> and
|
||||
<file:Documentation/networking/baycom.txt>.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called baycom_ser_fdx. This is recommended.
|
||||
|
||||
config BAYCOM_SER_HDX
|
||||
tristate "BAYCOM ser12 halfduplex driver for AX.25"
|
||||
depends on AX25
|
||||
select CRC_CCITT
|
||||
---help---
|
||||
This is one of two drivers for Baycom style simple amateur radio
|
||||
modems that connect to a serial interface. The driver supports the
|
||||
ser12 design in full-duplex mode. This is the old driver. It is
|
||||
still provided in case your serial interface chip does not work with
|
||||
the full-duplex driver. This driver is depreciated. To configure
|
||||
the driver, use the sethdlc utility available in the standard ax25
|
||||
utilities package. For information on the modems, see
|
||||
<http://www.baycom.de/> and
|
||||
<file:Documentation/networking/baycom.txt>.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called baycom_ser_hdx. This is recommended.
|
||||
|
||||
config BAYCOM_PAR
|
||||
tristate "BAYCOM picpar and par96 driver for AX.25"
|
||||
depends on PARPORT && AX25
|
||||
select CRC_CCITT
|
||||
---help---
|
||||
This is a driver for Baycom style simple amateur radio modems that
|
||||
connect to a parallel interface. The driver supports the picpar and
|
||||
par96 designs. To configure the driver, use the sethdlc utility
|
||||
available in the standard ax25 utilities package. For information on
|
||||
the modems, see <http://www.baycom.de/> and the file
|
||||
<file:Documentation/networking/baycom.txt>.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called baycom_par. This is recommended.
|
||||
|
||||
config BAYCOM_EPP
|
||||
tristate "BAYCOM epp driver for AX.25"
|
||||
depends on PARPORT && AX25 && !64BIT
|
||||
select CRC_CCITT
|
||||
---help---
|
||||
This is a driver for Baycom style simple amateur radio modems that
|
||||
connect to a parallel interface. The driver supports the EPP
|
||||
designs. To configure the driver, use the sethdlc utility available
|
||||
in the standard ax25 utilities package. For information on the
|
||||
modems, see <http://www.baycom.de/> and the file
|
||||
<file:Documentation/networking/baycom.txt>.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called baycom_epp. This is recommended.
|
||||
|
||||
config YAM
|
||||
tristate "YAM driver for AX.25"
|
||||
depends on AX25
|
||||
help
|
||||
The YAM is a modem for packet radio which connects to the serial
|
||||
port and includes some of the functions of a Terminal Node
|
||||
Controller. If you have one of those, say Y here.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called yam.
|
||||
|
22
drivers/net/hamradio/Makefile
Normal file
22
drivers/net/hamradio/Makefile
Normal file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Makefile for the Linux AX.25 and HFMODEM device drivers.
|
||||
#
|
||||
#
|
||||
# 19971130 Moved the amateur radio related network drivers from
|
||||
# drivers/net/ to drivers/hamradio for easier maintainance.
|
||||
# Joerg Reuter DL1BKE <jreuter@yaina.de>
|
||||
#
|
||||
# 20000806 Rewritten to use lists instead of if-statements.
|
||||
# Christoph Hellwig <hch@infradead.org>
|
||||
#
|
||||
|
||||
obj-$(CONFIG_DMASCC) += dmascc.o
|
||||
obj-$(CONFIG_SCC) += scc.o
|
||||
obj-$(CONFIG_MKISS) += mkiss.o
|
||||
obj-$(CONFIG_6PACK) += 6pack.o
|
||||
obj-$(CONFIG_YAM) += yam.o
|
||||
obj-$(CONFIG_BPQETHER) += bpqether.o
|
||||
obj-$(CONFIG_BAYCOM_SER_FDX) += baycom_ser_fdx.o hdlcdrv.o
|
||||
obj-$(CONFIG_BAYCOM_SER_HDX) += baycom_ser_hdx.o hdlcdrv.o
|
||||
obj-$(CONFIG_BAYCOM_PAR) += baycom_par.o hdlcdrv.o
|
||||
obj-$(CONFIG_BAYCOM_EPP) += baycom_epp.o hdlcdrv.o
|
1382
drivers/net/hamradio/baycom_epp.c
Normal file
1382
drivers/net/hamradio/baycom_epp.c
Normal file
File diff suppressed because it is too large
Load Diff
576
drivers/net/hamradio/baycom_par.c
Normal file
576
drivers/net/hamradio/baycom_par.c
Normal file
@@ -0,0 +1,576 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* baycom_par.c -- baycom par96 and picpar radio modem driver.
|
||||
*
|
||||
* Copyright (C) 1996-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.
|
||||
*
|
||||
*
|
||||
* Supported modems
|
||||
*
|
||||
* par96: This is a modem for 9600 baud FSK compatible to the G3RUH standard.
|
||||
* The modem does all the filtering and regenerates the receiver clock.
|
||||
* Data is transferred from and to the PC via a shift register.
|
||||
* The shift register is filled with 16 bits and an interrupt is
|
||||
* signalled. The PC then empties the shift register in a burst. This
|
||||
* modem connects to the parallel port, hence the name. The modem
|
||||
* leaves the implementation of the HDLC protocol and the scrambler
|
||||
* polynomial to the PC. This modem is no longer available (at least
|
||||
* from Baycom) and has been replaced by the PICPAR modem (see below).
|
||||
* You may however still build one from the schematics published in
|
||||
* cq-DL :-).
|
||||
*
|
||||
* picpar: This is a redesign of the par96 modem by Henning Rech, DF9IC. The
|
||||
* modem is protocol compatible to par96, but uses only three low
|
||||
* power ICs and can therefore be fed from the parallel port and
|
||||
* does not require an additional power supply. It features
|
||||
* built in DCD circuitry. The driver should therefore be configured
|
||||
* for hardware DCD.
|
||||
*
|
||||
*
|
||||
* Command line options (insmod command line)
|
||||
*
|
||||
* mode driver mode string. Valid choices are par96 and picpar.
|
||||
* iobase base address of the port; common values are 0x378, 0x278, 0x3bc
|
||||
*
|
||||
*
|
||||
* History:
|
||||
* 0.1 26.06.1996 Adapted from baycom.c and made network driver interface
|
||||
* 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
|
||||
* 0.3 26.04.1997 init code/data tagged
|
||||
* 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints)
|
||||
* 0.5 11.11.1997 split into separate files for ser12/par96
|
||||
* 0.6 03.08.1999 adapt to Linus' new __setup/__initcall
|
||||
* removed some pre-2.2 kernel compatibility cruft
|
||||
* 0.7 10.08.1999 Check if parport can do SPP and is safe to access during interrupt contexts
|
||||
* 0.8 12.02.2000 adapted to softnet driver interface
|
||||
* removed direct parport access, uses parport driver methods
|
||||
* 0.9 03.07.2000 fix interface name handling
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/hdlcdrv.h>
|
||||
#include <linux/baycom.h>
|
||||
#include <linux/parport.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <asm/bug.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define BAYCOM_DEBUG
|
||||
|
||||
/*
|
||||
* modem options; bit mask
|
||||
*/
|
||||
#define BAYCOM_OPTIONS_SOFTDCD 1
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static const char bc_drvname[] = "baycom_par";
|
||||
static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
|
||||
KERN_INFO "baycom_par: version 0.9 compiled " __TIME__ " " __DATE__ "\n";
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define NR_PORTS 4
|
||||
|
||||
static struct net_device *baycom_device[NR_PORTS];
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define PAR96_BURSTBITS 16
|
||||
#define PAR96_BURST 4
|
||||
#define PAR96_PTT 2
|
||||
#define PAR96_TXBIT 1
|
||||
#define PAR96_ACK 0x40
|
||||
#define PAR96_RXBIT 0x20
|
||||
#define PAR96_DCD 0x10
|
||||
#define PAR97_POWER 0xf8
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* Information that need to be kept for each board.
|
||||
*/
|
||||
|
||||
struct baycom_state {
|
||||
struct hdlcdrv_state hdrv;
|
||||
|
||||
struct pardevice *pdev;
|
||||
unsigned int options;
|
||||
|
||||
struct modem_state {
|
||||
short arb_divider;
|
||||
unsigned char flags;
|
||||
unsigned int shreg;
|
||||
struct modem_state_par96 {
|
||||
int dcd_count;
|
||||
unsigned int dcd_shreg;
|
||||
unsigned long descram;
|
||||
unsigned long scram;
|
||||
} par96;
|
||||
} modem;
|
||||
|
||||
#ifdef BAYCOM_DEBUG
|
||||
struct debug_vals {
|
||||
unsigned long last_jiffies;
|
||||
unsigned cur_intcnt;
|
||||
unsigned last_intcnt;
|
||||
int cur_pllcorr;
|
||||
int last_pllcorr;
|
||||
} debug_vals;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void __inline__ baycom_int_freq(struct baycom_state *bc)
|
||||
{
|
||||
#ifdef BAYCOM_DEBUG
|
||||
unsigned long cur_jiffies = jiffies;
|
||||
/*
|
||||
* measure the interrupt frequency
|
||||
*/
|
||||
bc->debug_vals.cur_intcnt++;
|
||||
if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) {
|
||||
bc->debug_vals.last_jiffies = cur_jiffies;
|
||||
bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
|
||||
bc->debug_vals.cur_intcnt = 0;
|
||||
bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
|
||||
bc->debug_vals.cur_pllcorr = 0;
|
||||
}
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* ===================== PAR96 specific routines =========================
|
||||
*/
|
||||
|
||||
#define PAR96_DESCRAM_TAP1 0x20000
|
||||
#define PAR96_DESCRAM_TAP2 0x01000
|
||||
#define PAR96_DESCRAM_TAP3 0x00001
|
||||
|
||||
#define PAR96_DESCRAM_TAPSH1 17
|
||||
#define PAR96_DESCRAM_TAPSH2 12
|
||||
#define PAR96_DESCRAM_TAPSH3 0
|
||||
|
||||
#define PAR96_SCRAM_TAP1 0x20000 /* X^17 */
|
||||
#define PAR96_SCRAM_TAPN 0x00021 /* X^0+X^5 */
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static __inline__ void par96_tx(struct net_device *dev, struct baycom_state *bc)
|
||||
{
|
||||
int i;
|
||||
unsigned int data = hdlcdrv_getbits(&bc->hdrv);
|
||||
struct parport *pp = bc->pdev->port;
|
||||
|
||||
for(i = 0; i < PAR96_BURSTBITS; i++, data >>= 1) {
|
||||
unsigned char val = PAR97_POWER;
|
||||
bc->modem.par96.scram = ((bc->modem.par96.scram << 1) |
|
||||
(bc->modem.par96.scram & 1));
|
||||
if (!(data & 1))
|
||||
bc->modem.par96.scram ^= 1;
|
||||
if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 1))
|
||||
bc->modem.par96.scram ^=
|
||||
(PAR96_SCRAM_TAPN << 1);
|
||||
if (bc->modem.par96.scram & (PAR96_SCRAM_TAP1 << 2))
|
||||
val |= PAR96_TXBIT;
|
||||
pp->ops->write_data(pp, val);
|
||||
pp->ops->write_data(pp, val | PAR96_BURST);
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static __inline__ void par96_rx(struct net_device *dev, struct baycom_state *bc)
|
||||
{
|
||||
int i;
|
||||
unsigned int data, mask, mask2, descx;
|
||||
struct parport *pp = bc->pdev->port;
|
||||
|
||||
/*
|
||||
* do receiver; differential decode and descramble on the fly
|
||||
*/
|
||||
for(data = i = 0; i < PAR96_BURSTBITS; i++) {
|
||||
bc->modem.par96.descram = (bc->modem.par96.descram << 1);
|
||||
if (pp->ops->read_status(pp) & PAR96_RXBIT)
|
||||
bc->modem.par96.descram |= 1;
|
||||
descx = bc->modem.par96.descram ^
|
||||
(bc->modem.par96.descram >> 1);
|
||||
/* now the diff decoded data is inverted in descram */
|
||||
pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT);
|
||||
descx ^= ((descx >> PAR96_DESCRAM_TAPSH1) ^
|
||||
(descx >> PAR96_DESCRAM_TAPSH2));
|
||||
data >>= 1;
|
||||
if (!(descx & 1))
|
||||
data |= 0x8000;
|
||||
pp->ops->write_data(pp, PAR97_POWER | PAR96_PTT | PAR96_BURST);
|
||||
}
|
||||
hdlcdrv_putbits(&bc->hdrv, data);
|
||||
/*
|
||||
* do DCD algorithm
|
||||
*/
|
||||
if (bc->options & BAYCOM_OPTIONS_SOFTDCD) {
|
||||
bc->modem.par96.dcd_shreg = (bc->modem.par96.dcd_shreg >> 16)
|
||||
| (data << 16);
|
||||
/* search for flags and set the dcd counter appropriately */
|
||||
for(mask = 0x1fe00, mask2 = 0xfc00, i = 0;
|
||||
i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
|
||||
if ((bc->modem.par96.dcd_shreg & mask) == mask2)
|
||||
bc->modem.par96.dcd_count = HDLCDRV_MAXFLEN+4;
|
||||
/* check for abort/noise sequences */
|
||||
for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0;
|
||||
i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1)
|
||||
if (((bc->modem.par96.dcd_shreg & mask) == mask2) &&
|
||||
(bc->modem.par96.dcd_count >= 0))
|
||||
bc->modem.par96.dcd_count -= HDLCDRV_MAXFLEN-10;
|
||||
/* decrement and set the dcd variable */
|
||||
if (bc->modem.par96.dcd_count >= 0)
|
||||
bc->modem.par96.dcd_count -= 2;
|
||||
hdlcdrv_setdcd(&bc->hdrv, bc->modem.par96.dcd_count > 0);
|
||||
} else {
|
||||
hdlcdrv_setdcd(&bc->hdrv, !!(pp->ops->read_status(pp) & PAR96_DCD));
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
|
||||
baycom_int_freq(bc);
|
||||
/*
|
||||
* check if transmitter active
|
||||
*/
|
||||
if (hdlcdrv_ptt(&bc->hdrv))
|
||||
par96_tx(dev, bc);
|
||||
else {
|
||||
par96_rx(dev, bc);
|
||||
if (--bc->modem.arb_divider <= 0) {
|
||||
bc->modem.arb_divider = 6;
|
||||
local_irq_enable();
|
||||
hdlcdrv_arbitrate(dev, &bc->hdrv);
|
||||
}
|
||||
}
|
||||
local_irq_enable();
|
||||
hdlcdrv_transmitter(dev, &bc->hdrv);
|
||||
hdlcdrv_receiver(dev, &bc->hdrv);
|
||||
local_irq_disable();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void par96_wakeup(void *handle)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)handle;
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
|
||||
printk(KERN_DEBUG "baycom_par: %s: why am I being woken up?\n", dev->name);
|
||||
if (!parport_claim(bc->pdev))
|
||||
printk(KERN_DEBUG "baycom_par: %s: I'm broken.\n", dev->name);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int par96_open(struct net_device *dev)
|
||||
{
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
struct parport *pp;
|
||||
|
||||
if (!dev || !bc)
|
||||
return -ENXIO;
|
||||
pp = parport_find_base(dev->base_addr);
|
||||
if (!pp) {
|
||||
printk(KERN_ERR "baycom_par: parport at 0x%lx unknown\n", dev->base_addr);
|
||||
return -ENXIO;
|
||||
}
|
||||
if (pp->irq < 0) {
|
||||
printk(KERN_ERR "baycom_par: parport at 0x%lx has no irq\n", pp->base);
|
||||
parport_put_port(pp);
|
||||
return -ENXIO;
|
||||
}
|
||||
if ((~pp->modes) & (PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT)) {
|
||||
printk(KERN_ERR "baycom_par: parport at 0x%lx cannot be used\n", pp->base);
|
||||
parport_put_port(pp);
|
||||
return -ENXIO;
|
||||
}
|
||||
memset(&bc->modem, 0, sizeof(bc->modem));
|
||||
bc->hdrv.par.bitrate = 9600;
|
||||
bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup,
|
||||
par96_interrupt, PARPORT_DEV_EXCL, dev);
|
||||
parport_put_port(pp);
|
||||
if (!bc->pdev) {
|
||||
printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", dev->base_addr);
|
||||
return -ENXIO;
|
||||
}
|
||||
if (parport_claim(bc->pdev)) {
|
||||
printk(KERN_ERR "baycom_par: parport at 0x%lx busy\n", pp->base);
|
||||
parport_unregister_device(bc->pdev);
|
||||
return -EBUSY;
|
||||
}
|
||||
pp = bc->pdev->port;
|
||||
dev->irq = pp->irq;
|
||||
pp->ops->data_forward(pp);
|
||||
bc->hdrv.par.bitrate = 9600;
|
||||
pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER); /* switch off PTT */
|
||||
pp->ops->enable_irq(pp);
|
||||
printk(KERN_INFO "%s: par96 at iobase 0x%lx irq %u options 0x%x\n",
|
||||
bc_drvname, dev->base_addr, dev->irq, bc->options);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int par96_close(struct net_device *dev)
|
||||
{
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
struct parport *pp;
|
||||
|
||||
if (!dev || !bc)
|
||||
return -EINVAL;
|
||||
pp = bc->pdev->port;
|
||||
/* disable interrupt */
|
||||
pp->ops->disable_irq(pp);
|
||||
/* switch off PTT */
|
||||
pp->ops->write_data(pp, PAR96_PTT | PAR97_POWER);
|
||||
parport_release(bc->pdev);
|
||||
parport_unregister_device(bc->pdev);
|
||||
printk(KERN_INFO "%s: close par96 at iobase 0x%lx irq %u\n",
|
||||
bc_drvname, dev->base_addr, dev->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* ===================== hdlcdrv driver interface =========================
|
||||
*/
|
||||
|
||||
static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||
struct hdlcdrv_ioctl *hi, int cmd);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct hdlcdrv_ops par96_ops = {
|
||||
.drvname = bc_drvname,
|
||||
.drvinfo = bc_drvinfo,
|
||||
.open = par96_open,
|
||||
.close = par96_close,
|
||||
.ioctl = baycom_ioctl
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_setmode(struct baycom_state *bc, const char *modestr)
|
||||
{
|
||||
if (!strncmp(modestr, "picpar", 6))
|
||||
bc->options = 0;
|
||||
else if (!strncmp(modestr, "par96", 5))
|
||||
bc->options = BAYCOM_OPTIONS_SOFTDCD;
|
||||
else
|
||||
bc->options = !!strchr(modestr, '*');
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||
struct hdlcdrv_ioctl *hi, int cmd)
|
||||
{
|
||||
struct baycom_state *bc;
|
||||
struct baycom_ioctl bi;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
bc = netdev_priv(dev);
|
||||
BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
|
||||
|
||||
if (cmd != SIOCDEVPRIVATE)
|
||||
return -ENOIOCTLCMD;
|
||||
switch (hi->cmd) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case HDLCDRVCTL_GETMODE:
|
||||
strcpy(hi->data.modename, bc->options ? "par96" : "picpar");
|
||||
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_SETMODE:
|
||||
if (netif_running(dev) || !capable(CAP_NET_ADMIN))
|
||||
return -EACCES;
|
||||
hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
|
||||
return baycom_setmode(bc, hi->data.modename);
|
||||
|
||||
case HDLCDRVCTL_MODELIST:
|
||||
strcpy(hi->data.modename, "par96,picpar");
|
||||
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_MODEMPARMASK:
|
||||
return HDLCDRV_PARMASK_IOBASE;
|
||||
|
||||
}
|
||||
|
||||
if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
switch (bi.cmd) {
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
#ifdef BAYCOM_DEBUG
|
||||
case BAYCOMCTL_GETDEBUG:
|
||||
bi.data.dbg.debug1 = bc->hdrv.ptt_keyed;
|
||||
bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
|
||||
bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
|
||||
break;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
|
||||
}
|
||||
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* command line settable parameters
|
||||
*/
|
||||
static const char *mode[NR_PORTS] = { "picpar", };
|
||||
static int iobase[NR_PORTS] = { 0x378, };
|
||||
|
||||
module_param_array(mode, charp, NULL, 0);
|
||||
MODULE_PARM_DESC(mode, "baycom operating mode; eg. par96 or picpar");
|
||||
module_param_array(iobase, int, NULL, 0);
|
||||
MODULE_PARM_DESC(iobase, "baycom io base address");
|
||||
|
||||
MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
|
||||
MODULE_DESCRIPTION("Baycom par96 and picpar amateur radio modem driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int __init init_baycompar(void)
|
||||
{
|
||||
int i, found = 0;
|
||||
char set_hw = 1;
|
||||
|
||||
printk(bc_drvinfo);
|
||||
/*
|
||||
* register net devices
|
||||
*/
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
struct net_device *dev;
|
||||
struct baycom_state *bc;
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
sprintf(ifname, "bcp%d", i);
|
||||
|
||||
if (!mode[i])
|
||||
set_hw = 0;
|
||||
if (!set_hw)
|
||||
iobase[i] = 0;
|
||||
|
||||
dev = hdlcdrv_register(&par96_ops,
|
||||
sizeof(struct baycom_state),
|
||||
ifname, iobase[i], 0, 0);
|
||||
if (IS_ERR(dev))
|
||||
break;
|
||||
|
||||
bc = netdev_priv(dev);
|
||||
if (set_hw && baycom_setmode(bc, mode[i]))
|
||||
set_hw = 0;
|
||||
found++;
|
||||
baycom_device[i] = dev;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -ENXIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit cleanup_baycompar(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NR_PORTS; i++) {
|
||||
struct net_device *dev = baycom_device[i];
|
||||
|
||||
if (dev)
|
||||
hdlcdrv_unregister(dev);
|
||||
}
|
||||
}
|
||||
|
||||
module_init(init_baycompar);
|
||||
module_exit(cleanup_baycompar);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#ifndef MODULE
|
||||
|
||||
/*
|
||||
* format: baycom_par=io,mode
|
||||
* mode: par96,picpar
|
||||
*/
|
||||
|
||||
static int __init baycom_par_setup(char *str)
|
||||
{
|
||||
static unsigned nr_dev;
|
||||
int ints[2];
|
||||
|
||||
if (nr_dev >= NR_PORTS)
|
||||
return 0;
|
||||
str = get_options(str, 2, ints);
|
||||
if (ints[0] < 1)
|
||||
return 0;
|
||||
mode[nr_dev] = str;
|
||||
iobase[nr_dev] = ints[1];
|
||||
nr_dev++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("baycom_par=", baycom_par_setup);
|
||||
|
||||
#endif /* MODULE */
|
||||
/* --------------------------------------------------------------------- */
|
704
drivers/net/hamradio/baycom_ser_fdx.c
Normal file
704
drivers/net/hamradio/baycom_ser_fdx.c
Normal file
@@ -0,0 +1,704 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* baycom_ser_fdx.c -- baycom ser12 fullduplex radio modem driver.
|
||||
*
|
||||
* Copyright (C) 1996-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.
|
||||
*
|
||||
*
|
||||
* Supported modems
|
||||
*
|
||||
* ser12: This is a very simple 1200 baud AFSK modem. The modem consists only
|
||||
* of a modulator/demodulator chip, usually a TI TCM3105. The computer
|
||||
* is responsible for regenerating the receiver bit clock, as well as
|
||||
* for handling the HDLC protocol. The modem connects to a serial port,
|
||||
* hence the name. Since the serial port is not used as an async serial
|
||||
* port, the kernel driver for serial ports cannot be used, and this
|
||||
* driver only supports standard serial hardware (8250, 16450, 16550A)
|
||||
*
|
||||
* This modem usually draws its supply current out of the otherwise unused
|
||||
* TXD pin of the serial port. Thus a contignuous stream of 0x00-bytes
|
||||
* is transmitted to achieve a positive supply voltage.
|
||||
*
|
||||
* hsk: This is a 4800 baud FSK modem, designed for TNC use. It works fine
|
||||
* in 'baycom-mode' :-) In contrast to the TCM3105 modem, power is
|
||||
* externally supplied. So there's no need to provide the 0x00-byte-stream
|
||||
* when receiving or idle, which drastically reduces interrupt load.
|
||||
*
|
||||
* Command line options (insmod command line)
|
||||
*
|
||||
* mode ser# hardware DCD
|
||||
* ser#* software DCD
|
||||
* ser#+ hardware DCD, inverted signal at DCD pin
|
||||
* '#' denotes the baud rate / 100, eg. ser12* is '1200 baud, soft DCD'
|
||||
* iobase base address of the port; common values are 0x3f8, 0x2f8, 0x3e8, 0x2e8
|
||||
* baud baud rate (between 300 and 4800)
|
||||
* irq interrupt line of the port; common values are 4,3
|
||||
*
|
||||
*
|
||||
* History:
|
||||
* 0.1 26.06.1996 Adapted from baycom.c and made network driver interface
|
||||
* 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
|
||||
* 0.3 26.04.1997 init code/data tagged
|
||||
* 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints)
|
||||
* 0.5 11.11.1997 ser12/par96 split into separate files
|
||||
* 0.6 24.01.1998 Thorsten Kranzkowski, dl8bcu and Thomas Sailer:
|
||||
* reduced interrupt load in transmit case
|
||||
* reworked receiver
|
||||
* 0.7 03.08.1999 adapt to Linus' new __setup/__initcall
|
||||
* 0.8 10.08.1999 use module_init/module_exit
|
||||
* 0.9 12.02.2000 adapted to softnet driver interface
|
||||
* 0.10 03.07.2000 fix interface name handling
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/hdlcdrv.h>
|
||||
#include <linux/baycom.h>
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define BAYCOM_DEBUG
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static const char bc_drvname[] = "baycom_ser_fdx";
|
||||
static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
|
||||
KERN_INFO "baycom_ser_fdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define NR_PORTS 4
|
||||
|
||||
static struct net_device *baycom_device[NR_PORTS];
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define RBR(iobase) (iobase+0)
|
||||
#define THR(iobase) (iobase+0)
|
||||
#define IER(iobase) (iobase+1)
|
||||
#define IIR(iobase) (iobase+2)
|
||||
#define FCR(iobase) (iobase+2)
|
||||
#define LCR(iobase) (iobase+3)
|
||||
#define MCR(iobase) (iobase+4)
|
||||
#define LSR(iobase) (iobase+5)
|
||||
#define MSR(iobase) (iobase+6)
|
||||
#define SCR(iobase) (iobase+7)
|
||||
#define DLL(iobase) (iobase+0)
|
||||
#define DLM(iobase) (iobase+1)
|
||||
|
||||
#define SER12_EXTENT 8
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* Information that need to be kept for each board.
|
||||
*/
|
||||
|
||||
struct baycom_state {
|
||||
struct hdlcdrv_state hdrv;
|
||||
|
||||
unsigned int baud, baud_us, baud_arbdiv, baud_uartdiv, baud_dcdtimeout;
|
||||
int opt_dcd;
|
||||
|
||||
struct modem_state {
|
||||
unsigned char flags;
|
||||
unsigned char ptt;
|
||||
unsigned int shreg;
|
||||
struct modem_state_ser12 {
|
||||
unsigned char tx_bit;
|
||||
unsigned char last_rxbit;
|
||||
int dcd_sum0, dcd_sum1, dcd_sum2;
|
||||
int dcd_time;
|
||||
unsigned int pll_time;
|
||||
unsigned int txshreg;
|
||||
} ser12;
|
||||
} modem;
|
||||
|
||||
#ifdef BAYCOM_DEBUG
|
||||
struct debug_vals {
|
||||
unsigned long last_jiffies;
|
||||
unsigned cur_intcnt;
|
||||
unsigned last_intcnt;
|
||||
int cur_pllcorr;
|
||||
int last_pllcorr;
|
||||
} debug_vals;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static inline void baycom_int_freq(struct baycom_state *bc)
|
||||
{
|
||||
#ifdef BAYCOM_DEBUG
|
||||
unsigned long cur_jiffies = jiffies;
|
||||
/*
|
||||
* measure the interrupt frequency
|
||||
*/
|
||||
bc->debug_vals.cur_intcnt++;
|
||||
if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) {
|
||||
bc->debug_vals.last_jiffies = cur_jiffies;
|
||||
bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
|
||||
bc->debug_vals.cur_intcnt = 0;
|
||||
bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
|
||||
bc->debug_vals.cur_pllcorr = 0;
|
||||
}
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* ===================== SER12 specific routines =========================
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static inline void ser12_set_divisor(struct net_device *dev,
|
||||
unsigned int divisor)
|
||||
{
|
||||
outb(0x81, LCR(dev->base_addr)); /* DLAB = 1 */
|
||||
outb(divisor, DLL(dev->base_addr));
|
||||
outb(divisor >> 8, DLM(dev->base_addr));
|
||||
outb(0x01, LCR(dev->base_addr)); /* word length = 6 */
|
||||
/*
|
||||
* make sure the next interrupt is generated;
|
||||
* 0 must be used to power the modem; the modem draws its
|
||||
* power from the TxD line
|
||||
*/
|
||||
outb(0x00, THR(dev->base_addr));
|
||||
/*
|
||||
* it is important not to set the divider while transmitting;
|
||||
* this reportedly makes some UARTs generating interrupts
|
||||
* in the hundredthousands per second region
|
||||
* Reported by: Ignacio.Arenaza@studi.epfl.ch (Ignacio Arenaza Nuno)
|
||||
*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#if 0
|
||||
static inline unsigned int hweight16(unsigned int w)
|
||||
__attribute__ ((unused));
|
||||
static inline unsigned int hweight8(unsigned int w)
|
||||
__attribute__ ((unused));
|
||||
|
||||
static inline unsigned int hweight16(unsigned int w)
|
||||
{
|
||||
unsigned short res = (w & 0x5555) + ((w >> 1) & 0x5555);
|
||||
res = (res & 0x3333) + ((res >> 2) & 0x3333);
|
||||
res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
|
||||
return (res & 0x00FF) + ((res >> 8) & 0x00FF);
|
||||
}
|
||||
|
||||
static inline unsigned int hweight8(unsigned int w)
|
||||
{
|
||||
unsigned short res = (w & 0x55) + ((w >> 1) & 0x55);
|
||||
res = (res & 0x33) + ((res >> 2) & 0x33);
|
||||
return (res & 0x0F) + ((res >> 4) & 0x0F);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static __inline__ void ser12_rx(struct net_device *dev, struct baycom_state *bc, struct timeval *tv, unsigned char curs)
|
||||
{
|
||||
int timediff;
|
||||
int bdus8 = bc->baud_us >> 3;
|
||||
int bdus4 = bc->baud_us >> 2;
|
||||
int bdus2 = bc->baud_us >> 1;
|
||||
|
||||
timediff = 1000000 + tv->tv_usec - bc->modem.ser12.pll_time;
|
||||
while (timediff >= 500000)
|
||||
timediff -= 1000000;
|
||||
while (timediff >= bdus2) {
|
||||
timediff -= bc->baud_us;
|
||||
bc->modem.ser12.pll_time += bc->baud_us;
|
||||
bc->modem.ser12.dcd_time--;
|
||||
/* first check if there is room to add a bit */
|
||||
if (bc->modem.shreg & 1) {
|
||||
hdlcdrv_putbits(&bc->hdrv, (bc->modem.shreg >> 1) ^ 0xffff);
|
||||
bc->modem.shreg = 0x10000;
|
||||
}
|
||||
/* add a one bit */
|
||||
bc->modem.shreg >>= 1;
|
||||
}
|
||||
if (bc->modem.ser12.dcd_time <= 0) {
|
||||
if (!bc->opt_dcd)
|
||||
hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
|
||||
bc->modem.ser12.dcd_sum1 +
|
||||
bc->modem.ser12.dcd_sum2) < 0);
|
||||
bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
|
||||
bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
|
||||
bc->modem.ser12.dcd_sum0 = 2; /* slight bias */
|
||||
bc->modem.ser12.dcd_time += 120;
|
||||
}
|
||||
if (bc->modem.ser12.last_rxbit != curs) {
|
||||
bc->modem.ser12.last_rxbit = curs;
|
||||
bc->modem.shreg |= 0x10000;
|
||||
/* adjust the PLL */
|
||||
if (timediff > 0)
|
||||
bc->modem.ser12.pll_time += bdus8;
|
||||
else
|
||||
bc->modem.ser12.pll_time += 1000000 - bdus8;
|
||||
/* update DCD */
|
||||
if (abs(timediff) > bdus4)
|
||||
bc->modem.ser12.dcd_sum0 += 4;
|
||||
else
|
||||
bc->modem.ser12.dcd_sum0--;
|
||||
#ifdef BAYCOM_DEBUG
|
||||
bc->debug_vals.cur_pllcorr = timediff;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
}
|
||||
while (bc->modem.ser12.pll_time >= 1000000)
|
||||
bc->modem.ser12.pll_time -= 1000000;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
struct timeval tv;
|
||||
unsigned char iir, msr;
|
||||
unsigned int txcount = 0;
|
||||
|
||||
if (!bc || bc->hdrv.magic != HDLCDRV_MAGIC)
|
||||
return IRQ_NONE;
|
||||
/* fast way out for shared irq */
|
||||
if ((iir = inb(IIR(dev->base_addr))) & 1)
|
||||
return IRQ_NONE;
|
||||
/* get current time */
|
||||
do_gettimeofday(&tv);
|
||||
msr = inb(MSR(dev->base_addr));
|
||||
/* delta DCD */
|
||||
if ((msr & 8) && bc->opt_dcd)
|
||||
hdlcdrv_setdcd(&bc->hdrv, !((msr ^ bc->opt_dcd) & 0x80));
|
||||
do {
|
||||
switch (iir & 6) {
|
||||
case 6:
|
||||
inb(LSR(dev->base_addr));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
inb(RBR(dev->base_addr));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/*
|
||||
* make sure the next interrupt is generated;
|
||||
* 0 must be used to power the modem; the modem draws its
|
||||
* power from the TxD line
|
||||
*/
|
||||
outb(0x00, THR(dev->base_addr));
|
||||
baycom_int_freq(bc);
|
||||
txcount++;
|
||||
/*
|
||||
* first output the last bit (!) then call HDLC transmitter,
|
||||
* since this may take quite long
|
||||
*/
|
||||
if (bc->modem.ptt)
|
||||
outb(0x0e | (!!bc->modem.ser12.tx_bit), MCR(dev->base_addr));
|
||||
else
|
||||
outb(0x0d, MCR(dev->base_addr)); /* transmitter off */
|
||||
break;
|
||||
|
||||
default:
|
||||
msr = inb(MSR(dev->base_addr));
|
||||
/* delta DCD */
|
||||
if ((msr & 8) && bc->opt_dcd)
|
||||
hdlcdrv_setdcd(&bc->hdrv, !((msr ^ bc->opt_dcd) & 0x80));
|
||||
break;
|
||||
}
|
||||
iir = inb(IIR(dev->base_addr));
|
||||
} while (!(iir & 1));
|
||||
ser12_rx(dev, bc, &tv, msr & 0x10); /* CTS */
|
||||
if (bc->modem.ptt && txcount) {
|
||||
if (bc->modem.ser12.txshreg <= 1) {
|
||||
bc->modem.ser12.txshreg = 0x10000 | hdlcdrv_getbits(&bc->hdrv);
|
||||
if (!hdlcdrv_ptt(&bc->hdrv)) {
|
||||
ser12_set_divisor(dev, 115200/100/8);
|
||||
bc->modem.ptt = 0;
|
||||
goto end_transmit;
|
||||
}
|
||||
}
|
||||
bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^ (bc->modem.ser12.txshreg & 1));
|
||||
bc->modem.ser12.txshreg >>= 1;
|
||||
}
|
||||
end_transmit:
|
||||
local_irq_enable();
|
||||
if (!bc->modem.ptt && txcount) {
|
||||
hdlcdrv_arbitrate(dev, &bc->hdrv);
|
||||
if (hdlcdrv_ptt(&bc->hdrv)) {
|
||||
ser12_set_divisor(dev, bc->baud_uartdiv);
|
||||
bc->modem.ser12.txshreg = 1;
|
||||
bc->modem.ptt = 1;
|
||||
}
|
||||
}
|
||||
hdlcdrv_transmitter(dev, &bc->hdrv);
|
||||
hdlcdrv_receiver(dev, &bc->hdrv);
|
||||
local_irq_disable();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
enum uart { c_uart_unknown, c_uart_8250,
|
||||
c_uart_16450, c_uart_16550, c_uart_16550A};
|
||||
static const char *uart_str[] = {
|
||||
"unknown", "8250", "16450", "16550", "16550A"
|
||||
};
|
||||
|
||||
static enum uart ser12_check_uart(unsigned int iobase)
|
||||
{
|
||||
unsigned char b1,b2,b3;
|
||||
enum uart u;
|
||||
enum uart uart_tab[] =
|
||||
{ c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
|
||||
|
||||
b1 = inb(MCR(iobase));
|
||||
outb(b1 | 0x10, MCR(iobase)); /* loopback mode */
|
||||
b2 = inb(MSR(iobase));
|
||||
outb(0x1a, MCR(iobase));
|
||||
b3 = inb(MSR(iobase)) & 0xf0;
|
||||
outb(b1, MCR(iobase)); /* restore old values */
|
||||
outb(b2, MSR(iobase));
|
||||
if (b3 != 0x90)
|
||||
return c_uart_unknown;
|
||||
inb(RBR(iobase));
|
||||
inb(RBR(iobase));
|
||||
outb(0x01, FCR(iobase)); /* enable FIFOs */
|
||||
u = uart_tab[(inb(IIR(iobase)) >> 6) & 3];
|
||||
if (u == c_uart_16450) {
|
||||
outb(0x5a, SCR(iobase));
|
||||
b1 = inb(SCR(iobase));
|
||||
outb(0xa5, SCR(iobase));
|
||||
b2 = inb(SCR(iobase));
|
||||
if ((b1 != 0x5a) || (b2 != 0xa5))
|
||||
u = c_uart_8250;
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int ser12_open(struct net_device *dev)
|
||||
{
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
enum uart u;
|
||||
|
||||
if (!dev || !bc)
|
||||
return -ENXIO;
|
||||
if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT ||
|
||||
dev->irq < 2 || dev->irq > 15)
|
||||
return -ENXIO;
|
||||
if (bc->baud < 300 || bc->baud > 4800)
|
||||
return -EINVAL;
|
||||
if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser_fdx")) {
|
||||
printk(KERN_WARNING "BAYCOM_SER_FSX: I/O port 0x%04lx busy \n",
|
||||
dev->base_addr);
|
||||
return -EACCES;
|
||||
}
|
||||
memset(&bc->modem, 0, sizeof(bc->modem));
|
||||
bc->hdrv.par.bitrate = bc->baud;
|
||||
bc->baud_us = 1000000/bc->baud;
|
||||
bc->baud_uartdiv = (115200/8)/bc->baud;
|
||||
if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown){
|
||||
release_region(dev->base_addr, SER12_EXTENT);
|
||||
return -EIO;
|
||||
}
|
||||
outb(0, FCR(dev->base_addr)); /* disable FIFOs */
|
||||
outb(0x0d, MCR(dev->base_addr));
|
||||
outb(0, IER(dev->base_addr));
|
||||
if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT | SA_SHIRQ,
|
||||
"baycom_ser_fdx", dev)) {
|
||||
release_region(dev->base_addr, SER12_EXTENT);
|
||||
return -EBUSY;
|
||||
}
|
||||
/*
|
||||
* set the SIO to 6 Bits/character; during receive,
|
||||
* the baud rate is set to produce 100 ints/sec
|
||||
* to feed the channel arbitration process,
|
||||
* during transmit to baud ints/sec to run
|
||||
* the transmitter
|
||||
*/
|
||||
ser12_set_divisor(dev, 115200/100/8);
|
||||
/*
|
||||
* enable transmitter empty interrupt and modem status interrupt
|
||||
*/
|
||||
outb(0x0a, IER(dev->base_addr));
|
||||
/*
|
||||
* make sure the next interrupt is generated;
|
||||
* 0 must be used to power the modem; the modem draws its
|
||||
* power from the TxD line
|
||||
*/
|
||||
outb(0x00, THR(dev->base_addr));
|
||||
hdlcdrv_setdcd(&bc->hdrv, 0);
|
||||
printk(KERN_INFO "%s: ser_fdx at iobase 0x%lx irq %u baud %u uart %s\n",
|
||||
bc_drvname, dev->base_addr, dev->irq, bc->baud, uart_str[u]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int ser12_close(struct net_device *dev)
|
||||
{
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
|
||||
if (!dev || !bc)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* disable interrupts
|
||||
*/
|
||||
outb(0, IER(dev->base_addr));
|
||||
outb(1, MCR(dev->base_addr));
|
||||
free_irq(dev->irq, dev);
|
||||
release_region(dev->base_addr, SER12_EXTENT);
|
||||
printk(KERN_INFO "%s: close ser_fdx at iobase 0x%lx irq %u\n",
|
||||
bc_drvname, dev->base_addr, dev->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* ===================== hdlcdrv driver interface =========================
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||
struct hdlcdrv_ioctl *hi, int cmd);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct hdlcdrv_ops ser12_ops = {
|
||||
.drvname = bc_drvname,
|
||||
.drvinfo = bc_drvinfo,
|
||||
.open = ser12_open,
|
||||
.close = ser12_close,
|
||||
.ioctl = baycom_ioctl,
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_setmode(struct baycom_state *bc, const char *modestr)
|
||||
{
|
||||
unsigned int baud;
|
||||
|
||||
if (!strncmp(modestr, "ser", 3)) {
|
||||
baud = simple_strtoul(modestr+3, NULL, 10);
|
||||
if (baud >= 3 && baud <= 48)
|
||||
bc->baud = baud*100;
|
||||
}
|
||||
if (strchr(modestr, '*'))
|
||||
bc->opt_dcd = 0;
|
||||
else if (strchr(modestr, '+'))
|
||||
bc->opt_dcd = -1;
|
||||
else
|
||||
bc->opt_dcd = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||
struct hdlcdrv_ioctl *hi, int cmd)
|
||||
{
|
||||
struct baycom_state *bc;
|
||||
struct baycom_ioctl bi;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
bc = netdev_priv(dev);
|
||||
BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
|
||||
|
||||
if (cmd != SIOCDEVPRIVATE)
|
||||
return -ENOIOCTLCMD;
|
||||
switch (hi->cmd) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case HDLCDRVCTL_GETMODE:
|
||||
sprintf(hi->data.modename, "ser%u", bc->baud / 100);
|
||||
if (bc->opt_dcd <= 0)
|
||||
strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : "+");
|
||||
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_SETMODE:
|
||||
if (netif_running(dev) || !capable(CAP_NET_ADMIN))
|
||||
return -EACCES;
|
||||
hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
|
||||
return baycom_setmode(bc, hi->data.modename);
|
||||
|
||||
case HDLCDRVCTL_MODELIST:
|
||||
strcpy(hi->data.modename, "ser12,ser3,ser24");
|
||||
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_MODEMPARMASK:
|
||||
return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ;
|
||||
|
||||
}
|
||||
|
||||
if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
switch (bi.cmd) {
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
#ifdef BAYCOM_DEBUG
|
||||
case BAYCOMCTL_GETDEBUG:
|
||||
bi.data.dbg.debug1 = bc->hdrv.ptt_keyed;
|
||||
bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
|
||||
bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
|
||||
break;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
|
||||
}
|
||||
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* command line settable parameters
|
||||
*/
|
||||
static char *mode[NR_PORTS] = { "ser12*", };
|
||||
static int iobase[NR_PORTS] = { 0x3f8, };
|
||||
static int irq[NR_PORTS] = { 4, };
|
||||
static int baud[NR_PORTS] = { [0 ... NR_PORTS-1] = 1200 };
|
||||
|
||||
module_param_array(mode, charp, NULL, 0);
|
||||
MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
|
||||
module_param_array(iobase, int, NULL, 0);
|
||||
MODULE_PARM_DESC(iobase, "baycom io base address");
|
||||
module_param_array(irq, int, NULL, 0);
|
||||
MODULE_PARM_DESC(irq, "baycom irq number");
|
||||
module_param_array(baud, int, NULL, 0);
|
||||
MODULE_PARM_DESC(baud, "baycom baud rate (300 to 4800)");
|
||||
|
||||
MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
|
||||
MODULE_DESCRIPTION("Baycom ser12 full duplex amateur radio modem driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int __init init_baycomserfdx(void)
|
||||
{
|
||||
int i, found = 0;
|
||||
char set_hw = 1;
|
||||
|
||||
printk(bc_drvinfo);
|
||||
/*
|
||||
* register net devices
|
||||
*/
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
struct net_device *dev;
|
||||
struct baycom_state *bc;
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
sprintf(ifname, "bcsf%d", i);
|
||||
|
||||
if (!mode[i])
|
||||
set_hw = 0;
|
||||
if (!set_hw)
|
||||
iobase[i] = irq[i] = 0;
|
||||
|
||||
dev = hdlcdrv_register(&ser12_ops,
|
||||
sizeof(struct baycom_state),
|
||||
ifname, iobase[i], irq[i], 0);
|
||||
if (IS_ERR(dev))
|
||||
break;
|
||||
|
||||
bc = netdev_priv(dev);
|
||||
if (set_hw && baycom_setmode(bc, mode[i]))
|
||||
set_hw = 0;
|
||||
bc->baud = baud[i];
|
||||
found++;
|
||||
baycom_device[i] = dev;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -ENXIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit cleanup_baycomserfdx(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NR_PORTS; i++) {
|
||||
struct net_device *dev = baycom_device[i];
|
||||
if (dev)
|
||||
hdlcdrv_unregister(dev);
|
||||
}
|
||||
}
|
||||
|
||||
module_init(init_baycomserfdx);
|
||||
module_exit(cleanup_baycomserfdx);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#ifndef MODULE
|
||||
|
||||
/*
|
||||
* format: baycom_ser_fdx=io,irq,mode
|
||||
* mode: ser# hardware DCD
|
||||
* ser#* software DCD
|
||||
* ser#+ hardware DCD, inverted signal at DCD pin
|
||||
* '#' denotes the baud rate / 100, eg. ser12* is '1200 baud, soft DCD'
|
||||
*/
|
||||
|
||||
static int __init baycom_ser_fdx_setup(char *str)
|
||||
{
|
||||
static unsigned nr_dev;
|
||||
int ints[4];
|
||||
|
||||
if (nr_dev >= NR_PORTS)
|
||||
return 0;
|
||||
str = get_options(str, 4, ints);
|
||||
if (ints[0] < 2)
|
||||
return 0;
|
||||
mode[nr_dev] = str;
|
||||
iobase[nr_dev] = ints[1];
|
||||
irq[nr_dev] = ints[2];
|
||||
if (ints[0] >= 3)
|
||||
baud[nr_dev] = ints[3];
|
||||
nr_dev++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("baycom_ser_fdx=", baycom_ser_fdx_setup);
|
||||
|
||||
#endif /* MODULE */
|
||||
/* --------------------------------------------------------------------- */
|
740
drivers/net/hamradio/baycom_ser_hdx.c
Normal file
740
drivers/net/hamradio/baycom_ser_hdx.c
Normal file
@@ -0,0 +1,740 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* baycom_ser_hdx.c -- baycom ser12 halfduplex radio modem driver.
|
||||
*
|
||||
* Copyright (C) 1996-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.
|
||||
*
|
||||
*
|
||||
* Supported modems
|
||||
*
|
||||
* ser12: This is a very simple 1200 baud AFSK modem. The modem consists only
|
||||
* of a modulator/demodulator chip, usually a TI TCM3105. The computer
|
||||
* is responsible for regenerating the receiver bit clock, as well as
|
||||
* for handling the HDLC protocol. The modem connects to a serial port,
|
||||
* hence the name. Since the serial port is not used as an async serial
|
||||
* port, the kernel driver for serial ports cannot be used, and this
|
||||
* driver only supports standard serial hardware (8250, 16450, 16550A)
|
||||
*
|
||||
*
|
||||
* Command line options (insmod command line)
|
||||
*
|
||||
* mode ser12 hardware DCD
|
||||
* ser12* software DCD
|
||||
* ser12@ hardware/software DCD, i.e. no explicit DCD signal but hardware
|
||||
* mutes audio input to the modem
|
||||
* ser12+ hardware DCD, inverted signal at DCD pin
|
||||
* iobase base address of the port; common values are 0x3f8, 0x2f8, 0x3e8, 0x2e8
|
||||
* irq interrupt line of the port; common values are 4,3
|
||||
*
|
||||
*
|
||||
* History:
|
||||
* 0.1 26.06.1996 Adapted from baycom.c and made network driver interface
|
||||
* 18.10.1996 Changed to new user space access routines (copy_{to,from}_user)
|
||||
* 0.3 26.04.1997 init code/data tagged
|
||||
* 0.4 08.07.1997 alternative ser12 decoding algorithm (uses delta CTS ints)
|
||||
* 0.5 11.11.1997 ser12/par96 split into separate files
|
||||
* 0.6 14.04.1998 cleanups
|
||||
* 0.7 03.08.1999 adapt to Linus' new __setup/__initcall
|
||||
* 0.8 10.08.1999 use module_init/module_exit
|
||||
* 0.9 12.02.2000 adapted to softnet driver interface
|
||||
* 0.10 03.07.2000 fix interface name handling
|
||||
*/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/hdlcdrv.h>
|
||||
#include <linux/baycom.h>
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define BAYCOM_DEBUG
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static const char bc_drvname[] = "baycom_ser_hdx";
|
||||
static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
|
||||
KERN_INFO "baycom_ser_hdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define NR_PORTS 4
|
||||
|
||||
static struct net_device *baycom_device[NR_PORTS];
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define RBR(iobase) (iobase+0)
|
||||
#define THR(iobase) (iobase+0)
|
||||
#define IER(iobase) (iobase+1)
|
||||
#define IIR(iobase) (iobase+2)
|
||||
#define FCR(iobase) (iobase+2)
|
||||
#define LCR(iobase) (iobase+3)
|
||||
#define MCR(iobase) (iobase+4)
|
||||
#define LSR(iobase) (iobase+5)
|
||||
#define MSR(iobase) (iobase+6)
|
||||
#define SCR(iobase) (iobase+7)
|
||||
#define DLL(iobase) (iobase+0)
|
||||
#define DLM(iobase) (iobase+1)
|
||||
|
||||
#define SER12_EXTENT 8
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* Information that need to be kept for each board.
|
||||
*/
|
||||
|
||||
struct baycom_state {
|
||||
struct hdlcdrv_state hdrv;
|
||||
|
||||
int opt_dcd;
|
||||
|
||||
struct modem_state {
|
||||
short arb_divider;
|
||||
unsigned char flags;
|
||||
unsigned int shreg;
|
||||
struct modem_state_ser12 {
|
||||
unsigned char tx_bit;
|
||||
int dcd_sum0, dcd_sum1, dcd_sum2;
|
||||
unsigned char last_sample;
|
||||
unsigned char last_rxbit;
|
||||
unsigned int dcd_shreg;
|
||||
unsigned int dcd_time;
|
||||
unsigned int bit_pll;
|
||||
unsigned char interm_sample;
|
||||
} ser12;
|
||||
} modem;
|
||||
|
||||
#ifdef BAYCOM_DEBUG
|
||||
struct debug_vals {
|
||||
unsigned long last_jiffies;
|
||||
unsigned cur_intcnt;
|
||||
unsigned last_intcnt;
|
||||
int cur_pllcorr;
|
||||
int last_pllcorr;
|
||||
} debug_vals;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static inline void baycom_int_freq(struct baycom_state *bc)
|
||||
{
|
||||
#ifdef BAYCOM_DEBUG
|
||||
unsigned long cur_jiffies = jiffies;
|
||||
/*
|
||||
* measure the interrupt frequency
|
||||
*/
|
||||
bc->debug_vals.cur_intcnt++;
|
||||
if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) {
|
||||
bc->debug_vals.last_jiffies = cur_jiffies;
|
||||
bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt;
|
||||
bc->debug_vals.cur_intcnt = 0;
|
||||
bc->debug_vals.last_pllcorr = bc->debug_vals.cur_pllcorr;
|
||||
bc->debug_vals.cur_pllcorr = 0;
|
||||
}
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* ===================== SER12 specific routines =========================
|
||||
*/
|
||||
|
||||
static inline void ser12_set_divisor(struct net_device *dev,
|
||||
unsigned char divisor)
|
||||
{
|
||||
outb(0x81, LCR(dev->base_addr)); /* DLAB = 1 */
|
||||
outb(divisor, DLL(dev->base_addr));
|
||||
outb(0, DLM(dev->base_addr));
|
||||
outb(0x01, LCR(dev->base_addr)); /* word length = 6 */
|
||||
/*
|
||||
* make sure the next interrupt is generated;
|
||||
* 0 must be used to power the modem; the modem draws its
|
||||
* power from the TxD line
|
||||
*/
|
||||
outb(0x00, THR(dev->base_addr));
|
||||
/*
|
||||
* it is important not to set the divider while transmitting;
|
||||
* this reportedly makes some UARTs generating interrupts
|
||||
* in the hundredthousands per second region
|
||||
* Reported by: Ignacio.Arenaza@studi.epfl.ch (Ignacio Arenaza Nuno)
|
||||
*/
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* must call the TX arbitrator every 10ms
|
||||
*/
|
||||
#define SER12_ARB_DIVIDER(bc) (bc->opt_dcd ? 24 : 36)
|
||||
|
||||
#define SER12_DCD_INTERVAL(bc) (bc->opt_dcd ? 12 : 240)
|
||||
|
||||
static inline void ser12_tx(struct net_device *dev, struct baycom_state *bc)
|
||||
{
|
||||
/* one interrupt per channel bit */
|
||||
ser12_set_divisor(dev, 12);
|
||||
/*
|
||||
* first output the last bit (!) then call HDLC transmitter,
|
||||
* since this may take quite long
|
||||
*/
|
||||
outb(0x0e | (!!bc->modem.ser12.tx_bit), MCR(dev->base_addr));
|
||||
if (bc->modem.shreg <= 1)
|
||||
bc->modem.shreg = 0x10000 | hdlcdrv_getbits(&bc->hdrv);
|
||||
bc->modem.ser12.tx_bit = !(bc->modem.ser12.tx_bit ^
|
||||
(bc->modem.shreg & 1));
|
||||
bc->modem.shreg >>= 1;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static inline void ser12_rx(struct net_device *dev, struct baycom_state *bc)
|
||||
{
|
||||
unsigned char cur_s;
|
||||
/*
|
||||
* do demodulator
|
||||
*/
|
||||
cur_s = inb(MSR(dev->base_addr)) & 0x10; /* the CTS line */
|
||||
hdlcdrv_channelbit(&bc->hdrv, cur_s);
|
||||
bc->modem.ser12.dcd_shreg = (bc->modem.ser12.dcd_shreg << 1) |
|
||||
(cur_s != bc->modem.ser12.last_sample);
|
||||
bc->modem.ser12.last_sample = cur_s;
|
||||
if(bc->modem.ser12.dcd_shreg & 1) {
|
||||
if (!bc->opt_dcd) {
|
||||
unsigned int dcdspos, dcdsneg;
|
||||
|
||||
dcdspos = dcdsneg = 0;
|
||||
dcdspos += ((bc->modem.ser12.dcd_shreg >> 1) & 1);
|
||||
if (!(bc->modem.ser12.dcd_shreg & 0x7ffffffe))
|
||||
dcdspos += 2;
|
||||
dcdsneg += ((bc->modem.ser12.dcd_shreg >> 2) & 1);
|
||||
dcdsneg += ((bc->modem.ser12.dcd_shreg >> 3) & 1);
|
||||
dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
|
||||
|
||||
bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
|
||||
} else
|
||||
bc->modem.ser12.dcd_sum0--;
|
||||
}
|
||||
if(!bc->modem.ser12.dcd_time) {
|
||||
hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
|
||||
bc->modem.ser12.dcd_sum1 +
|
||||
bc->modem.ser12.dcd_sum2) < 0);
|
||||
bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
|
||||
bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
|
||||
/* offset to ensure DCD off on silent input */
|
||||
bc->modem.ser12.dcd_sum0 = 2;
|
||||
bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc);
|
||||
}
|
||||
bc->modem.ser12.dcd_time--;
|
||||
if (!bc->opt_dcd) {
|
||||
/*
|
||||
* PLL code for the improved software DCD algorithm
|
||||
*/
|
||||
if (bc->modem.ser12.interm_sample) {
|
||||
/*
|
||||
* intermediate sample; set timing correction to normal
|
||||
*/
|
||||
ser12_set_divisor(dev, 4);
|
||||
} else {
|
||||
/*
|
||||
* do PLL correction and call HDLC receiver
|
||||
*/
|
||||
switch (bc->modem.ser12.dcd_shreg & 7) {
|
||||
case 1: /* transition too late */
|
||||
ser12_set_divisor(dev, 5);
|
||||
#ifdef BAYCOM_DEBUG
|
||||
bc->debug_vals.cur_pllcorr++;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
break;
|
||||
case 4: /* transition too early */
|
||||
ser12_set_divisor(dev, 3);
|
||||
#ifdef BAYCOM_DEBUG
|
||||
bc->debug_vals.cur_pllcorr--;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
break;
|
||||
default:
|
||||
ser12_set_divisor(dev, 4);
|
||||
break;
|
||||
}
|
||||
bc->modem.shreg >>= 1;
|
||||
if (bc->modem.ser12.last_sample ==
|
||||
bc->modem.ser12.last_rxbit)
|
||||
bc->modem.shreg |= 0x10000;
|
||||
bc->modem.ser12.last_rxbit =
|
||||
bc->modem.ser12.last_sample;
|
||||
}
|
||||
if (++bc->modem.ser12.interm_sample >= 3)
|
||||
bc->modem.ser12.interm_sample = 0;
|
||||
/*
|
||||
* DCD stuff
|
||||
*/
|
||||
if (bc->modem.ser12.dcd_shreg & 1) {
|
||||
unsigned int dcdspos, dcdsneg;
|
||||
|
||||
dcdspos = dcdsneg = 0;
|
||||
dcdspos += ((bc->modem.ser12.dcd_shreg >> 1) & 1);
|
||||
dcdspos += (!(bc->modem.ser12.dcd_shreg & 0x7ffffffe))
|
||||
<< 1;
|
||||
dcdsneg += ((bc->modem.ser12.dcd_shreg >> 2) & 1);
|
||||
dcdsneg += ((bc->modem.ser12.dcd_shreg >> 3) & 1);
|
||||
dcdsneg += ((bc->modem.ser12.dcd_shreg >> 4) & 1);
|
||||
|
||||
bc->modem.ser12.dcd_sum0 += 16*dcdspos - dcdsneg;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* PLL algorithm for the hardware squelch DCD algorithm
|
||||
*/
|
||||
if (bc->modem.ser12.interm_sample) {
|
||||
/*
|
||||
* intermediate sample; set timing correction to normal
|
||||
*/
|
||||
ser12_set_divisor(dev, 6);
|
||||
} else {
|
||||
/*
|
||||
* do PLL correction and call HDLC receiver
|
||||
*/
|
||||
switch (bc->modem.ser12.dcd_shreg & 3) {
|
||||
case 1: /* transition too late */
|
||||
ser12_set_divisor(dev, 7);
|
||||
#ifdef BAYCOM_DEBUG
|
||||
bc->debug_vals.cur_pllcorr++;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
break;
|
||||
case 2: /* transition too early */
|
||||
ser12_set_divisor(dev, 5);
|
||||
#ifdef BAYCOM_DEBUG
|
||||
bc->debug_vals.cur_pllcorr--;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
break;
|
||||
default:
|
||||
ser12_set_divisor(dev, 6);
|
||||
break;
|
||||
}
|
||||
bc->modem.shreg >>= 1;
|
||||
if (bc->modem.ser12.last_sample ==
|
||||
bc->modem.ser12.last_rxbit)
|
||||
bc->modem.shreg |= 0x10000;
|
||||
bc->modem.ser12.last_rxbit =
|
||||
bc->modem.ser12.last_sample;
|
||||
}
|
||||
bc->modem.ser12.interm_sample = !bc->modem.ser12.interm_sample;
|
||||
/*
|
||||
* DCD stuff
|
||||
*/
|
||||
bc->modem.ser12.dcd_sum0 -= (bc->modem.ser12.dcd_shreg & 1);
|
||||
}
|
||||
outb(0x0d, MCR(dev->base_addr)); /* transmitter off */
|
||||
if (bc->modem.shreg & 1) {
|
||||
hdlcdrv_putbits(&bc->hdrv, bc->modem.shreg >> 1);
|
||||
bc->modem.shreg = 0x10000;
|
||||
}
|
||||
if(!bc->modem.ser12.dcd_time) {
|
||||
if (bc->opt_dcd & 1)
|
||||
hdlcdrv_setdcd(&bc->hdrv, !((inb(MSR(dev->base_addr)) ^ bc->opt_dcd) & 0x80));
|
||||
else
|
||||
hdlcdrv_setdcd(&bc->hdrv, (bc->modem.ser12.dcd_sum0 +
|
||||
bc->modem.ser12.dcd_sum1 +
|
||||
bc->modem.ser12.dcd_sum2) < 0);
|
||||
bc->modem.ser12.dcd_sum2 = bc->modem.ser12.dcd_sum1;
|
||||
bc->modem.ser12.dcd_sum1 = bc->modem.ser12.dcd_sum0;
|
||||
/* offset to ensure DCD off on silent input */
|
||||
bc->modem.ser12.dcd_sum0 = 2;
|
||||
bc->modem.ser12.dcd_time = SER12_DCD_INTERVAL(bc);
|
||||
}
|
||||
bc->modem.ser12.dcd_time--;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static irqreturn_t ser12_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)dev_id;
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
unsigned char iir;
|
||||
|
||||
if (!dev || !bc || bc->hdrv.magic != HDLCDRV_MAGIC)
|
||||
return IRQ_NONE;
|
||||
/* fast way out */
|
||||
if ((iir = inb(IIR(dev->base_addr))) & 1)
|
||||
return IRQ_NONE;
|
||||
baycom_int_freq(bc);
|
||||
do {
|
||||
switch (iir & 6) {
|
||||
case 6:
|
||||
inb(LSR(dev->base_addr));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
inb(RBR(dev->base_addr));
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/*
|
||||
* check if transmitter active
|
||||
*/
|
||||
if (hdlcdrv_ptt(&bc->hdrv))
|
||||
ser12_tx(dev, bc);
|
||||
else {
|
||||
ser12_rx(dev, bc);
|
||||
bc->modem.arb_divider--;
|
||||
}
|
||||
outb(0x00, THR(dev->base_addr));
|
||||
break;
|
||||
|
||||
default:
|
||||
inb(MSR(dev->base_addr));
|
||||
break;
|
||||
}
|
||||
iir = inb(IIR(dev->base_addr));
|
||||
} while (!(iir & 1));
|
||||
if (bc->modem.arb_divider <= 0) {
|
||||
bc->modem.arb_divider = SER12_ARB_DIVIDER(bc);
|
||||
local_irq_enable();
|
||||
hdlcdrv_arbitrate(dev, &bc->hdrv);
|
||||
}
|
||||
local_irq_enable();
|
||||
hdlcdrv_transmitter(dev, &bc->hdrv);
|
||||
hdlcdrv_receiver(dev, &bc->hdrv);
|
||||
local_irq_disable();
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
enum uart { c_uart_unknown, c_uart_8250,
|
||||
c_uart_16450, c_uart_16550, c_uart_16550A};
|
||||
static const char *uart_str[] = {
|
||||
"unknown", "8250", "16450", "16550", "16550A"
|
||||
};
|
||||
|
||||
static enum uart ser12_check_uart(unsigned int iobase)
|
||||
{
|
||||
unsigned char b1,b2,b3;
|
||||
enum uart u;
|
||||
enum uart uart_tab[] =
|
||||
{ c_uart_16450, c_uart_unknown, c_uart_16550, c_uart_16550A };
|
||||
|
||||
b1 = inb(MCR(iobase));
|
||||
outb(b1 | 0x10, MCR(iobase)); /* loopback mode */
|
||||
b2 = inb(MSR(iobase));
|
||||
outb(0x1a, MCR(iobase));
|
||||
b3 = inb(MSR(iobase)) & 0xf0;
|
||||
outb(b1, MCR(iobase)); /* restore old values */
|
||||
outb(b2, MSR(iobase));
|
||||
if (b3 != 0x90)
|
||||
return c_uart_unknown;
|
||||
inb(RBR(iobase));
|
||||
inb(RBR(iobase));
|
||||
outb(0x01, FCR(iobase)); /* enable FIFOs */
|
||||
u = uart_tab[(inb(IIR(iobase)) >> 6) & 3];
|
||||
if (u == c_uart_16450) {
|
||||
outb(0x5a, SCR(iobase));
|
||||
b1 = inb(SCR(iobase));
|
||||
outb(0xa5, SCR(iobase));
|
||||
b2 = inb(SCR(iobase));
|
||||
if ((b1 != 0x5a) || (b2 != 0xa5))
|
||||
u = c_uart_8250;
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int ser12_open(struct net_device *dev)
|
||||
{
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
enum uart u;
|
||||
|
||||
if (!dev || !bc)
|
||||
return -ENXIO;
|
||||
if (!dev->base_addr || dev->base_addr > 0x1000-SER12_EXTENT ||
|
||||
dev->irq < 2 || dev->irq > 15)
|
||||
return -ENXIO;
|
||||
if (!request_region(dev->base_addr, SER12_EXTENT, "baycom_ser12"))
|
||||
return -EACCES;
|
||||
memset(&bc->modem, 0, sizeof(bc->modem));
|
||||
bc->hdrv.par.bitrate = 1200;
|
||||
if ((u = ser12_check_uart(dev->base_addr)) == c_uart_unknown) {
|
||||
release_region(dev->base_addr, SER12_EXTENT);
|
||||
return -EIO;
|
||||
}
|
||||
outb(0, FCR(dev->base_addr)); /* disable FIFOs */
|
||||
outb(0x0d, MCR(dev->base_addr));
|
||||
outb(0, IER(dev->base_addr));
|
||||
if (request_irq(dev->irq, ser12_interrupt, SA_INTERRUPT | SA_SHIRQ,
|
||||
"baycom_ser12", dev)) {
|
||||
release_region(dev->base_addr, SER12_EXTENT);
|
||||
return -EBUSY;
|
||||
}
|
||||
/*
|
||||
* enable transmitter empty interrupt
|
||||
*/
|
||||
outb(2, IER(dev->base_addr));
|
||||
/*
|
||||
* set the SIO to 6 Bits/character and 19200 or 28800 baud, so that
|
||||
* we get exactly (hopefully) 2 or 3 interrupts per radio symbol,
|
||||
* depending on the usage of the software DCD routine
|
||||
*/
|
||||
ser12_set_divisor(dev, bc->opt_dcd ? 6 : 4);
|
||||
printk(KERN_INFO "%s: ser12 at iobase 0x%lx irq %u uart %s\n",
|
||||
bc_drvname, dev->base_addr, dev->irq, uart_str[u]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int ser12_close(struct net_device *dev)
|
||||
{
|
||||
struct baycom_state *bc = netdev_priv(dev);
|
||||
|
||||
if (!dev || !bc)
|
||||
return -EINVAL;
|
||||
/*
|
||||
* disable interrupts
|
||||
*/
|
||||
outb(0, IER(dev->base_addr));
|
||||
outb(1, MCR(dev->base_addr));
|
||||
free_irq(dev->irq, dev);
|
||||
release_region(dev->base_addr, SER12_EXTENT);
|
||||
printk(KERN_INFO "%s: close ser12 at iobase 0x%lx irq %u\n",
|
||||
bc_drvname, dev->base_addr, dev->irq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* ===================== hdlcdrv driver interface =========================
|
||||
*/
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||
struct hdlcdrv_ioctl *hi, int cmd);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct hdlcdrv_ops ser12_ops = {
|
||||
.drvname = bc_drvname,
|
||||
.drvinfo = bc_drvinfo,
|
||||
.open = ser12_open,
|
||||
.close = ser12_close,
|
||||
.ioctl = baycom_ioctl,
|
||||
};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_setmode(struct baycom_state *bc, const char *modestr)
|
||||
{
|
||||
if (strchr(modestr, '*'))
|
||||
bc->opt_dcd = 0;
|
||||
else if (strchr(modestr, '+'))
|
||||
bc->opt_dcd = -1;
|
||||
else if (strchr(modestr, '@'))
|
||||
bc->opt_dcd = -2;
|
||||
else
|
||||
bc->opt_dcd = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr,
|
||||
struct hdlcdrv_ioctl *hi, int cmd)
|
||||
{
|
||||
struct baycom_state *bc;
|
||||
struct baycom_ioctl bi;
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
bc = netdev_priv(dev);
|
||||
BUG_ON(bc->hdrv.magic != HDLCDRV_MAGIC);
|
||||
|
||||
if (cmd != SIOCDEVPRIVATE)
|
||||
return -ENOIOCTLCMD;
|
||||
switch (hi->cmd) {
|
||||
default:
|
||||
break;
|
||||
|
||||
case HDLCDRVCTL_GETMODE:
|
||||
strcpy(hi->data.modename, "ser12");
|
||||
if (bc->opt_dcd <= 0)
|
||||
strcat(hi->data.modename, (!bc->opt_dcd) ? "*" : (bc->opt_dcd == -2) ? "@" : "+");
|
||||
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_SETMODE:
|
||||
if (netif_running(dev) || !capable(CAP_NET_ADMIN))
|
||||
return -EACCES;
|
||||
hi->data.modename[sizeof(hi->data.modename)-1] = '\0';
|
||||
return baycom_setmode(bc, hi->data.modename);
|
||||
|
||||
case HDLCDRVCTL_MODELIST:
|
||||
strcpy(hi->data.modename, "ser12");
|
||||
if (copy_to_user(ifr->ifr_data, hi, sizeof(struct hdlcdrv_ioctl)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_MODEMPARMASK:
|
||||
return HDLCDRV_PARMASK_IOBASE | HDLCDRV_PARMASK_IRQ;
|
||||
|
||||
}
|
||||
|
||||
if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
switch (bi.cmd) {
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
#ifdef BAYCOM_DEBUG
|
||||
case BAYCOMCTL_GETDEBUG:
|
||||
bi.data.dbg.debug1 = bc->hdrv.ptt_keyed;
|
||||
bi.data.dbg.debug2 = bc->debug_vals.last_intcnt;
|
||||
bi.data.dbg.debug3 = bc->debug_vals.last_pllcorr;
|
||||
break;
|
||||
#endif /* BAYCOM_DEBUG */
|
||||
|
||||
}
|
||||
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* command line settable parameters
|
||||
*/
|
||||
static char *mode[NR_PORTS] = { "ser12*", };
|
||||
static int iobase[NR_PORTS] = { 0x3f8, };
|
||||
static int irq[NR_PORTS] = { 4, };
|
||||
|
||||
module_param_array(mode, charp, NULL, 0);
|
||||
MODULE_PARM_DESC(mode, "baycom operating mode; * for software DCD");
|
||||
module_param_array(iobase, int, NULL, 0);
|
||||
MODULE_PARM_DESC(iobase, "baycom io base address");
|
||||
module_param_array(irq, int, NULL, 0);
|
||||
MODULE_PARM_DESC(irq, "baycom irq number");
|
||||
|
||||
MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
|
||||
MODULE_DESCRIPTION("Baycom ser12 half duplex amateur radio modem driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int __init init_baycomserhdx(void)
|
||||
{
|
||||
int i, found = 0;
|
||||
char set_hw = 1;
|
||||
|
||||
printk(bc_drvinfo);
|
||||
/*
|
||||
* register net devices
|
||||
*/
|
||||
for (i = 0; i < NR_PORTS; i++) {
|
||||
struct net_device *dev;
|
||||
struct baycom_state *bc;
|
||||
char ifname[IFNAMSIZ];
|
||||
|
||||
sprintf(ifname, "bcsh%d", i);
|
||||
|
||||
if (!mode[i])
|
||||
set_hw = 0;
|
||||
if (!set_hw)
|
||||
iobase[i] = irq[i] = 0;
|
||||
|
||||
dev = hdlcdrv_register(&ser12_ops,
|
||||
sizeof(struct baycom_state),
|
||||
ifname, iobase[i], irq[i], 0);
|
||||
if (IS_ERR(dev))
|
||||
break;
|
||||
|
||||
bc = netdev_priv(dev);
|
||||
if (set_hw && baycom_setmode(bc, mode[i]))
|
||||
set_hw = 0;
|
||||
found++;
|
||||
baycom_device[i] = dev;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
return -ENXIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit cleanup_baycomserhdx(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < NR_PORTS; i++) {
|
||||
struct net_device *dev = baycom_device[i];
|
||||
|
||||
if (dev)
|
||||
hdlcdrv_unregister(dev);
|
||||
}
|
||||
}
|
||||
|
||||
module_init(init_baycomserhdx);
|
||||
module_exit(cleanup_baycomserhdx);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#ifndef MODULE
|
||||
|
||||
/*
|
||||
* format: baycom_ser_hdx=io,irq,mode
|
||||
* mode: ser12 hardware DCD
|
||||
* ser12* software DCD
|
||||
* ser12@ hardware/software DCD, i.e. no explicit DCD signal but hardware
|
||||
* mutes audio input to the modem
|
||||
* ser12+ hardware DCD, inverted signal at DCD pin
|
||||
*/
|
||||
|
||||
static int __init baycom_ser_hdx_setup(char *str)
|
||||
{
|
||||
static unsigned nr_dev;
|
||||
int ints[3];
|
||||
|
||||
if (nr_dev >= NR_PORTS)
|
||||
return 0;
|
||||
str = get_options(str, 3, ints);
|
||||
if (ints[0] < 2)
|
||||
return 0;
|
||||
mode[nr_dev] = str;
|
||||
iobase[nr_dev] = ints[1];
|
||||
irq[nr_dev] = ints[2];
|
||||
nr_dev++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
__setup("baycom_ser_hdx=", baycom_ser_hdx_setup);
|
||||
|
||||
#endif /* MODULE */
|
||||
/* --------------------------------------------------------------------- */
|
643
drivers/net/hamradio/bpqether.c
Normal file
643
drivers/net/hamradio/bpqether.c
Normal file
@@ -0,0 +1,643 @@
|
||||
/*
|
||||
* G8BPQ compatible "AX.25 via ethernet" driver release 004
|
||||
*
|
||||
* This code REQUIRES 2.0.0 or higher/ NET3.029
|
||||
*
|
||||
* This module:
|
||||
* This module 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 is a "pseudo" network driver to allow AX.25 over Ethernet
|
||||
* using G8BPQ encapsulation. It has been extracted from the protocol
|
||||
* implementation because
|
||||
*
|
||||
* - things got unreadable within the protocol stack
|
||||
* - to cure the protocol stack from "feature-ism"
|
||||
* - a protocol implementation shouldn't need to know on
|
||||
* which hardware it is running
|
||||
* - user-level programs like the AX.25 utilities shouldn't
|
||||
* need to know about the hardware.
|
||||
* - IP over ethernet encapsulated AX.25 was impossible
|
||||
* - rxecho.c did not work
|
||||
* - to have room for extensions
|
||||
* - it just deserves to "live" as an own driver
|
||||
*
|
||||
* This driver can use any ethernet destination address, and can be
|
||||
* limited to accept frames from one dedicated ethernet card only.
|
||||
*
|
||||
* Note that the driver sets up the BPQ devices automagically on
|
||||
* startup or (if started before the "insmod" of an ethernet device)
|
||||
* on "ifconfig up". It hopefully will remove the BPQ on "rmmod"ing
|
||||
* the ethernet device (in fact: as soon as another ethernet or bpq
|
||||
* device gets "ifconfig"ured).
|
||||
*
|
||||
* I have heard that several people are thinking of experiments
|
||||
* with highspeed packet radio using existing ethernet cards.
|
||||
* Well, this driver is prepared for this purpose, just add
|
||||
* your tx key control and a txdelay / tailtime algorithm,
|
||||
* probably some buffering, and /voila/...
|
||||
*
|
||||
* History
|
||||
* BPQ 001 Joerg(DL1BKE) Extracted BPQ code from AX.25
|
||||
* protocol stack and added my own
|
||||
* yet existing patches
|
||||
* BPQ 002 Joerg(DL1BKE) Scan network device list on
|
||||
* startup.
|
||||
* BPQ 003 Joerg(DL1BKE) Ethernet destination address
|
||||
* and accepted source address
|
||||
* can be configured by an ioctl()
|
||||
* call.
|
||||
* Fixed to match Linux networking
|
||||
* changes - 2.1.15.
|
||||
* BPQ 004 Joerg(DL1BKE) Fixed to not lock up on ifconfig.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/socket.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/net.h>
|
||||
#include <net/ax25.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <net/sock.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/netfilter.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include <net/ip.h>
|
||||
#include <net/arp.h>
|
||||
|
||||
#include <linux/bpqether.h>
|
||||
|
||||
static char banner[] __initdata = KERN_INFO "AX.25: bpqether driver version 004\n";
|
||||
|
||||
static unsigned char ax25_bcast[AX25_ADDR_LEN] =
|
||||
{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
|
||||
static unsigned char ax25_defaddr[AX25_ADDR_LEN] =
|
||||
{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
|
||||
|
||||
static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
|
||||
|
||||
static char bpq_eth_addr[6];
|
||||
|
||||
static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *);
|
||||
static int bpq_device_event(struct notifier_block *, unsigned long, void *);
|
||||
static const char *bpq_print_ethaddr(const unsigned char *);
|
||||
|
||||
static struct packet_type bpq_packet_type = {
|
||||
.type = __constant_htons(ETH_P_BPQ),
|
||||
.func = bpq_rcv,
|
||||
};
|
||||
|
||||
static struct notifier_block bpq_dev_notifier = {
|
||||
.notifier_call =bpq_device_event,
|
||||
};
|
||||
|
||||
|
||||
struct bpqdev {
|
||||
struct list_head bpq_list; /* list of bpq devices chain */
|
||||
struct net_device *ethdev; /* link to ethernet device */
|
||||
struct net_device *axdev; /* bpq device (bpq#) */
|
||||
struct net_device_stats stats; /* some statistics */
|
||||
char dest_addr[6]; /* ether destination address */
|
||||
char acpt_addr[6]; /* accept ether frames from this address only */
|
||||
};
|
||||
|
||||
static LIST_HEAD(bpq_devices);
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
/*
|
||||
* Get the ethernet device for a BPQ device
|
||||
*/
|
||||
static inline struct net_device *bpq_get_ether_dev(struct net_device *dev)
|
||||
{
|
||||
struct bpqdev *bpq = netdev_priv(dev);
|
||||
|
||||
return bpq ? bpq->ethdev : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the BPQ device for the ethernet device
|
||||
*/
|
||||
static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
|
||||
{
|
||||
struct bpqdev *bpq;
|
||||
|
||||
list_for_each_entry(bpq, &bpq_devices, bpq_list) {
|
||||
if (bpq->ethdev == dev)
|
||||
return bpq->axdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline int dev_is_ethdev(struct net_device *dev)
|
||||
{
|
||||
return (
|
||||
dev->type == ARPHRD_ETHER
|
||||
&& strncmp(dev->name, "dummy", 5)
|
||||
);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
/*
|
||||
* Receive an AX.25 frame via an ethernet interface.
|
||||
*/
|
||||
static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype)
|
||||
{
|
||||
int len;
|
||||
char * ptr;
|
||||
struct ethhdr *eth;
|
||||
struct bpqdev *bpq;
|
||||
|
||||
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
|
||||
return NET_RX_DROP;
|
||||
|
||||
if (!pskb_may_pull(skb, sizeof(struct ethhdr)))
|
||||
goto drop;
|
||||
|
||||
rcu_read_lock();
|
||||
dev = bpq_get_ax25_dev(dev);
|
||||
|
||||
if (dev == NULL || !netif_running(dev))
|
||||
goto drop_unlock;
|
||||
|
||||
/*
|
||||
* if we want to accept frames from just one ethernet device
|
||||
* we check the source address of the sender.
|
||||
*/
|
||||
|
||||
bpq = netdev_priv(dev);
|
||||
|
||||
eth = eth_hdr(skb);
|
||||
|
||||
if (!(bpq->acpt_addr[0] & 0x01) &&
|
||||
memcmp(eth->h_source, bpq->acpt_addr, ETH_ALEN))
|
||||
goto drop_unlock;
|
||||
|
||||
if (skb_cow(skb, sizeof(struct ethhdr)))
|
||||
goto drop_unlock;
|
||||
|
||||
len = skb->data[0] + skb->data[1] * 256 - 5;
|
||||
|
||||
skb_pull(skb, 2); /* Remove the length bytes */
|
||||
skb_trim(skb, len); /* Set the length of the data */
|
||||
|
||||
bpq->stats.rx_packets++;
|
||||
bpq->stats.rx_bytes += len;
|
||||
|
||||
ptr = skb_push(skb, 1);
|
||||
*ptr = 0;
|
||||
|
||||
skb->dev = dev;
|
||||
skb->protocol = htons(ETH_P_AX25);
|
||||
skb->mac.raw = skb->data;
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
|
||||
netif_rx(skb);
|
||||
dev->last_rx = jiffies;
|
||||
unlock:
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
return 0;
|
||||
drop_unlock:
|
||||
kfree_skb(skb);
|
||||
goto unlock;
|
||||
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an AX.25 frame via an ethernet interface
|
||||
*/
|
||||
static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct sk_buff *newskb;
|
||||
unsigned char *ptr;
|
||||
struct bpqdev *bpq;
|
||||
int size;
|
||||
|
||||
/*
|
||||
* Just to be *really* sure not to send anything if the interface
|
||||
* is down, the ethernet device may have gone.
|
||||
*/
|
||||
if (!netif_running(dev)) {
|
||||
kfree_skb(skb);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
skb_pull(skb, 1);
|
||||
size = skb->len;
|
||||
|
||||
/*
|
||||
* The AX.25 code leaves enough room for the ethernet header, but
|
||||
* sendto() does not.
|
||||
*/
|
||||
if (skb_headroom(skb) < AX25_BPQ_HEADER_LEN) { /* Ough! */
|
||||
if ((newskb = skb_realloc_headroom(skb, AX25_BPQ_HEADER_LEN)) == NULL) {
|
||||
printk(KERN_WARNING "bpqether: out of memory\n");
|
||||
kfree_skb(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (skb->sk != NULL)
|
||||
skb_set_owner_w(newskb, skb->sk);
|
||||
|
||||
kfree_skb(skb);
|
||||
skb = newskb;
|
||||
}
|
||||
|
||||
skb->protocol = htons(ETH_P_AX25);
|
||||
|
||||
ptr = skb_push(skb, 2);
|
||||
|
||||
*ptr++ = (size + 5) % 256;
|
||||
*ptr++ = (size + 5) / 256;
|
||||
|
||||
bpq = netdev_priv(dev);
|
||||
|
||||
if ((dev = bpq_get_ether_dev(dev)) == NULL) {
|
||||
bpq->stats.tx_dropped++;
|
||||
kfree_skb(skb);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
skb->dev = dev;
|
||||
skb->nh.raw = skb->data;
|
||||
dev->hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
|
||||
bpq->stats.tx_packets++;
|
||||
bpq->stats.tx_bytes+=skb->len;
|
||||
|
||||
dev_queue_xmit(skb);
|
||||
netif_wake_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Statistics
|
||||
*/
|
||||
static struct net_device_stats *bpq_get_stats(struct net_device *dev)
|
||||
{
|
||||
struct bpqdev *bpq = netdev_priv(dev);
|
||||
|
||||
return &bpq->stats;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set AX.25 callsign
|
||||
*/
|
||||
static int bpq_set_mac_address(struct net_device *dev, void *addr)
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)addr;
|
||||
|
||||
memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ioctl commands
|
||||
*
|
||||
* SIOCSBPQETHOPT reserved for enhancements
|
||||
* SIOCSBPQETHADDR set the destination and accepted
|
||||
* source ethernet address (broadcast
|
||||
* or multicast: accept all)
|
||||
*/
|
||||
static int bpq_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct bpq_ethaddr __user *ethaddr = ifr->ifr_data;
|
||||
struct bpqdev *bpq = netdev_priv(dev);
|
||||
struct bpq_req req;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCSBPQETHOPT:
|
||||
if (copy_from_user(&req, ifr->ifr_data, sizeof(struct bpq_req)))
|
||||
return -EFAULT;
|
||||
switch (req.cmd) {
|
||||
case SIOCGBPQETHPARAM:
|
||||
case SIOCSBPQETHPARAM:
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SIOCSBPQETHADDR:
|
||||
if (copy_from_user(bpq->dest_addr, ethaddr->destination, ETH_ALEN))
|
||||
return -EFAULT;
|
||||
if (copy_from_user(bpq->acpt_addr, ethaddr->accept, ETH_ALEN))
|
||||
return -EFAULT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* open/close a device
|
||||
*/
|
||||
static int bpq_open(struct net_device *dev)
|
||||
{
|
||||
netif_start_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bpq_close(struct net_device *dev)
|
||||
{
|
||||
netif_stop_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
/*
|
||||
* Proc filesystem
|
||||
*/
|
||||
static const char * bpq_print_ethaddr(const unsigned char *e)
|
||||
{
|
||||
static char buf[18];
|
||||
|
||||
sprintf(buf, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
|
||||
e[0], e[1], e[2], e[3], e[4], e[5]);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
|
||||
{
|
||||
int i = 1;
|
||||
struct bpqdev *bpqdev;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
if (*pos == 0)
|
||||
return SEQ_START_TOKEN;
|
||||
|
||||
list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
|
||||
if (i == *pos)
|
||||
return bpqdev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||
{
|
||||
struct list_head *p;
|
||||
|
||||
++*pos;
|
||||
|
||||
if (v == SEQ_START_TOKEN)
|
||||
p = bpq_devices.next;
|
||||
else
|
||||
p = ((struct bpqdev *)v)->bpq_list.next;
|
||||
|
||||
return (p == &bpq_devices) ? NULL
|
||||
: list_entry(p, struct bpqdev, bpq_list);
|
||||
}
|
||||
|
||||
static void bpq_seq_stop(struct seq_file *seq, void *v)
|
||||
{
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
||||
static int bpq_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
if (v == SEQ_START_TOKEN)
|
||||
seq_puts(seq,
|
||||
"dev ether destination accept from\n");
|
||||
else {
|
||||
const struct bpqdev *bpqdev = v;
|
||||
|
||||
seq_printf(seq, "%-5s %-10s %s ",
|
||||
bpqdev->axdev->name, bpqdev->ethdev->name,
|
||||
bpq_print_ethaddr(bpqdev->dest_addr));
|
||||
|
||||
seq_printf(seq, "%s\n",
|
||||
(bpqdev->acpt_addr[0] & 0x01) ? "*"
|
||||
: bpq_print_ethaddr(bpqdev->acpt_addr));
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct seq_operations bpq_seqops = {
|
||||
.start = bpq_seq_start,
|
||||
.next = bpq_seq_next,
|
||||
.stop = bpq_seq_stop,
|
||||
.show = bpq_seq_show,
|
||||
};
|
||||
|
||||
static int bpq_info_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &bpq_seqops);
|
||||
}
|
||||
|
||||
static struct file_operations bpq_info_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = bpq_info_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
static void bpq_setup(struct net_device *dev)
|
||||
{
|
||||
|
||||
dev->hard_start_xmit = bpq_xmit;
|
||||
dev->open = bpq_open;
|
||||
dev->stop = bpq_close;
|
||||
dev->set_mac_address = bpq_set_mac_address;
|
||||
dev->get_stats = bpq_get_stats;
|
||||
dev->do_ioctl = bpq_ioctl;
|
||||
dev->destructor = free_netdev;
|
||||
|
||||
memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
|
||||
memcpy(dev->dev_addr, ax25_defaddr, AX25_ADDR_LEN);
|
||||
|
||||
dev->flags = 0;
|
||||
|
||||
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
|
||||
dev->hard_header = ax25_encapsulate;
|
||||
dev->rebuild_header = ax25_rebuild_header;
|
||||
#endif
|
||||
|
||||
dev->type = ARPHRD_AX25;
|
||||
dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
|
||||
dev->mtu = AX25_DEF_PACLEN;
|
||||
dev->addr_len = AX25_ADDR_LEN;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a new device.
|
||||
*/
|
||||
static int bpq_new_device(struct net_device *edev)
|
||||
{
|
||||
int err;
|
||||
struct net_device *ndev;
|
||||
struct bpqdev *bpq;
|
||||
|
||||
ndev = alloc_netdev(sizeof(struct bpqdev), "bpq%d",
|
||||
bpq_setup);
|
||||
if (!ndev)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
bpq = netdev_priv(ndev);
|
||||
dev_hold(edev);
|
||||
bpq->ethdev = edev;
|
||||
bpq->axdev = ndev;
|
||||
|
||||
memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr));
|
||||
memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr));
|
||||
|
||||
err = dev_alloc_name(ndev, ndev->name);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
err = register_netdevice(ndev);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
/* List protected by RTNL */
|
||||
list_add_rcu(&bpq->bpq_list, &bpq_devices);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
dev_put(edev);
|
||||
free_netdev(ndev);
|
||||
return err;
|
||||
|
||||
}
|
||||
|
||||
static void bpq_free_device(struct net_device *ndev)
|
||||
{
|
||||
struct bpqdev *bpq = netdev_priv(ndev);
|
||||
|
||||
dev_put(bpq->ethdev);
|
||||
list_del_rcu(&bpq->bpq_list);
|
||||
|
||||
unregister_netdevice(ndev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle device status changes.
|
||||
*/
|
||||
static int bpq_device_event(struct notifier_block *this,unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = (struct net_device *)ptr;
|
||||
|
||||
if (!dev_is_ethdev(dev))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_UP: /* new ethernet device -> new BPQ interface */
|
||||
if (bpq_get_ax25_dev(dev) == NULL)
|
||||
bpq_new_device(dev);
|
||||
break;
|
||||
|
||||
case NETDEV_DOWN: /* ethernet device closed -> close BPQ interface */
|
||||
if ((dev = bpq_get_ax25_dev(dev)) != NULL)
|
||||
dev_close(dev);
|
||||
break;
|
||||
|
||||
case NETDEV_UNREGISTER: /* ethernet device removed -> free BPQ interface */
|
||||
if ((dev = bpq_get_ax25_dev(dev)) != NULL)
|
||||
bpq_free_device(dev);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
/*
|
||||
* Initialize driver. To be called from af_ax25 if not compiled as a
|
||||
* module
|
||||
*/
|
||||
static int __init bpq_init_driver(void)
|
||||
{
|
||||
#ifdef CONFIG_PROC_FS
|
||||
if (!proc_net_fops_create("bpqether", S_IRUGO, &bpq_info_fops)) {
|
||||
printk(KERN_ERR
|
||||
"bpq: cannot create /proc/net/bpqether entry.\n");
|
||||
return -ENOENT;
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
dev_add_pack(&bpq_packet_type);
|
||||
|
||||
register_netdevice_notifier(&bpq_dev_notifier);
|
||||
|
||||
printk(banner);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit bpq_cleanup_driver(void)
|
||||
{
|
||||
struct bpqdev *bpq;
|
||||
|
||||
dev_remove_pack(&bpq_packet_type);
|
||||
|
||||
unregister_netdevice_notifier(&bpq_dev_notifier);
|
||||
|
||||
proc_net_remove("bpqether");
|
||||
|
||||
rtnl_lock();
|
||||
while (!list_empty(&bpq_devices)) {
|
||||
bpq = list_entry(bpq_devices.next, struct bpqdev, bpq_list);
|
||||
bpq_free_device(bpq->axdev);
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Joerg Reuter DL1BKE <jreuter@yaina.de>");
|
||||
MODULE_DESCRIPTION("Transmit and receive AX.25 packets over Ethernet");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init(bpq_init_driver);
|
||||
module_exit(bpq_cleanup_driver);
|
1493
drivers/net/hamradio/dmascc.c
Normal file
1493
drivers/net/hamradio/dmascc.c
Normal file
File diff suppressed because it is too large
Load Diff
817
drivers/net/hamradio/hdlcdrv.c
Normal file
817
drivers/net/hamradio/hdlcdrv.c
Normal file
@@ -0,0 +1,817 @@
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* hdlcdrv.c -- HDLC packet radio network driver.
|
||||
*
|
||||
* Copyright (C) 1996-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.
|
||||
*
|
||||
* 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/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/init.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/hdlcdrv.h>
|
||||
/* prototypes for ax25_encapsulate and ax25_rebuild_header */
|
||||
#include <net/ax25.h>
|
||||
|
||||
/* make genksyms happy */
|
||||
#include <linux/ip.h>
|
||||
#include <linux/udp.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/crc-ccitt.h>
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* The name of the card. Is used for messages and in the requests for
|
||||
* io regions, irqs and dma channels
|
||||
*/
|
||||
|
||||
static char ax25_bcast[AX25_ADDR_LEN] =
|
||||
{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
|
||||
static char ax25_nocall[AX25_ADDR_LEN] =
|
||||
{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define KISS_VERBOSE
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
#define PARAM_TXDELAY 1
|
||||
#define PARAM_PERSIST 2
|
||||
#define PARAM_SLOTTIME 3
|
||||
#define PARAM_TXTAIL 4
|
||||
#define PARAM_FULLDUP 5
|
||||
#define PARAM_HARDWARE 6
|
||||
#define PARAM_RETURN 255
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* the CRC routines are stolen from WAMPES
|
||||
* by Dieter Deyke
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static inline void append_crc_ccitt(unsigned char *buffer, int len)
|
||||
{
|
||||
unsigned int crc = crc_ccitt(0xffff, buffer, len) ^ 0xffff;
|
||||
*buffer++ = crc;
|
||||
*buffer++ = crc >> 8;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
|
||||
{
|
||||
return (crc_ccitt(0xffff, buf, cnt) & 0xffff) == 0xf0b8;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#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) ((tenms * s->par.bitrate) / 100 / 16)
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/*
|
||||
* The HDLC routines
|
||||
*/
|
||||
|
||||
static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits,
|
||||
int num)
|
||||
{
|
||||
int added = 0;
|
||||
|
||||
while (s->hdlcrx.rx_state && num >= 8) {
|
||||
if (s->hdlcrx.len >= sizeof(s->hdlcrx.buffer)) {
|
||||
s->hdlcrx.rx_state = 0;
|
||||
return 0;
|
||||
}
|
||||
*s->hdlcrx.bp++ = bits >> (32-num);
|
||||
s->hdlcrx.len++;
|
||||
num -= 8;
|
||||
added += 8;
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int pkt_len;
|
||||
unsigned char *cp;
|
||||
|
||||
if (s->hdlcrx.len < 4)
|
||||
return;
|
||||
if (!check_crc_ccitt(s->hdlcrx.buffer, s->hdlcrx.len))
|
||||
return;
|
||||
pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
|
||||
if (!(skb = dev_alloc_skb(pkt_len))) {
|
||||
printk("%s: memory squeeze, dropping packet\n", dev->name);
|
||||
s->stats.rx_dropped++;
|
||||
return;
|
||||
}
|
||||
skb->dev = dev;
|
||||
cp = skb_put(skb, pkt_len);
|
||||
*cp++ = 0; /* KISS kludge */
|
||||
memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
|
||||
skb->protocol = htons(ETH_P_AX25);
|
||||
skb->mac.raw = skb->data;
|
||||
netif_rx(skb);
|
||||
dev->last_rx = jiffies;
|
||||
s->stats.rx_packets++;
|
||||
}
|
||||
|
||||
void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s)
|
||||
{
|
||||
int i;
|
||||
unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word;
|
||||
|
||||
if (!s || s->magic != HDLCDRV_MAGIC)
|
||||
return;
|
||||
if (test_and_set_bit(0, &s->hdlcrx.in_hdlc_rx))
|
||||
return;
|
||||
|
||||
while (!hdlcdrv_hbuf_empty(&s->hdlcrx.hbuf)) {
|
||||
word = hdlcdrv_hbuf_get(&s->hdlcrx.hbuf);
|
||||
|
||||
#ifdef HDLCDRV_DEBUG
|
||||
hdlcdrv_add_bitbuffer_word(&s->bitbuf_hdlc, word);
|
||||
#endif /* HDLCDRV_DEBUG */
|
||||
s->hdlcrx.bitstream >>= 16;
|
||||
s->hdlcrx.bitstream |= word << 16;
|
||||
s->hdlcrx.bitbuf >>= 16;
|
||||
s->hdlcrx.bitbuf |= word << 16;
|
||||
s->hdlcrx.numbits += 16;
|
||||
for(i = 15, mask1 = 0x1fc00, mask2 = 0x1fe00, mask3 = 0x0fc00,
|
||||
mask4 = 0x1f800, mask5 = 0xf800, mask6 = 0xffff;
|
||||
i >= 0;
|
||||
i--, mask1 <<= 1, mask2 <<= 1, mask3 <<= 1, mask4 <<= 1,
|
||||
mask5 <<= 1, mask6 = (mask6 << 1) | 1) {
|
||||
if ((s->hdlcrx.bitstream & mask1) == mask1)
|
||||
s->hdlcrx.rx_state = 0; /* abort received */
|
||||
else if ((s->hdlcrx.bitstream & mask2) == mask3) {
|
||||
/* flag received */
|
||||
if (s->hdlcrx.rx_state) {
|
||||
hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf
|
||||
<< (8+i),
|
||||
s->hdlcrx.numbits
|
||||
-8-i);
|
||||
hdlc_rx_flag(dev, s);
|
||||
}
|
||||
s->hdlcrx.len = 0;
|
||||
s->hdlcrx.bp = s->hdlcrx.buffer;
|
||||
s->hdlcrx.rx_state = 1;
|
||||
s->hdlcrx.numbits = i;
|
||||
} else if ((s->hdlcrx.bitstream & mask4) == mask5) {
|
||||
/* stuffed bit */
|
||||
s->hdlcrx.numbits--;
|
||||
s->hdlcrx.bitbuf = (s->hdlcrx.bitbuf & (~mask6)) |
|
||||
((s->hdlcrx.bitbuf & mask6) << 1);
|
||||
}
|
||||
}
|
||||
s->hdlcrx.numbits -= hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf,
|
||||
s->hdlcrx.numbits);
|
||||
}
|
||||
clear_bit(0, &s->hdlcrx.in_hdlc_rx);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static inline void do_kiss_params(struct hdlcdrv_state *s,
|
||||
unsigned char *data, unsigned long len)
|
||||
{
|
||||
|
||||
#ifdef KISS_VERBOSE
|
||||
#define PKP(a,b) printk(KERN_INFO "hdlcdrv.c: channel params: " a "\n", b)
|
||||
#else /* KISS_VERBOSE */
|
||||
#define PKP(a,b)
|
||||
#endif /* KISS_VERBOSE */
|
||||
|
||||
if (len < 2)
|
||||
return;
|
||||
switch(data[0]) {
|
||||
case PARAM_TXDELAY:
|
||||
s->ch_params.tx_delay = data[1];
|
||||
PKP("TX delay = %ums", 10 * s->ch_params.tx_delay);
|
||||
break;
|
||||
case PARAM_PERSIST:
|
||||
s->ch_params.ppersist = data[1];
|
||||
PKP("p persistence = %u", s->ch_params.ppersist);
|
||||
break;
|
||||
case PARAM_SLOTTIME:
|
||||
s->ch_params.slottime = data[1];
|
||||
PKP("slot time = %ums", s->ch_params.slottime);
|
||||
break;
|
||||
case PARAM_TXTAIL:
|
||||
s->ch_params.tx_tail = data[1];
|
||||
PKP("TX tail = %ums", s->ch_params.tx_tail);
|
||||
break;
|
||||
case PARAM_FULLDUP:
|
||||
s->ch_params.fulldup = !!data[1];
|
||||
PKP("%s duplex", s->ch_params.fulldup ? "full" : "half");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#undef PKP
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s)
|
||||
{
|
||||
unsigned int mask1, mask2, mask3;
|
||||
int i;
|
||||
struct sk_buff *skb;
|
||||
int pkt_len;
|
||||
|
||||
if (!s || s->magic != HDLCDRV_MAGIC)
|
||||
return;
|
||||
if (test_and_set_bit(0, &s->hdlctx.in_hdlc_tx))
|
||||
return;
|
||||
for (;;) {
|
||||
if (s->hdlctx.numbits >= 16) {
|
||||
if (hdlcdrv_hbuf_full(&s->hdlctx.hbuf)) {
|
||||
clear_bit(0, &s->hdlctx.in_hdlc_tx);
|
||||
return;
|
||||
}
|
||||
hdlcdrv_hbuf_put(&s->hdlctx.hbuf, s->hdlctx.bitbuf);
|
||||
s->hdlctx.bitbuf >>= 16;
|
||||
s->hdlctx.numbits -= 16;
|
||||
}
|
||||
switch (s->hdlctx.tx_state) {
|
||||
default:
|
||||
clear_bit(0, &s->hdlctx.in_hdlc_tx);
|
||||
return;
|
||||
case 0:
|
||||
case 1:
|
||||
if (s->hdlctx.numflags) {
|
||||
s->hdlctx.numflags--;
|
||||
s->hdlctx.bitbuf |=
|
||||
0x7e7e << s->hdlctx.numbits;
|
||||
s->hdlctx.numbits += 16;
|
||||
break;
|
||||
}
|
||||
if (s->hdlctx.tx_state == 1) {
|
||||
clear_bit(0, &s->hdlctx.in_hdlc_tx);
|
||||
return;
|
||||
}
|
||||
if (!(skb = s->skb)) {
|
||||
int flgs = tenms_to_2flags(s, s->ch_params.tx_tail);
|
||||
if (flgs < 2)
|
||||
flgs = 2;
|
||||
s->hdlctx.tx_state = 1;
|
||||
s->hdlctx.numflags = flgs;
|
||||
break;
|
||||
}
|
||||
s->skb = NULL;
|
||||
netif_wake_queue(dev);
|
||||
pkt_len = skb->len-1; /* strip KISS byte */
|
||||
if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
|
||||
s->hdlctx.tx_state = 0;
|
||||
s->hdlctx.numflags = 1;
|
||||
dev_kfree_skb_irq(skb);
|
||||
break;
|
||||
}
|
||||
memcpy(s->hdlctx.buffer, skb->data+1, pkt_len);
|
||||
dev_kfree_skb_irq(skb);
|
||||
s->hdlctx.bp = s->hdlctx.buffer;
|
||||
append_crc_ccitt(s->hdlctx.buffer, pkt_len);
|
||||
s->hdlctx.len = pkt_len+2; /* the appended CRC */
|
||||
s->hdlctx.tx_state = 2;
|
||||
s->hdlctx.bitstream = 0;
|
||||
s->stats.tx_packets++;
|
||||
break;
|
||||
case 2:
|
||||
if (!s->hdlctx.len) {
|
||||
s->hdlctx.tx_state = 0;
|
||||
s->hdlctx.numflags = 1;
|
||||
break;
|
||||
}
|
||||
s->hdlctx.len--;
|
||||
s->hdlctx.bitbuf |= *s->hdlctx.bp <<
|
||||
s->hdlctx.numbits;
|
||||
s->hdlctx.bitstream >>= 8;
|
||||
s->hdlctx.bitstream |= (*s->hdlctx.bp++) << 16;
|
||||
mask1 = 0x1f000;
|
||||
mask2 = 0x10000;
|
||||
mask3 = 0xffffffff >> (31-s->hdlctx.numbits);
|
||||
s->hdlctx.numbits += 8;
|
||||
for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1,
|
||||
mask3 = (mask3 << 1) | 1) {
|
||||
if ((s->hdlctx.bitstream & mask1) != mask1)
|
||||
continue;
|
||||
s->hdlctx.bitstream &= ~mask2;
|
||||
s->hdlctx.bitbuf =
|
||||
(s->hdlctx.bitbuf & mask3) |
|
||||
((s->hdlctx.bitbuf &
|
||||
(~mask3)) << 1);
|
||||
s->hdlctx.numbits++;
|
||||
mask3 = (mask3 << 1) | 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static void start_tx(struct net_device *dev, struct hdlcdrv_state *s)
|
||||
{
|
||||
s->hdlctx.tx_state = 0;
|
||||
s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay);
|
||||
s->hdlctx.bitbuf = s->hdlctx.bitstream = s->hdlctx.numbits = 0;
|
||||
hdlcdrv_transmitter(dev, s);
|
||||
s->hdlctx.ptt = 1;
|
||||
s->ptt_keyed++;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
static unsigned short random_seed;
|
||||
|
||||
static inline unsigned short random_num(void)
|
||||
{
|
||||
random_seed = 28629 * random_seed + 157;
|
||||
return random_seed;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
|
||||
{
|
||||
if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb)
|
||||
return;
|
||||
if (s->ch_params.fulldup) {
|
||||
start_tx(dev, s);
|
||||
return;
|
||||
}
|
||||
if (s->hdlcrx.dcd) {
|
||||
s->hdlctx.slotcnt = s->ch_params.slottime;
|
||||
return;
|
||||
}
|
||||
if ((--s->hdlctx.slotcnt) > 0)
|
||||
return;
|
||||
s->hdlctx.slotcnt = s->ch_params.slottime;
|
||||
if ((random_num() % 256) > s->ch_params.ppersist)
|
||||
return;
|
||||
start_tx(dev, s);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* ===================== network driver interface =========================
|
||||
*/
|
||||
|
||||
static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct hdlcdrv_state *sm = netdev_priv(dev);
|
||||
|
||||
if (skb->data[0] != 0) {
|
||||
do_kiss_params(sm, skb->data, skb->len);
|
||||
dev_kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
if (sm->skb)
|
||||
return -1;
|
||||
netif_stop_queue(dev);
|
||||
sm->skb = skb;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr)
|
||||
{
|
||||
struct sockaddr *sa = (struct sockaddr *)addr;
|
||||
|
||||
/* addr is an AX.25 shifted ASCII mac address */
|
||||
memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev)
|
||||
{
|
||||
struct hdlcdrv_state *sm = netdev_priv(dev);
|
||||
|
||||
/*
|
||||
* Get the current statistics. This may be called with the
|
||||
* card open or closed.
|
||||
*/
|
||||
return &sm->stats;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
struct hdlcdrv_state *s = netdev_priv(dev);
|
||||
int i;
|
||||
|
||||
if (!s->ops || !s->ops->open)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* initialise some variables
|
||||
*/
|
||||
s->opened = 1;
|
||||
s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
|
||||
s->hdlcrx.in_hdlc_rx = 0;
|
||||
s->hdlcrx.rx_state = 0;
|
||||
|
||||
s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
|
||||
s->hdlctx.in_hdlc_tx = 0;
|
||||
s->hdlctx.tx_state = 1;
|
||||
s->hdlctx.numflags = 0;
|
||||
s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
|
||||
s->hdlctx.ptt = 0;
|
||||
s->hdlctx.slotcnt = s->ch_params.slottime;
|
||||
s->hdlctx.calibrate = 0;
|
||||
|
||||
i = s->ops->open(dev);
|
||||
if (i)
|
||||
return i;
|
||||
netif_start_queue(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
/*
|
||||
* The inverse routine to hdlcdrv_open().
|
||||
*/
|
||||
|
||||
static int hdlcdrv_close(struct net_device *dev)
|
||||
{
|
||||
struct hdlcdrv_state *s = netdev_priv(dev);
|
||||
int i = 0;
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
if (s->ops && s->ops->close)
|
||||
i = s->ops->close(dev);
|
||||
if (s->skb)
|
||||
dev_kfree_skb(s->skb);
|
||||
s->skb = NULL;
|
||||
s->opened = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct hdlcdrv_state *s = netdev_priv(dev);
|
||||
struct hdlcdrv_ioctl bi;
|
||||
|
||||
if (cmd != SIOCDEVPRIVATE) {
|
||||
if (s->ops && s->ops->ioctl)
|
||||
return s->ops->ioctl(dev, ifr, &bi, cmd);
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
|
||||
switch (bi.cmd) {
|
||||
default:
|
||||
if (s->ops && s->ops->ioctl)
|
||||
return s->ops->ioctl(dev, ifr, &bi, cmd);
|
||||
return -ENOIOCTLCMD;
|
||||
|
||||
case HDLCDRVCTL_GETCHANNELPAR:
|
||||
bi.data.cp.tx_delay = s->ch_params.tx_delay;
|
||||
bi.data.cp.tx_tail = s->ch_params.tx_tail;
|
||||
bi.data.cp.slottime = s->ch_params.slottime;
|
||||
bi.data.cp.ppersist = s->ch_params.ppersist;
|
||||
bi.data.cp.fulldup = s->ch_params.fulldup;
|
||||
break;
|
||||
|
||||
case HDLCDRVCTL_SETCHANNELPAR:
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EACCES;
|
||||
s->ch_params.tx_delay = bi.data.cp.tx_delay;
|
||||
s->ch_params.tx_tail = bi.data.cp.tx_tail;
|
||||
s->ch_params.slottime = bi.data.cp.slottime;
|
||||
s->ch_params.ppersist = bi.data.cp.ppersist;
|
||||
s->ch_params.fulldup = bi.data.cp.fulldup;
|
||||
s->hdlctx.slotcnt = 1;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_GETMODEMPAR:
|
||||
bi.data.mp.iobase = dev->base_addr;
|
||||
bi.data.mp.irq = dev->irq;
|
||||
bi.data.mp.dma = dev->dma;
|
||||
bi.data.mp.dma2 = s->ptt_out.dma2;
|
||||
bi.data.mp.seriobase = s->ptt_out.seriobase;
|
||||
bi.data.mp.pariobase = s->ptt_out.pariobase;
|
||||
bi.data.mp.midiiobase = s->ptt_out.midiiobase;
|
||||
break;
|
||||
|
||||
case HDLCDRVCTL_SETMODEMPAR:
|
||||
if ((!capable(CAP_SYS_RAWIO)) || netif_running(dev))
|
||||
return -EACCES;
|
||||
dev->base_addr = bi.data.mp.iobase;
|
||||
dev->irq = bi.data.mp.irq;
|
||||
dev->dma = bi.data.mp.dma;
|
||||
s->ptt_out.dma2 = bi.data.mp.dma2;
|
||||
s->ptt_out.seriobase = bi.data.mp.seriobase;
|
||||
s->ptt_out.pariobase = bi.data.mp.pariobase;
|
||||
s->ptt_out.midiiobase = bi.data.mp.midiiobase;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_GETSTAT:
|
||||
bi.data.cs.ptt = hdlcdrv_ptt(s);
|
||||
bi.data.cs.dcd = s->hdlcrx.dcd;
|
||||
bi.data.cs.ptt_keyed = s->ptt_keyed;
|
||||
bi.data.cs.tx_packets = s->stats.tx_packets;
|
||||
bi.data.cs.tx_errors = s->stats.tx_errors;
|
||||
bi.data.cs.rx_packets = s->stats.rx_packets;
|
||||
bi.data.cs.rx_errors = s->stats.rx_errors;
|
||||
break;
|
||||
|
||||
case HDLCDRVCTL_OLDGETSTAT:
|
||||
bi.data.ocs.ptt = hdlcdrv_ptt(s);
|
||||
bi.data.ocs.dcd = s->hdlcrx.dcd;
|
||||
bi.data.ocs.ptt_keyed = s->ptt_keyed;
|
||||
break;
|
||||
|
||||
case HDLCDRVCTL_CALIBRATE:
|
||||
if(!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
|
||||
return 0;
|
||||
|
||||
case HDLCDRVCTL_GETSAMPLES:
|
||||
#ifndef HDLCDRV_DEBUG
|
||||
return -EPERM;
|
||||
#else /* HDLCDRV_DEBUG */
|
||||
if (s->bitbuf_channel.rd == s->bitbuf_channel.wr)
|
||||
return -EAGAIN;
|
||||
bi.data.bits =
|
||||
s->bitbuf_channel.buffer[s->bitbuf_channel.rd];
|
||||
s->bitbuf_channel.rd = (s->bitbuf_channel.rd+1) %
|
||||
sizeof(s->bitbuf_channel.buffer);
|
||||
break;
|
||||
#endif /* HDLCDRV_DEBUG */
|
||||
|
||||
case HDLCDRVCTL_GETBITS:
|
||||
#ifndef HDLCDRV_DEBUG
|
||||
return -EPERM;
|
||||
#else /* HDLCDRV_DEBUG */
|
||||
if (s->bitbuf_hdlc.rd == s->bitbuf_hdlc.wr)
|
||||
return -EAGAIN;
|
||||
bi.data.bits =
|
||||
s->bitbuf_hdlc.buffer[s->bitbuf_hdlc.rd];
|
||||
s->bitbuf_hdlc.rd = (s->bitbuf_hdlc.rd+1) %
|
||||
sizeof(s->bitbuf_hdlc.buffer);
|
||||
break;
|
||||
#endif /* HDLCDRV_DEBUG */
|
||||
|
||||
case HDLCDRVCTL_DRIVERNAME:
|
||||
if (s->ops && s->ops->drvname) {
|
||||
strncpy(bi.data.drivername, s->ops->drvname,
|
||||
sizeof(bi.data.drivername));
|
||||
break;
|
||||
}
|
||||
bi.data.drivername[0] = '\0';
|
||||
break;
|
||||
|
||||
}
|
||||
if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Initialize fields in hdlcdrv
|
||||
*/
|
||||
static void hdlcdrv_setup(struct net_device *dev)
|
||||
{
|
||||
static const struct hdlcdrv_channel_params dflt_ch_params = {
|
||||
20, 2, 10, 40, 0
|
||||
};
|
||||
struct hdlcdrv_state *s = netdev_priv(dev);
|
||||
|
||||
/*
|
||||
* initialize the hdlcdrv_state struct
|
||||
*/
|
||||
s->ch_params = dflt_ch_params;
|
||||
s->ptt_keyed = 0;
|
||||
|
||||
spin_lock_init(&s->hdlcrx.hbuf.lock);
|
||||
s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
|
||||
s->hdlcrx.in_hdlc_rx = 0;
|
||||
s->hdlcrx.rx_state = 0;
|
||||
|
||||
spin_lock_init(&s->hdlctx.hbuf.lock);
|
||||
s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
|
||||
s->hdlctx.in_hdlc_tx = 0;
|
||||
s->hdlctx.tx_state = 1;
|
||||
s->hdlctx.numflags = 0;
|
||||
s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
|
||||
s->hdlctx.ptt = 0;
|
||||
s->hdlctx.slotcnt = s->ch_params.slottime;
|
||||
s->hdlctx.calibrate = 0;
|
||||
|
||||
#ifdef HDLCDRV_DEBUG
|
||||
s->bitbuf_channel.rd = s->bitbuf_channel.wr = 0;
|
||||
s->bitbuf_channel.shreg = 0x80;
|
||||
|
||||
s->bitbuf_hdlc.rd = s->bitbuf_hdlc.wr = 0;
|
||||
s->bitbuf_hdlc.shreg = 0x80;
|
||||
#endif /* HDLCDRV_DEBUG */
|
||||
|
||||
/*
|
||||
* initialize the device struct
|
||||
*/
|
||||
dev->open = hdlcdrv_open;
|
||||
dev->stop = hdlcdrv_close;
|
||||
dev->do_ioctl = hdlcdrv_ioctl;
|
||||
dev->hard_start_xmit = hdlcdrv_send_packet;
|
||||
dev->get_stats = hdlcdrv_get_stats;
|
||||
|
||||
/* Fill in the fields of the device structure */
|
||||
|
||||
s->skb = NULL;
|
||||
|
||||
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
|
||||
dev->hard_header = ax25_encapsulate;
|
||||
dev->rebuild_header = ax25_rebuild_header;
|
||||
#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
|
||||
dev->hard_header = NULL;
|
||||
dev->rebuild_header = NULL;
|
||||
#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
|
||||
dev->set_mac_address = hdlcdrv_set_mac_address;
|
||||
|
||||
dev->type = ARPHRD_AX25; /* AF_AX25 device */
|
||||
dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
|
||||
dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */
|
||||
dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */
|
||||
memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
|
||||
memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN);
|
||||
dev->tx_queue_len = 16;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
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)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct hdlcdrv_state *s;
|
||||
int err;
|
||||
|
||||
BUG_ON(ops == NULL);
|
||||
|
||||
if (privsize < sizeof(struct hdlcdrv_state))
|
||||
privsize = sizeof(struct hdlcdrv_state);
|
||||
|
||||
dev = alloc_netdev(privsize, ifname, hdlcdrv_setup);
|
||||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
/*
|
||||
* initialize part of the hdlcdrv_state struct
|
||||
*/
|
||||
s = netdev_priv(dev);
|
||||
s->magic = HDLCDRV_MAGIC;
|
||||
s->ops = ops;
|
||||
dev->base_addr = baseaddr;
|
||||
dev->irq = irq;
|
||||
dev->dma = dma;
|
||||
|
||||
err = register_netdev(dev);
|
||||
if (err < 0) {
|
||||
printk(KERN_WARNING "hdlcdrv: cannot register net "
|
||||
"device %s\n", dev->name);
|
||||
free_netdev(dev);
|
||||
dev = ERR_PTR(err);
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
void hdlcdrv_unregister(struct net_device *dev)
|
||||
{
|
||||
struct hdlcdrv_state *s = netdev_priv(dev);
|
||||
|
||||
BUG_ON(s->magic != HDLCDRV_MAGIC);
|
||||
|
||||
if (s->opened && s->ops->close)
|
||||
s->ops->close(dev);
|
||||
unregister_netdev(dev);
|
||||
|
||||
free_netdev(dev);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
EXPORT_SYMBOL(hdlcdrv_receiver);
|
||||
EXPORT_SYMBOL(hdlcdrv_transmitter);
|
||||
EXPORT_SYMBOL(hdlcdrv_arbitrate);
|
||||
EXPORT_SYMBOL(hdlcdrv_register);
|
||||
EXPORT_SYMBOL(hdlcdrv_unregister);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static int __init hdlcdrv_init_driver(void)
|
||||
{
|
||||
printk(KERN_INFO "hdlcdrv: (C) 1996-2000 Thomas Sailer HB9JNX/AE4WA\n");
|
||||
printk(KERN_INFO "hdlcdrv: version 0.8 compiled " __TIME__ " " __DATE__ "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static void __exit hdlcdrv_cleanup_driver(void)
|
||||
{
|
||||
printk(KERN_INFO "hdlcdrv: cleanup\n");
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
|
||||
MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init(hdlcdrv_init_driver);
|
||||
module_exit(hdlcdrv_cleanup_driver);
|
||||
|
||||
/* --------------------------------------------------------------------- */
|
951
drivers/net/hamradio/mkiss.c
Normal file
951
drivers/net/hamradio/mkiss.c
Normal file
@@ -0,0 +1,951 @@
|
||||
/*
|
||||
* MKISS Driver
|
||||
*
|
||||
* This module:
|
||||
* This module 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 module implements the AX.25 protocol for kernel-based
|
||||
* devices like TTYs. It interfaces between a raw TTY, and the
|
||||
* kernel's AX.25 protocol layers, just like slip.c.
|
||||
* AX.25 needs to be separated from slip.c while slip.c is no
|
||||
* longer a static kernel device since it is a module.
|
||||
* This method clears the way to implement other kiss protocols
|
||||
* like mkiss smack g8bpq ..... so far only mkiss is implemented.
|
||||
*
|
||||
* Hans Alblas <hans@esrac.ele.tue.nl>
|
||||
*
|
||||
* History
|
||||
* Jonathan (G4KLX) Fixed to match Linux networking changes - 2.1.15.
|
||||
* Matthias (DG2FEF) Added support for FlexNet CRC (on special request)
|
||||
* Fixed bug in ax25_close(): dev_lock_wait() was
|
||||
* called twice, causing a deadlock.
|
||||
* Jeroen (PE1RXQ) Removed old MKISS_MAGIC stuff and calls to
|
||||
* MOD_*_USE_COUNT
|
||||
* Remove cli() and fix rtnl lock usage.
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/system.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/inet.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
#include <net/ax25.h>
|
||||
|
||||
#include "mkiss.h"
|
||||
|
||||
#ifdef CONFIG_INET
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#endif
|
||||
|
||||
static char banner[] __initdata = KERN_INFO "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
|
||||
|
||||
typedef struct ax25_ctrl {
|
||||
struct ax_disp ctrl; /* */
|
||||
struct net_device dev; /* the device */
|
||||
} ax25_ctrl_t;
|
||||
|
||||
static ax25_ctrl_t **ax25_ctrls;
|
||||
|
||||
int ax25_maxdev = AX25_MAXDEV; /* Can be overridden with insmod! */
|
||||
|
||||
static struct tty_ldisc ax_ldisc;
|
||||
|
||||
static int ax25_init(struct net_device *);
|
||||
static int kiss_esc(unsigned char *, unsigned char *, int);
|
||||
static int kiss_esc_crc(unsigned char *, unsigned char *, unsigned short, int);
|
||||
static void kiss_unesc(struct ax_disp *, unsigned char);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static const unsigned short Crc_flex_table[] = {
|
||||
0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
|
||||
0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770,
|
||||
0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9,
|
||||
0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1,
|
||||
0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a,
|
||||
0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672,
|
||||
0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb,
|
||||
0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3,
|
||||
0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c,
|
||||
0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574,
|
||||
0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd,
|
||||
0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5,
|
||||
0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e,
|
||||
0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476,
|
||||
0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf,
|
||||
0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7,
|
||||
0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30,
|
||||
0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378,
|
||||
0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1,
|
||||
0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9,
|
||||
0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32,
|
||||
0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a,
|
||||
0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3,
|
||||
0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb,
|
||||
0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34,
|
||||
0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c,
|
||||
0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5,
|
||||
0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd,
|
||||
0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36,
|
||||
0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e,
|
||||
0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
|
||||
0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static unsigned short calc_crc_flex(unsigned char *cp, int size)
|
||||
{
|
||||
unsigned short crc = 0xffff;
|
||||
|
||||
while (size--)
|
||||
crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int check_crc_flex(unsigned char *cp, int size)
|
||||
{
|
||||
unsigned short crc = 0xffff;
|
||||
|
||||
if (size < 3)
|
||||
return -1;
|
||||
|
||||
while (size--)
|
||||
crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
|
||||
|
||||
if ((crc & 0xffff) != 0x7070)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
/* Find a free channel, and link in this `tty' line. */
|
||||
static inline struct ax_disp *ax_alloc(void)
|
||||
{
|
||||
ax25_ctrl_t *axp=NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ax25_maxdev; i++) {
|
||||
axp = ax25_ctrls[i];
|
||||
|
||||
/* Not allocated ? */
|
||||
if (axp == NULL)
|
||||
break;
|
||||
|
||||
/* Not in use ? */
|
||||
if (!test_and_set_bit(AXF_INUSE, &axp->ctrl.flags))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sorry, too many, all slots in use */
|
||||
if (i >= ax25_maxdev)
|
||||
return NULL;
|
||||
|
||||
/* If no channels are available, allocate one */
|
||||
if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) {
|
||||
axp = ax25_ctrls[i];
|
||||
}
|
||||
memset(axp, 0, sizeof(ax25_ctrl_t));
|
||||
|
||||
/* Initialize channel control data */
|
||||
set_bit(AXF_INUSE, &axp->ctrl.flags);
|
||||
sprintf(axp->dev.name, "ax%d", i++);
|
||||
axp->ctrl.tty = NULL;
|
||||
axp->dev.base_addr = i;
|
||||
axp->dev.priv = (void *)&axp->ctrl;
|
||||
axp->dev.next = NULL;
|
||||
axp->dev.init = ax25_init;
|
||||
|
||||
if (axp != NULL) {
|
||||
/*
|
||||
* register device so that it can be ifconfig'ed
|
||||
* ax25_init() will be called as a side-effect
|
||||
* SIDE-EFFECT WARNING: ax25_init() CLEARS axp->ctrl !
|
||||
*/
|
||||
if (register_netdev(&axp->dev) == 0) {
|
||||
/* (Re-)Set the INUSE bit. Very Important! */
|
||||
set_bit(AXF_INUSE, &axp->ctrl.flags);
|
||||
axp->ctrl.dev = &axp->dev;
|
||||
axp->dev.priv = (void *) &axp->ctrl;
|
||||
|
||||
return &axp->ctrl;
|
||||
} else {
|
||||
clear_bit(AXF_INUSE,&axp->ctrl.flags);
|
||||
printk(KERN_ERR "mkiss: ax_alloc() - register_netdev() failure.\n");
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Free an AX25 channel. */
|
||||
static inline void ax_free(struct ax_disp *ax)
|
||||
{
|
||||
/* Free all AX25 frame buffers. */
|
||||
if (ax->rbuff)
|
||||
kfree(ax->rbuff);
|
||||
ax->rbuff = NULL;
|
||||
if (ax->xbuff)
|
||||
kfree(ax->xbuff);
|
||||
ax->xbuff = NULL;
|
||||
if (!test_and_clear_bit(AXF_INUSE, &ax->flags))
|
||||
printk(KERN_ERR "mkiss: %s: ax_free for already free unit.\n", ax->dev->name);
|
||||
}
|
||||
|
||||
static void ax_changedmtu(struct ax_disp *ax)
|
||||
{
|
||||
struct net_device *dev = ax->dev;
|
||||
unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
|
||||
int len;
|
||||
|
||||
len = dev->mtu * 2;
|
||||
|
||||
/*
|
||||
* allow for arrival of larger UDP packets, even if we say not to
|
||||
* also fixes a bug in which SunOS sends 512-byte packets even with
|
||||
* an MSS of 128
|
||||
*/
|
||||
if (len < 576 * 2)
|
||||
len = 576 * 2;
|
||||
|
||||
xbuff = kmalloc(len + 4, GFP_ATOMIC);
|
||||
rbuff = kmalloc(len + 4, GFP_ATOMIC);
|
||||
|
||||
if (xbuff == NULL || rbuff == NULL) {
|
||||
printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, MTU change cancelled.\n",
|
||||
ax->dev->name);
|
||||
dev->mtu = ax->mtu;
|
||||
if (xbuff != NULL)
|
||||
kfree(xbuff);
|
||||
if (rbuff != NULL)
|
||||
kfree(rbuff);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ax->buflock);
|
||||
|
||||
oxbuff = ax->xbuff;
|
||||
ax->xbuff = xbuff;
|
||||
orbuff = ax->rbuff;
|
||||
ax->rbuff = rbuff;
|
||||
|
||||
if (ax->xleft) {
|
||||
if (ax->xleft <= len) {
|
||||
memcpy(ax->xbuff, ax->xhead, ax->xleft);
|
||||
} else {
|
||||
ax->xleft = 0;
|
||||
ax->tx_dropped++;
|
||||
}
|
||||
}
|
||||
|
||||
ax->xhead = ax->xbuff;
|
||||
|
||||
if (ax->rcount) {
|
||||
if (ax->rcount <= len) {
|
||||
memcpy(ax->rbuff, orbuff, ax->rcount);
|
||||
} else {
|
||||
ax->rcount = 0;
|
||||
ax->rx_over_errors++;
|
||||
set_bit(AXF_ERROR, &ax->flags);
|
||||
}
|
||||
}
|
||||
|
||||
ax->mtu = dev->mtu + 73;
|
||||
ax->buffsize = len;
|
||||
|
||||
spin_unlock_bh(&ax->buflock);
|
||||
|
||||
if (oxbuff != NULL)
|
||||
kfree(oxbuff);
|
||||
if (orbuff != NULL)
|
||||
kfree(orbuff);
|
||||
}
|
||||
|
||||
|
||||
/* Set the "sending" flag. This must be atomic. */
|
||||
static inline void ax_lock(struct ax_disp *ax)
|
||||
{
|
||||
netif_stop_queue(ax->dev);
|
||||
}
|
||||
|
||||
|
||||
/* Clear the "sending" flag. This must be atomic. */
|
||||
static inline void ax_unlock(struct ax_disp *ax)
|
||||
{
|
||||
netif_start_queue(ax->dev);
|
||||
}
|
||||
|
||||
/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
|
||||
static void ax_bump(struct ax_disp *ax)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int count;
|
||||
|
||||
spin_lock_bh(&ax->buflock);
|
||||
if (ax->rbuff[0] > 0x0f) {
|
||||
if (ax->rbuff[0] & 0x20) {
|
||||
ax->crcmode = CRC_MODE_FLEX;
|
||||
if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
|
||||
ax->rx_errors++;
|
||||
return;
|
||||
}
|
||||
ax->rcount -= 2;
|
||||
/* dl9sau bugfix: the trailling two bytes flexnet crc
|
||||
* will not be passed to the kernel. thus we have
|
||||
* to correct the kissparm signature, because it
|
||||
* indicates a crc but there's none
|
||||
*/
|
||||
*ax->rbuff &= ~0x20;
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&ax->buflock);
|
||||
|
||||
count = ax->rcount;
|
||||
|
||||
if ((skb = dev_alloc_skb(count)) == NULL) {
|
||||
printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name);
|
||||
ax->rx_dropped++;
|
||||
return;
|
||||
}
|
||||
|
||||
skb->dev = ax->dev;
|
||||
spin_lock_bh(&ax->buflock);
|
||||
memcpy(skb_put(skb,count), ax->rbuff, count);
|
||||
spin_unlock_bh(&ax->buflock);
|
||||
skb->mac.raw = skb->data;
|
||||
skb->protocol = htons(ETH_P_AX25);
|
||||
netif_rx(skb);
|
||||
ax->dev->last_rx = jiffies;
|
||||
ax->rx_packets++;
|
||||
ax->rx_bytes+=count;
|
||||
}
|
||||
|
||||
/* Encapsulate one AX.25 packet and stuff into a TTY queue. */
|
||||
static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
|
||||
{
|
||||
unsigned char *p;
|
||||
int actual, count;
|
||||
|
||||
if (ax->mtu != ax->dev->mtu + 73) /* Someone has been ifconfigging */
|
||||
ax_changedmtu(ax);
|
||||
|
||||
if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */
|
||||
len = ax->mtu;
|
||||
printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
|
||||
ax->tx_dropped++;
|
||||
ax_unlock(ax);
|
||||
return;
|
||||
}
|
||||
|
||||
p = icp;
|
||||
|
||||
spin_lock_bh(&ax->buflock);
|
||||
switch (ax->crcmode) {
|
||||
unsigned short crc;
|
||||
|
||||
case CRC_MODE_FLEX:
|
||||
*p |= 0x20;
|
||||
crc = calc_crc_flex(p, len);
|
||||
count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
|
||||
break;
|
||||
|
||||
default:
|
||||
count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
|
||||
break;
|
||||
}
|
||||
|
||||
ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
|
||||
actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
|
||||
ax->tx_packets++;
|
||||
ax->tx_bytes+=actual;
|
||||
ax->dev->trans_start = jiffies;
|
||||
ax->xleft = count - actual;
|
||||
ax->xhead = ax->xbuff + actual;
|
||||
|
||||
spin_unlock_bh(&ax->buflock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called by the driver when there's room for more data. If we have
|
||||
* more packets to send, we send them here.
|
||||
*/
|
||||
static void ax25_write_wakeup(struct tty_struct *tty)
|
||||
{
|
||||
int actual;
|
||||
struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
|
||||
|
||||
/* First make sure we're connected. */
|
||||
if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev))
|
||||
return;
|
||||
if (ax->xleft <= 0) {
|
||||
/* Now serial buffer is almost free & we can start
|
||||
* transmission of another packet
|
||||
*/
|
||||
tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
|
||||
|
||||
netif_wake_queue(ax->dev);
|
||||
return;
|
||||
}
|
||||
|
||||
actual = tty->driver->write(tty, ax->xhead, ax->xleft);
|
||||
ax->xleft -= actual;
|
||||
ax->xhead += actual;
|
||||
}
|
||||
|
||||
/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
|
||||
static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct ax_disp *ax = netdev_priv(dev);
|
||||
|
||||
if (!netif_running(dev)) {
|
||||
printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (netif_queue_stopped(dev)) {
|
||||
/*
|
||||
* May be we must check transmitter timeout here ?
|
||||
* 14 Oct 1994 Dmitry Gorodchanin.
|
||||
*/
|
||||
if (jiffies - dev->trans_start < 20 * HZ) {
|
||||
/* 20 sec timeout not reached */
|
||||
return 1;
|
||||
}
|
||||
|
||||
printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
|
||||
(ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ?
|
||||
"bad line quality" : "driver error");
|
||||
|
||||
ax->xleft = 0;
|
||||
ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
|
||||
ax_unlock(ax);
|
||||
}
|
||||
|
||||
/* We were not busy, so we are now... :-) */
|
||||
if (skb != NULL) {
|
||||
ax_lock(ax);
|
||||
ax_encaps(ax, skb->data, skb->len);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
|
||||
|
||||
/* Return the frame type ID */
|
||||
static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
|
||||
void *daddr, void *saddr, unsigned len)
|
||||
{
|
||||
#ifdef CONFIG_INET
|
||||
if (type != htons(ETH_P_AX25))
|
||||
return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ax_rebuild_header(struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_INET
|
||||
return ax25_rebuild_header(skb);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CONFIG_{AX25,AX25_MODULE} */
|
||||
|
||||
/* Open the low-level part of the AX25 channel. Easy! */
|
||||
static int ax_open(struct net_device *dev)
|
||||
{
|
||||
struct ax_disp *ax = netdev_priv(dev);
|
||||
unsigned long len;
|
||||
|
||||
if (ax->tty == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Allocate the frame buffers:
|
||||
*
|
||||
* rbuff Receive buffer.
|
||||
* xbuff Transmit buffer.
|
||||
*/
|
||||
len = dev->mtu * 2;
|
||||
|
||||
/*
|
||||
* allow for arrival of larger UDP packets, even if we say not to
|
||||
* also fixes a bug in which SunOS sends 512-byte packets even with
|
||||
* an MSS of 128
|
||||
*/
|
||||
if (len < 576 * 2)
|
||||
len = 576 * 2;
|
||||
|
||||
if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
|
||||
goto norbuff;
|
||||
|
||||
if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
|
||||
goto noxbuff;
|
||||
|
||||
ax->mtu = dev->mtu + 73;
|
||||
ax->buffsize = len;
|
||||
ax->rcount = 0;
|
||||
ax->xleft = 0;
|
||||
|
||||
ax->flags &= (1 << AXF_INUSE); /* Clear ESCAPE & ERROR flags */
|
||||
|
||||
spin_lock_init(&ax->buflock);
|
||||
|
||||
netif_start_queue(dev);
|
||||
return 0;
|
||||
|
||||
noxbuff:
|
||||
kfree(ax->rbuff);
|
||||
|
||||
norbuff:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
/* Close the low-level part of the AX25 channel. Easy! */
|
||||
static int ax_close(struct net_device *dev)
|
||||
{
|
||||
struct ax_disp *ax = netdev_priv(dev);
|
||||
|
||||
if (ax->tty == NULL)
|
||||
return -EBUSY;
|
||||
|
||||
ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ax25_receive_room(struct tty_struct *tty)
|
||||
{
|
||||
return 65536; /* We can handle an infinite amount of data. :-) */
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle the 'receiver data ready' interrupt.
|
||||
* This function is called by the 'tty_io' module in the kernel when
|
||||
* a block of data has been received, which can now be decapsulated
|
||||
* and sent on to the AX.25 layer for further processing.
|
||||
*/
|
||||
static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
|
||||
{
|
||||
struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
|
||||
|
||||
if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Argh! mtu change time! - costs us the packet part received
|
||||
* at the change
|
||||
*/
|
||||
if (ax->mtu != ax->dev->mtu + 73)
|
||||
ax_changedmtu(ax);
|
||||
|
||||
/* Read the characters out of the buffer */
|
||||
while (count--) {
|
||||
if (fp != NULL && *fp++) {
|
||||
if (!test_and_set_bit(AXF_ERROR, &ax->flags))
|
||||
ax->rx_errors++;
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
|
||||
kiss_unesc(ax, *cp++);
|
||||
}
|
||||
}
|
||||
|
||||
static int ax25_open(struct tty_struct *tty)
|
||||
{
|
||||
struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
|
||||
int err;
|
||||
|
||||
/* First make sure we're not already connected. */
|
||||
if (ax && ax->magic == AX25_MAGIC)
|
||||
return -EEXIST;
|
||||
|
||||
/* OK. Find a free AX25 channel to use. */
|
||||
if ((ax = ax_alloc()) == NULL)
|
||||
return -ENFILE;
|
||||
|
||||
ax->tty = tty;
|
||||
tty->disc_data = ax;
|
||||
|
||||
if (tty->driver->flush_buffer)
|
||||
tty->driver->flush_buffer(tty);
|
||||
|
||||
/* Restore default settings */
|
||||
ax->dev->type = ARPHRD_AX25;
|
||||
|
||||
/* Perform the low-level AX25 initialization. */
|
||||
if ((err = ax_open(ax->dev)))
|
||||
return err;
|
||||
|
||||
/* Done. We have linked the TTY line to a channel. */
|
||||
return ax->dev->base_addr;
|
||||
}
|
||||
|
||||
static void ax25_close(struct tty_struct *tty)
|
||||
{
|
||||
struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
|
||||
|
||||
/* First make sure we're connected. */
|
||||
if (ax == NULL || ax->magic != AX25_MAGIC)
|
||||
return;
|
||||
|
||||
unregister_netdev(ax->dev);
|
||||
|
||||
tty->disc_data = NULL;
|
||||
ax->tty = NULL;
|
||||
|
||||
ax_free(ax);
|
||||
}
|
||||
|
||||
|
||||
static struct net_device_stats *ax_get_stats(struct net_device *dev)
|
||||
{
|
||||
static struct net_device_stats stats;
|
||||
struct ax_disp *ax = netdev_priv(dev);
|
||||
|
||||
memset(&stats, 0, sizeof(struct net_device_stats));
|
||||
|
||||
stats.rx_packets = ax->rx_packets;
|
||||
stats.tx_packets = ax->tx_packets;
|
||||
stats.rx_bytes = ax->rx_bytes;
|
||||
stats.tx_bytes = ax->tx_bytes;
|
||||
stats.rx_dropped = ax->rx_dropped;
|
||||
stats.tx_dropped = ax->tx_dropped;
|
||||
stats.tx_errors = ax->tx_errors;
|
||||
stats.rx_errors = ax->rx_errors;
|
||||
stats.rx_over_errors = ax->rx_over_errors;
|
||||
|
||||
return &stats;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* STANDARD ENCAPSULATION *
|
||||
************************************************************************/
|
||||
|
||||
static int kiss_esc(unsigned char *s, unsigned char *d, int len)
|
||||
{
|
||||
unsigned char *ptr = d;
|
||||
unsigned char c;
|
||||
|
||||
/*
|
||||
* Send an initial END character to flush out any
|
||||
* data that may have accumulated in the receiver
|
||||
* due to line noise.
|
||||
*/
|
||||
|
||||
*ptr++ = END;
|
||||
|
||||
while (len-- > 0) {
|
||||
switch (c = *s++) {
|
||||
case END:
|
||||
*ptr++ = ESC;
|
||||
*ptr++ = ESC_END;
|
||||
break;
|
||||
case ESC:
|
||||
*ptr++ = ESC;
|
||||
*ptr++ = ESC_ESC;
|
||||
break;
|
||||
default:
|
||||
*ptr++ = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*ptr++ = END;
|
||||
|
||||
return ptr - d;
|
||||
}
|
||||
|
||||
/*
|
||||
* MW:
|
||||
* OK its ugly, but tell me a better solution without copying the
|
||||
* packet to a temporary buffer :-)
|
||||
*/
|
||||
static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len)
|
||||
{
|
||||
unsigned char *ptr = d;
|
||||
unsigned char c=0;
|
||||
|
||||
*ptr++ = END;
|
||||
while (len > 0) {
|
||||
if (len > 2)
|
||||
c = *s++;
|
||||
else if (len > 1)
|
||||
c = crc >> 8;
|
||||
else if (len > 0)
|
||||
c = crc & 0xff;
|
||||
|
||||
len--;
|
||||
|
||||
switch (c) {
|
||||
case END:
|
||||
*ptr++ = ESC;
|
||||
*ptr++ = ESC_END;
|
||||
break;
|
||||
case ESC:
|
||||
*ptr++ = ESC;
|
||||
*ptr++ = ESC_ESC;
|
||||
break;
|
||||
default:
|
||||
*ptr++ = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*ptr++ = END;
|
||||
return ptr - d;
|
||||
}
|
||||
|
||||
static void kiss_unesc(struct ax_disp *ax, unsigned char s)
|
||||
{
|
||||
switch (s) {
|
||||
case END:
|
||||
/* drop keeptest bit = VSV */
|
||||
if (test_bit(AXF_KEEPTEST, &ax->flags))
|
||||
clear_bit(AXF_KEEPTEST, &ax->flags);
|
||||
|
||||
if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
|
||||
ax_bump(ax);
|
||||
|
||||
clear_bit(AXF_ESCAPE, &ax->flags);
|
||||
ax->rcount = 0;
|
||||
return;
|
||||
|
||||
case ESC:
|
||||
set_bit(AXF_ESCAPE, &ax->flags);
|
||||
return;
|
||||
case ESC_ESC:
|
||||
if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
|
||||
s = ESC;
|
||||
break;
|
||||
case ESC_END:
|
||||
if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
|
||||
s = END;
|
||||
break;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ax->buflock);
|
||||
if (!test_bit(AXF_ERROR, &ax->flags)) {
|
||||
if (ax->rcount < ax->buffsize) {
|
||||
ax->rbuff[ax->rcount++] = s;
|
||||
spin_unlock_bh(&ax->buflock);
|
||||
return;
|
||||
}
|
||||
|
||||
ax->rx_over_errors++;
|
||||
set_bit(AXF_ERROR, &ax->flags);
|
||||
}
|
||||
spin_unlock_bh(&ax->buflock);
|
||||
}
|
||||
|
||||
|
||||
static int ax_set_mac_address(struct net_device *dev, void __user *addr)
|
||||
{
|
||||
if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ax_set_dev_mac_address(struct net_device *dev, void *addr)
|
||||
{
|
||||
struct sockaddr *sa = addr;
|
||||
|
||||
memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Perform I/O control on an active ax25 channel. */
|
||||
static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void __user *arg)
|
||||
{
|
||||
struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
|
||||
unsigned int tmp;
|
||||
|
||||
/* First make sure we're connected. */
|
||||
if (ax == NULL || ax->magic != AX25_MAGIC)
|
||||
return -EINVAL;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCGIFNAME:
|
||||
if (copy_to_user(arg, ax->dev->name, strlen(ax->dev->name) + 1))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
|
||||
case SIOCGIFENCAP:
|
||||
return put_user(4, (int __user *)arg);
|
||||
|
||||
case SIOCSIFENCAP:
|
||||
if (get_user(tmp, (int __user *)arg))
|
||||
return -EFAULT;
|
||||
ax->mode = tmp;
|
||||
ax->dev->addr_len = AX25_ADDR_LEN; /* sizeof an AX.25 addr */
|
||||
ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
|
||||
ax->dev->type = ARPHRD_AX25;
|
||||
return 0;
|
||||
|
||||
case SIOCSIFHWADDR:
|
||||
return ax_set_mac_address(ax->dev, arg);
|
||||
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
}
|
||||
|
||||
static int ax_open_dev(struct net_device *dev)
|
||||
{
|
||||
struct ax_disp *ax = netdev_priv(dev);
|
||||
|
||||
if (ax->tty == NULL)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the driver. Called by network startup. */
|
||||
static int ax25_init(struct net_device *dev)
|
||||
{
|
||||
struct ax_disp *ax = netdev_priv(dev);
|
||||
|
||||
static char ax25_bcast[AX25_ADDR_LEN] =
|
||||
{'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
|
||||
static char ax25_test[AX25_ADDR_LEN] =
|
||||
{'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
|
||||
|
||||
if (ax == NULL) /* Allocation failed ?? */
|
||||
return -ENODEV;
|
||||
|
||||
/* Set up the "AX25 Control Block". (And clear statistics) */
|
||||
memset(ax, 0, sizeof (struct ax_disp));
|
||||
ax->magic = AX25_MAGIC;
|
||||
ax->dev = dev;
|
||||
|
||||
/* Finish setting up the DEVICE info. */
|
||||
dev->mtu = AX_MTU;
|
||||
dev->hard_start_xmit = ax_xmit;
|
||||
dev->open = ax_open_dev;
|
||||
dev->stop = ax_close;
|
||||
dev->get_stats = ax_get_stats;
|
||||
dev->set_mac_address = ax_set_dev_mac_address;
|
||||
dev->hard_header_len = 0;
|
||||
dev->addr_len = 0;
|
||||
dev->type = ARPHRD_AX25;
|
||||
dev->tx_queue_len = 10;
|
||||
dev->hard_header = ax_header;
|
||||
dev->rebuild_header = ax_rebuild_header;
|
||||
|
||||
memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
|
||||
memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
|
||||
|
||||
/* New-style flags. */
|
||||
dev->flags = IFF_BROADCAST | IFF_MULTICAST;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************************** */
|
||||
/* * Init MKISS driver * */
|
||||
/* ******************************************************************** */
|
||||
|
||||
static int __init mkiss_init_driver(void)
|
||||
{
|
||||
int status;
|
||||
|
||||
printk(banner);
|
||||
|
||||
if (ax25_maxdev < 4)
|
||||
ax25_maxdev = 4; /* Sanity */
|
||||
|
||||
if ((ax25_ctrls = kmalloc(sizeof(void *) * ax25_maxdev, GFP_KERNEL)) == NULL) {
|
||||
printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array!\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Clear the pointer array, we allocate devices when we need them */
|
||||
memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */
|
||||
|
||||
/* Fill in our line protocol discipline, and register it */
|
||||
ax_ldisc.magic = TTY_LDISC_MAGIC;
|
||||
ax_ldisc.name = "mkiss";
|
||||
ax_ldisc.open = ax25_open;
|
||||
ax_ldisc.close = ax25_close;
|
||||
ax_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
|
||||
unsigned int, unsigned long))ax25_disp_ioctl;
|
||||
ax_ldisc.receive_buf = ax25_receive_buf;
|
||||
ax_ldisc.receive_room = ax25_receive_room;
|
||||
ax_ldisc.write_wakeup = ax25_write_wakeup;
|
||||
|
||||
if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) {
|
||||
printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status);
|
||||
kfree(ax25_ctrls);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void __exit mkiss_exit_driver(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ax25_maxdev; i++) {
|
||||
if (ax25_ctrls[i]) {
|
||||
/*
|
||||
* VSV = if dev->start==0, then device
|
||||
* unregistered while close proc.
|
||||
*/
|
||||
if (netif_running(&ax25_ctrls[i]->dev))
|
||||
unregister_netdev(&ax25_ctrls[i]->dev);
|
||||
kfree(ax25_ctrls[i]);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(ax25_ctrls);
|
||||
ax25_ctrls = NULL;
|
||||
|
||||
if ((i = tty_register_ldisc(N_AX25, NULL)))
|
||||
printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Hans Albas PE1AYX <hans@esrac.ele.tue.nl>");
|
||||
MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
|
||||
MODULE_PARM(ax25_maxdev, "i");
|
||||
MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_LDISC(N_AX25);
|
||||
module_init(mkiss_init_driver);
|
||||
module_exit(mkiss_exit_driver);
|
||||
|
62
drivers/net/hamradio/mkiss.h
Normal file
62
drivers/net/hamradio/mkiss.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
* Defines for the Multi-KISS driver.
|
||||
****************************************************************************/
|
||||
|
||||
#define AX25_MAXDEV 16 /* MAX number of AX25 channels;
|
||||
This can be overridden with
|
||||
insmod -oax25_maxdev=nnn */
|
||||
#define AX_MTU 236
|
||||
|
||||
/* SLIP/KISS protocol characters. */
|
||||
#define END 0300 /* indicates end of frame */
|
||||
#define ESC 0333 /* indicates byte stuffing */
|
||||
#define ESC_END 0334 /* ESC ESC_END means END 'data' */
|
||||
#define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
|
||||
|
||||
struct ax_disp {
|
||||
int magic;
|
||||
|
||||
/* Various fields. */
|
||||
struct tty_struct *tty; /* ptr to TTY structure */
|
||||
struct net_device *dev; /* easy for intr handling */
|
||||
|
||||
/* These are pointers to the malloc()ed frame buffers. */
|
||||
unsigned char *rbuff; /* receiver buffer */
|
||||
int rcount; /* received chars counter */
|
||||
unsigned char *xbuff; /* transmitter buffer */
|
||||
unsigned char *xhead; /* pointer to next byte to XMIT */
|
||||
int xleft; /* bytes left in XMIT queue */
|
||||
|
||||
/* SLIP interface statistics. */
|
||||
unsigned long rx_packets; /* inbound frames counter */
|
||||
unsigned long tx_packets; /* outbound frames counter */
|
||||
unsigned long rx_bytes; /* inbound bytes counter */
|
||||
unsigned long tx_bytes; /* outbound bytes counter */
|
||||
unsigned long rx_errors; /* Parity, etc. errors */
|
||||
unsigned long tx_errors; /* Planned stuff */
|
||||
unsigned long rx_dropped; /* No memory for skb */
|
||||
unsigned long tx_dropped; /* When MTU change */
|
||||
unsigned long rx_over_errors; /* Frame bigger then SLIP buf. */
|
||||
|
||||
/* Detailed SLIP statistics. */
|
||||
int mtu; /* Our mtu (to spot changes!) */
|
||||
int buffsize; /* Max buffers sizes */
|
||||
|
||||
|
||||
unsigned long flags; /* Flag values/ mode etc */
|
||||
/* long req'd: used by set_bit --RR */
|
||||
#define AXF_INUSE 0 /* Channel in use */
|
||||
#define AXF_ESCAPE 1 /* ESC received */
|
||||
#define AXF_ERROR 2 /* Parity, etc. error */
|
||||
#define AXF_KEEPTEST 3 /* Keepalive test flag */
|
||||
#define AXF_OUTWAIT 4 /* is outpacket was flag */
|
||||
|
||||
int mode;
|
||||
int crcmode; /* MW: for FlexNet, SMACK etc. */
|
||||
#define CRC_MODE_NONE 0
|
||||
#define CRC_MODE_FLEX 1
|
||||
#define CRC_MODE_SMACK 2
|
||||
spinlock_t buflock; /* lock for rbuf and xbuf */
|
||||
};
|
||||
|
||||
#define AX25_MAGIC 0x5316
|
2191
drivers/net/hamradio/scc.c
Normal file
2191
drivers/net/hamradio/scc.c
Normal file
File diff suppressed because it is too large
Load Diff
1218
drivers/net/hamradio/yam.c
Normal file
1218
drivers/net/hamradio/yam.c
Normal file
File diff suppressed because it is too large
Load Diff
343
drivers/net/hamradio/yam1200.h
Normal file
343
drivers/net/hamradio/yam1200.h
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
*
|
||||
* File yam1k2b5.mcs converted to h format by mcs2h
|
||||
*
|
||||
* (C) F6FBB 1998
|
||||
*
|
||||
* Tue Aug 25 20:24:08 1998
|
||||
*
|
||||
*/
|
||||
|
||||
static unsigned char bits_1200[]= {
|
||||
0xff,0xf2,0x00,0xa5,0xad,0xff,0xfe,0x9f,0xff,0xef,0xf3,0xcb,0xff,0xdb,0xfc,0xf2,
|
||||
0xff,0xf6,0xff,0x3c,0xbf,0xfd,0xbf,0xdf,0x6e,0x3f,0x6f,0xf1,0x7d,0xb4,0xfd,0xbf,
|
||||
0xdf,0x6f,0x3f,0x6f,0xf7,0x0b,0xff,0xdb,0xfd,0xf2,0xff,0xf6,0xff,0xff,0xff,0xff,
|
||||
0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xdf,0xff,0xff,0xff,0xef,0xff,0xff,0xff,
|
||||
0xfd,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xbf,
|
||||
0xff,0xff,0xf7,0xff,0xff,0xfb,0xff,0xff,0xff,0xfc,0xff,0xfe,0xff,0xff,0xff,0xf0,
|
||||
0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xf1,0xff,0xff,0xfe,0x7f,0xbf,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xfb,0xff,0xff,0xff,0xf0,0x9f,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xfd,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xf7,0xff,
|
||||
0xff,0xff,0xfb,0xff,0xfb,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xf7,0xff,0xff,0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xef,0xff,0xf0,0x5f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xef,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xbf,0xff,0xff,0xdf,0xf7,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xfb,0xfe,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,
|
||||
0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xeb,
|
||||
0xff,0xff,0xff,0xfd,0xff,0xbf,0xf1,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xfb,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x6f,0xff,0xff,0xff,
|
||||
0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xf7,0xff,0xff,0xf1,0xff,0xff,0xf7,0xbf,0xe7,0xff,0xff,0xff,0xff,0xfb,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0x77,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xdb,
|
||||
0xff,0xff,0xf5,0xa5,0xfd,0x4b,0x6e,0xef,0x33,0x32,0xdd,0xd3,0x4a,0xd6,0x92,0xfe,
|
||||
0xb3,0x3f,0xbd,0xf1,0xfa,0xdb,0xfe,0xf7,0xf6,0x96,0xbd,0xbd,0xff,0xbd,0xff,0xed,
|
||||
0x7f,0x6b,0x7f,0xfb,0xdf,0xfe,0xfb,0xfe,0x90,0xcf,0xff,0xff,0xff,0xfe,0xbe,0xef,
|
||||
0xff,0xff,0xdb,0x5f,0xf6,0xff,0xf6,0x8f,0xfd,0xa5,0xdd,0xff,0xff,0xff,0xff,0x6f,
|
||||
0x7f,0xdb,0xf1,0xfc,0xbf,0xff,0x6f,0xff,0xef,0xfc,0x5b,0x5d,0xda,0xdf,0xf4,0xff,
|
||||
0xf2,0xff,0xfd,0xbf,0xff,0xff,0xff,0xd0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xfb,0xef,0xb7,0xfc,0x33,0xff,0xfb,0xff,0x04,0x6a,0xf3,0x3c,0x36,0xff,0xf0,
|
||||
0x0f,0xf1,0x0f,0xff,0xff,0xff,0xf3,0x15,0x72,0x0f,0xf1,0x6f,0xff,0xfe,0x94,0x3f,
|
||||
0xff,0xff,0xff,0x7b,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf0,
|
||||
0xf7,0xef,0xb7,0xfc,0x33,0xff,0xff,0xff,0x04,0x6a,0xf3,0x3c,0x36,0xff,0xf0,0x0f,
|
||||
0xf1,0x0f,0xff,0xff,0xff,0xf3,0x15,0x73,0x8f,0xf2,0x6f,0xff,0xfe,0x94,0x3f,0xff,
|
||||
0xff,0xff,0x7d,0x9f,0xff,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x9e,
|
||||
0xff,0xfc,0xef,0xd3,0xfb,0xff,0x7f,0xf5,0x5f,0xfe,0x59,0xff,0xff,0xff,0xfc,0xf1,
|
||||
0xfe,0x7f,0xff,0xff,0xfa,0x17,0xff,0xe7,0xef,0xef,0xff,0xff,0x3f,0xf1,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf5,0xff,0xbf,0xff,0xfc,0xea,
|
||||
0xff,0xf0,0xff,0xff,0xbf,0xf9,0x3f,0xb1,0xef,0xff,0xd7,0xff,0xfb,0xff,0xf0,0xff,
|
||||
0xff,0xf3,0xff,0xdf,0xff,0x7b,0xff,0xfd,0xff,0xf6,0xff,0xbf,0xff,0xff,0xbf,0xff,
|
||||
0xff,0xff,0xda,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf2,0xc0,0x01,0x00,0x00,0x02,0x02,
|
||||
0x02,0x02,0x00,0x40,0x40,0x40,0x10,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x19,0x00,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,
|
||||
0x00,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xfb,0xff,0xfd,0xff,
|
||||
0xff,0x7f,0xff,0xff,0xbf,0xff,0xef,0xff,0xff,0xfd,0xff,0xff,0xf1,0xff,0xdf,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xbf,0xfe,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xdf,
|
||||
0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xbf,0xdf,0xff,0x7f,0xff,0xff,0xff,0xff,
|
||||
0xdf,0xdf,0xff,0xef,0xff,0x9e,0xef,0xff,0xff,0x7f,0xff,0xf1,0xef,0xff,0xff,0xff,
|
||||
0xf7,0xfa,0xbf,0xff,0xff,0xfe,0x47,0xef,0xff,0xbd,0xf6,0xff,0xff,0xdf,0xf5,0xf0,
|
||||
0xf0,0xef,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,0x00,0x00,0x04,0x00,0x01,0x02,0x08,
|
||||
0x16,0x00,0x00,0x00,0x80,0x00,0x01,0x02,0x00,0x80,0x01,0x0c,0x02,0x00,0x00,0x01,
|
||||
0x00,0x00,0x20,0x00,0x00,0x06,0x00,0x20,0x00,0x10,0x00,0x14,0x00,0x04,0xc1,0xf0,
|
||||
0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0x7f,
|
||||
0xec,0xff,0xff,0xfa,0xff,0xbf,0xff,0x6f,0xff,0xe1,0xff,0xff,0xff,0xff,0xbd,0xfe,
|
||||
0x46,0xff,0xef,0x7f,0xcd,0xdf,0xff,0xff,0xfd,0xff,0xbd,0xff,0x7f,0x7f,0xf0,0x4f,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xa4,0xbc,0xcd,0x6d,0x6b,0x6f,0x5b,0xdc,0x33,
|
||||
0x5a,0xf6,0xf7,0xf6,0xb3,0x3f,0xbd,0xc1,0xfa,0x5a,0xf6,0xf6,0xb6,0xf7,0xff,0xbd,
|
||||
0xbb,0x3c,0xce,0xcf,0x34,0xef,0x33,0xbb,0xcc,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,
|
||||
0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xd6,0xff,0xfd,0xfd,0xbf,0xff,0xad,
|
||||
0xbf,0xf9,0x7f,0x6f,0xfc,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,0xff,0xda,0xdb,0xfc,
|
||||
0xdb,0xff,0x76,0x8f,0xf6,0xff,0xcd,0xab,0xfe,0xfb,0xff,0xd0,0xff,0xff,0xff,0xff,
|
||||
0xfe,0xff,0x9f,0xff,0xf4,0x20,0xaf,0x6d,0x0b,0xc1,0x7b,0xff,0xff,0xff,0xcb,0xff,
|
||||
0x3f,0xf0,0xef,0x7f,0x0f,0xf1,0xc3,0x3c,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x0b,
|
||||
0x1d,0x6a,0x64,0x05,0x6b,0x99,0x01,0xff,0xfd,0xef,0xf0,0x2f,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xf4,0x00,0x2f,0xcc,0x0b,0xc3,0x7f,0xff,0xff,0xff,0x0a,0xdf,0xbf,
|
||||
0xfd,0x7f,0xff,0xff,0xf1,0xc3,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x4a,0x0e,
|
||||
0x96,0x64,0x02,0x97,0x99,0x10,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xfe,0x84,0xf9,0xd5,0x27,0xf1,0x7f,0xff,0xf8,0xeb,0xdf,0xf3,0xcf,0x3f,
|
||||
0x1f,0xff,0xf7,0x11,0xff,0xcf,0xff,0xfe,0x67,0xff,0xff,0xff,0xff,0xc4,0xff,0xff,
|
||||
0xb3,0xa1,0xff,0xf9,0xe0,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xf5,0xff,
|
||||
0xff,0xfb,0x7f,0xe0,0xff,0xc7,0xfe,0x7f,0x3f,0xff,0xfd,0x77,0x8d,0x7f,0x0f,0xff,
|
||||
0xc3,0xff,0xf1,0xbf,0x8f,0xcf,0xff,0xff,0xdd,0x7b,0xff,0xf6,0xfa,0xf7,0xff,0x40,
|
||||
0x9f,0xf9,0x7f,0xd8,0xff,0xff,0xfa,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,
|
||||
0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x10,0x00,0x00,0x10,
|
||||
0x00,0x01,0x00,0x10,0x20,0x20,0x00,0x00,0x10,0x00,0x04,0x01,0x05,0x00,0x00,0x00,
|
||||
0x00,0x40,0x40,0x00,0x00,0x3c,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,
|
||||
0xff,0xff,0xfe,0x7f,0x7f,0xff,0xef,0xff,0xff,0xdf,0xff,0xff,0xdf,0xff,0xef,0xf7,
|
||||
0xf1,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xf7,0xff,0xff,0xff,0xfc,0xfd,0xff,0x7f,
|
||||
0x7e,0xff,0xff,0xff,0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xff,0xff,0xff,
|
||||
0xff,0xff,0xfe,0xeb,0xfd,0x6f,0xff,0xf7,0xfe,0xf5,0x7f,0xff,0xff,0x7f,0xbf,0xb1,
|
||||
0xff,0xff,0x9f,0xbf,0xfb,0xff,0xfe,0xff,0xfe,0xff,0xf7,0xeb,0xdf,0xbf,0x5f,0xdd,
|
||||
0xff,0xdb,0xfd,0xd0,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x20,0x00,0x42,0x00,
|
||||
0x00,0x00,0x30,0x18,0x04,0x08,0x09,0x21,0x82,0x80,0x02,0x00,0x08,0x00,0x01,0x00,
|
||||
0x00,0x00,0x0c,0x20,0x10,0x00,0x11,0x00,0x44,0x84,0x00,0x20,0x20,0x84,0x80,0x00,
|
||||
0x00,0x00,0xc1,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xf7,0xff,0xfb,0xdd,0xf9,0xff,
|
||||
0xda,0xff,0xdc,0xdd,0xfc,0xfb,0xff,0xbf,0xfb,0x3e,0xd7,0x96,0xfe,0x61,0xf7,0xff,
|
||||
0x7f,0xff,0x3f,0xfd,0xff,0xdf,0xcf,0xf7,0xdf,0xf7,0xbf,0xfd,0xff,0xfe,0xef,0xef,
|
||||
0xfe,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf3,0xbd,0xfd,0x4b,0x74,0xcf,
|
||||
0x73,0x5b,0xcb,0x3b,0xdf,0xfe,0xf7,0xfe,0xd3,0x75,0xac,0xa1,0xfb,0xdf,0xfe,0xf7,
|
||||
0x76,0x96,0xb5,0x24,0xbd,0xa5,0xad,0x49,0x2f,0x69,0x2b,0x52,0x5b,0xbd,0xff,0xff,
|
||||
0xf0,0xcf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xfe,0xff,0xcc,
|
||||
0xa7,0xfb,0xad,0xff,0x7f,0x6f,0xff,0x6d,0x7f,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,
|
||||
0x6f,0xff,0xdb,0xff,0xdb,0xff,0xf6,0x97,0xf6,0xff,0xb5,0xb5,0xff,0xff,0xff,0xd0,
|
||||
0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xa5,0xbc,0x43,0xfc,0x7c,0x03,0xe7,
|
||||
0xff,0xff,0x20,0xff,0xff,0xff,0xcc,0xfd,0x7d,0xf1,0xff,0xff,0xff,0xff,0xd5,0x59,
|
||||
0xba,0x56,0x66,0x6a,0xad,0x9a,0xa9,0x9a,0x97,0xa5,0xaa,0xbb,0xff,0xff,0xf0,0x0f,
|
||||
0xff,0xff,0xff,0xfe,0xfe,0xfb,0xff,0xfd,0xf7,0xfd,0x43,0xff,0xfd,0x6b,0xe7,0xff,
|
||||
0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0x3f,0xf1,0xff,0xff,0xff,0xff,0xd5,0x59,0xb5,
|
||||
0xa6,0x66,0x6a,0xad,0x9a,0xa9,0x99,0x6b,0x5a,0xaa,0xff,0xff,0xb7,0xf0,0x3f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0x9c,0xf7,0xfd,0xd2,0x41,0xff,0xff,0xf2,0x7f,
|
||||
0x8f,0xff,0xff,0x3d,0xf3,0xff,0x17,0xf1,0xff,0xff,0xff,0xff,0xff,0x7f,0xdf,0xfc,
|
||||
0x8f,0x38,0xff,0xef,0x23,0xff,0xfb,0xf7,0xc8,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,
|
||||
0xff,0xfe,0xf5,0x7f,0xff,0xfd,0xff,0xe4,0xff,0xeb,0xff,0xcf,0xbf,0xfa,0xff,0xab,
|
||||
0xef,0xff,0xfb,0xff,0xf3,0xfd,0x61,0xff,0xff,0xff,0xff,0xfa,0xff,0xfb,0xfd,0x0d,
|
||||
0xff,0xfe,0xff,0x43,0x7f,0xfe,0xbf,0xd0,0xfd,0xff,0xfa,0xf0,0x3f,0xff,0xff,0xff,
|
||||
0xfe,0xf3,0xc0,0x00,0x00,0x00,0x02,0x00,0x02,0x01,0x00,0x60,0xc0,0x40,0x00,0x00,
|
||||
0x00,0x00,0x34,0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x88,0x00,
|
||||
0x00,0x03,0x00,0x00,0x40,0x00,0x40,0x00,0x00,0x3c,0xf0,0x3f,0xff,0xff,0xff,0xfe,
|
||||
0xfd,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0x7f,0xbf,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xf7,0xf1,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xfd,0xff,
|
||||
0xff,0xff,0xff,0xfe,0xfe,0x5f,0xff,0xff,0xcb,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf0,
|
||||
0xff,0xff,0xfd,0xff,0xef,0xe3,0xde,0xee,0xd9,0xc5,0x93,0xff,0xff,0xfe,0xfe,0xff,
|
||||
0xfb,0xee,0xfe,0xf1,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xbf,0xf7,0xff,0xff,0x7f,
|
||||
0xaf,0xbd,0xdf,0xdf,0xfb,0xf3,0xf3,0xf0,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf8,0x34,
|
||||
0x00,0x06,0x61,0x00,0x18,0x01,0xa0,0x05,0x17,0x00,0x20,0x05,0x28,0x20,0x00,0x00,
|
||||
0x05,0x00,0x41,0x00,0x00,0x40,0x00,0x09,0x00,0x01,0x20,0x86,0x82,0x08,0x40,0x03,
|
||||
0x80,0x30,0x70,0x08,0x14,0x02,0xc1,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xff,0xbd,0xef,0xfb,0xff,0xff,0xfb,0x9c,0x7f,0xef,0xdf,0xff,0xbf,0xeb,0xde,
|
||||
0xff,0xc1,0x7f,0xff,0xfb,0x7f,0xff,0xff,0xff,0x5f,0xff,0xff,0xff,0xdf,0xbf,0xef,
|
||||
0x3f,0xf7,0x8f,0xef,0x7f,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xbd,
|
||||
0xdf,0xef,0x7d,0x6d,0x2b,0x5a,0x5d,0xd2,0xdf,0xf6,0x92,0xb6,0xb2,0xb3,0xac,0xa1,
|
||||
0xfb,0xdf,0xfe,0xf1,0xee,0xf5,0xf6,0xbc,0x6b,0xbd,0x7d,0xaf,0x1a,0xef,0x5f,0x6b,
|
||||
0xc6,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,
|
||||
0xf6,0xff,0xf6,0xb7,0xfd,0xad,0xfd,0xbf,0xf3,0x6f,0xff,0x6f,0xff,0xdb,0xd1,0xfd,
|
||||
0xbf,0xff,0x6f,0xf5,0x6b,0xbc,0x5b,0x3c,0xda,0xef,0x16,0xaf,0x16,0xff,0xcd,0xab,
|
||||
0xff,0x6f,0xff,0xd0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfc,0xbf,0xff,0xff,
|
||||
0xff,0x6c,0x03,0x10,0xc1,0xf3,0xff,0xf3,0x3a,0xf3,0xca,0xff,0xaf,0xf1,0xff,0xff,
|
||||
0xff,0xff,0xd9,0x96,0xa6,0x65,0xa6,0x66,0x6a,0x95,0x69,0x69,0x6a,0x5a,0x5a,0xff,
|
||||
0xff,0x5f,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,
|
||||
0xea,0x0f,0x50,0xc3,0xf3,0x7f,0xff,0xf3,0xf3,0xc3,0xff,0xaf,0xf1,0xff,0xff,0xff,
|
||||
0xff,0xd9,0x96,0xa6,0x65,0xa6,0x66,0x6a,0x95,0x69,0x69,0x6a,0x5a,0x5a,0xff,0xff,
|
||||
0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xd7,0xff,0xff,0x5f,0xc1,
|
||||
0x3f,0xf7,0x5e,0xf5,0xce,0x9e,0x5f,0x3f,0x17,0xff,0xf3,0xe1,0xff,0xff,0xff,0xff,
|
||||
0xd8,0xff,0xfa,0xfe,0x67,0xff,0xfe,0xbf,0x5a,0xff,0xff,0xaf,0xf5,0xff,0xff,0xff,
|
||||
0xf0,0x2f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xfd,0xff,0xf7,0xff,0xfd,0x4e,0x3d,
|
||||
0x3f,0xe7,0x0b,0xbf,0x8f,0xf9,0xff,0xeb,0xe3,0xff,0xe1,0xff,0xff,0xfc,0xff,0xc7,
|
||||
0x9f,0xff,0x3e,0x39,0xe5,0xff,0xcf,0x9b,0xf9,0xff,0xff,0xc5,0xff,0xff,0xfa,0xf0,
|
||||
0x5f,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,
|
||||
0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x20,0x00,0x20,
|
||||
0x00,0x01,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0xf0,0x4f,
|
||||
0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xbf,
|
||||
0x3f,0xff,0xff,0xbf,0xff,0xff,0xff,0xfb,0xf1,0xff,0xff,0xff,0xff,0xf7,0xff,0xf7,
|
||||
0xff,0xed,0xff,0xfb,0xfe,0xff,0x7f,0xff,0x7f,0xdf,0xff,0xff,0xdd,0xf0,0x3f,0xff,
|
||||
0xff,0xff,0xfe,0xf0,0xff,0xff,0xf3,0xff,0xf7,0xff,0xfe,0x5f,0xff,0xf7,0xff,0xff,
|
||||
0xdf,0xff,0xff,0xff,0xf7,0xfe,0x7b,0xf1,0xff,0xfd,0xfd,0xff,0xdf,0xdf,0xff,0x7d,
|
||||
0x73,0xf9,0xff,0xc3,0x7e,0xfe,0xff,0xef,0xd7,0xff,0xcf,0xd0,0xf0,0x6f,0xff,0xff,
|
||||
0xff,0xfe,0xf8,0x30,0x00,0x00,0x40,0x04,0x00,0x01,0x41,0x20,0x00,0x04,0x00,0x02,
|
||||
0xd5,0x09,0x00,0x02,0x80,0x02,0x01,0x00,0x00,0x00,0x0a,0x04,0x00,0x07,0x00,0x01,
|
||||
0x50,0x01,0x80,0x02,0x61,0x40,0x41,0x0c,0x14,0x08,0xc1,0xf0,0x9f,0xff,0xff,0xff,
|
||||
0xfe,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0xdf,0xcb,0x5f,0xfe,0xef,0xff,0xfe,
|
||||
0xff,0x3f,0xff,0x7f,0xfd,0xc1,0xff,0xff,0x7f,0xff,0xdf,0xfd,0xfc,0xfd,0xf7,0xee,
|
||||
0xff,0xff,0x4e,0xff,0xdf,0xcf,0xdb,0xeb,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0x7f,
|
||||
0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,
|
||||
0xf7,0xfb,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0x7f,0xff,0xff,0xff,0x7f,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xdd,0xff,
|
||||
0xff,0xff,0xa5,0xff,0x6f,0x6b,0xe9,0x6f,0xda,0xca,0xfb,0xdd,0xee,0xf7,0xf6,0xb2,
|
||||
0xb3,0xa4,0xa1,0x5b,0x5b,0xf6,0xd7,0xf4,0xf7,0x7b,0xbd,0xbd,0xad,0xcf,0xef,0x7f,
|
||||
0x6b,0x7f,0x3b,0xdf,0xdb,0xff,0xff,0x30,0xcf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,
|
||||
0xff,0xff,0xff,0xf6,0xfe,0x96,0xff,0xfd,0xb5,0xfd,0xbf,0xad,0x7f,0xff,0x6f,0xff,
|
||||
0xde,0xd1,0xad,0xad,0xe9,0xff,0xf1,0xec,0xef,0xde,0x3f,0xcb,0xff,0xf6,0xff,0x32,
|
||||
0xff,0xc5,0xbd,0xff,0xff,0xff,0xd0,0xbf,0xff,0xff,0xff,0xfe,0xfe,0xfb,0xff,0xf4,
|
||||
0x28,0xbf,0xff,0xfd,0xfb,0xd3,0xff,0xff,0x42,0xff,0xff,0xff,0xea,0xb3,0xfc,0xc3,
|
||||
0xc1,0xff,0x33,0xff,0xc0,0x15,0x6b,0x70,0xff,0xf0,0xf2,0x4f,0xff,0xfc,0x3e,0x97,
|
||||
0x3c,0xff,0xff,0xfd,0xef,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfe,0x78,
|
||||
0xbf,0xff,0xfd,0xf3,0xef,0x55,0xff,0x7e,0xff,0xff,0xff,0xea,0xb3,0xfc,0xc3,0xc1,
|
||||
0xff,0x33,0xff,0xc0,0x15,0x6f,0xff,0x0f,0xf0,0xf0,0x0f,0xff,0xfc,0x3d,0x6b,0xc3,
|
||||
0xff,0xff,0xfe,0xf7,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,
|
||||
0xff,0x23,0xf8,0x7f,0xff,0x4e,0xff,0xff,0xff,0xfb,0xf9,0x17,0xff,0xf6,0xf1,0xff,
|
||||
0xcf,0xef,0xff,0xff,0x13,0xdf,0xe6,0x2f,0xc7,0xff,0xff,0xe7,0xc1,0xfd,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xfe,0xae,0xff,
|
||||
0xff,0x7f,0x3b,0x3f,0xfc,0x7f,0xfc,0xef,0xff,0xfc,0xe2,0x7b,0xff,0xf1,0xfd,0xed,
|
||||
0xef,0xff,0xff,0x35,0x73,0xff,0xff,0xfe,0xfa,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,
|
||||
0xff,0xfa,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x80,0x00,0x00,0x40,0x00,0x00,0x00,0x0c,0x04,0x01,0x40,0x40,0x00,
|
||||
0x00,0x30,0x28,0x04,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,
|
||||
0x38,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xfb,0xff,0x7f,
|
||||
0xff,0xff,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xdf,0xdf,0xff,
|
||||
0xff,0xff,0xff,0xed,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xbf,0xbf,0xff,0xff,0xc3,
|
||||
0xf0,0x3f,0xff,0xff,0xff,0xfe,0xf0,0xbf,0xfd,0xff,0xbf,0xff,0xff,0xfd,0xff,0xff,
|
||||
0xff,0xff,0xff,0xfd,0x7b,0xff,0x7f,0xff,0xbd,0xff,0xf1,0xef,0xff,0xff,0xfd,0xdf,
|
||||
0xfd,0xfb,0xff,0xff,0xbf,0xbe,0xff,0xcd,0x7f,0xfc,0xf7,0xf7,0x6f,0xbf,0xd8,0xf0,
|
||||
0xef,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,0x00,0x00,0x04,0x00,0x00,0xa0,0x00,0x00,
|
||||
0xc0,0x00,0x00,0x20,0x34,0x00,0x00,0x00,0x0c,0x81,0x00,0x20,0xa4,0x20,0x00,0x10,
|
||||
0x08,0x04,0x48,0x08,0x00,0x40,0x93,0x00,0x10,0x00,0x38,0x18,0x20,0xc1,0xf0,0x3f,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xfb,0xff,0xff,0xb9,0xdf,0xfe,0xb3,0xff,0xff,0xe7,0xfd,
|
||||
0xff,0xff,0x3b,0xff,0x7f,0xff,0xbf,0xff,0xc1,0xff,0xfc,0xff,0xff,0x3f,0x77,0xfe,
|
||||
0xfe,0xcf,0xff,0xbf,0xfd,0xbf,0xff,0xfe,0xed,0xf2,0xfd,0xf7,0xff,0xf0,0x2f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xbf,0xff,0xff,
|
||||
0xff,0xfe,0xff,0xff,0xff,0xf3,0xad,0xcf,0xef,0x70,0xc9,0x73,0x3b,0xdf,0x5b,0x4a,
|
||||
0xf6,0xb7,0xfe,0xd7,0xf5,0xbc,0xc1,0x33,0xca,0xd6,0xb7,0x6e,0xf7,0xfb,0xbd,0xc5,
|
||||
0x24,0xcf,0x6f,0x2f,0x4d,0x2b,0xba,0x5a,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,
|
||||
0xfe,0xbf,0xff,0xff,0xff,0xff,0xf6,0xf6,0xd7,0xff,0xff,0xad,0xbd,0xff,0xff,0xff,
|
||||
0xef,0xf7,0x7f,0xfc,0x5b,0xb1,0xfd,0xbd,0x75,0x6f,0xef,0x6a,0xfd,0x5b,0xfb,0xdb,
|
||||
0x3a,0xbf,0x8e,0x9f,0xff,0xbf,0xfd,0xff,0x6f,0xff,0xd0,0x6f,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xbb,0xff,0xf0,0x3f,0xff,0xff,0xfd,0xfb,0x7f,0xde,0xff,0xff,0x5a,0xd6,0xbf,
|
||||
0xd8,0x2a,0xbf,0xbf,0xf1,0xe5,0xff,0xcc,0xc0,0xa9,0x70,0xff,0xf3,0x3c,0x3c,0xfd,
|
||||
0x57,0xfd,0x98,0x03,0x00,0xc3,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xff,0x3d,0xbf,0xff,0xfd,0xfb,0xff,0xdb,0xff,0xff,0x0f,0xfc,0x3f,0xd8,
|
||||
0x2a,0xbf,0xbf,0xf1,0xef,0xff,0xcc,0xc0,0x96,0xbe,0xff,0xf3,0x3f,0xff,0xfd,0x57,
|
||||
0xfd,0x99,0x0f,0xff,0xc3,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xff,0xff,
|
||||
0xff,0xf1,0xe7,0xff,0xff,0xf3,0x8e,0x7b,0xff,0xa8,0xff,0xdf,0x7f,0x8e,0x78,0x73,
|
||||
0xff,0xf1,0x51,0x62,0xff,0xfc,0x4b,0xff,0xf3,0xff,0x7e,0xcf,0xf9,0xff,0xfd,0xff,
|
||||
0xff,0x7f,0xff,0xe0,0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,
|
||||
0xfb,0xfd,0xae,0xff,0xfc,0xfe,0x6f,0x3f,0xf8,0xfd,0x77,0xaf,0xfe,0x37,0xfe,0x7b,
|
||||
0xff,0xb1,0x8c,0xff,0xef,0xfd,0xf8,0xe7,0xbf,0xff,0xf1,0xfe,0x3e,0xf7,0xfe,0x95,
|
||||
0x3e,0xbf,0xff,0xff,0xff,0xfa,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,0x00,
|
||||
0x01,0x04,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x08,
|
||||
0x41,0x80,0x10,0x00,0x00,0x08,0x10,0x84,0x00,0x0c,0x04,0x02,0x61,0x00,0x00,0x81,
|
||||
0x00,0x00,0x00,0x00,0x3d,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,
|
||||
0xff,0xff,0x7f,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
|
||||
0x7f,0xbf,0xf7,0x7f,0xef,0xff,0xef,0xff,0xf7,0xfd,0xff,0xff,0xfd,0x7f,0xff,0xbe,
|
||||
0xdf,0xff,0xff,0xd9,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xff,0x7f,0xfb,0xff,
|
||||
0xfb,0xff,0xbf,0xff,0xf3,0x7f,0xfb,0xfd,0xeb,0x7f,0xdf,0xfa,0xff,0xde,0xf0,0xed,
|
||||
0xff,0xb1,0xf7,0xf9,0x1f,0xb5,0x5b,0xfe,0x7e,0xf7,0xbe,0xfd,0x7f,0x5f,0xb5,0xf7,
|
||||
0xff,0xff,0xd0,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x01,0x00,0x07,0x42,0x01,
|
||||
0x00,0x6a,0x18,0x50,0x80,0x00,0x00,0x02,0x40,0x01,0x01,0x20,0x01,0x01,0x24,0x14,
|
||||
0x21,0x10,0x02,0x08,0x07,0x08,0x00,0x40,0x10,0x80,0x58,0x00,0x84,0x80,0x18,0x10,
|
||||
0x40,0xc1,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xff,0xdb,0xb7,0xf3,
|
||||
0xdf,0x7c,0xf8,0x74,0xff,0xff,0x6f,0x7d,0x3f,0x7e,0xec,0x7f,0xc1,0xf5,0xff,0xcf,
|
||||
0x6f,0x9f,0xf9,0xdf,0xbe,0xe5,0xe7,0xff,0xd7,0xf3,0xdd,0xfb,0xff,0xfc,0xff,0xbf,
|
||||
0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xf0,0x2f,0xff,0xff,0xff,0xfe,0xd7,0xff,0xff,0xff,0xb4,0xcf,0xef,0x77,0x6f,0x73,
|
||||
0x3a,0x4a,0x3a,0xcb,0xd4,0xf7,0x2e,0xd6,0xbd,0xbd,0xa1,0x3b,0xdf,0xd6,0xf7,0xee,
|
||||
0xd3,0x35,0xbd,0xfb,0xbd,0xce,0xeb,0x2b,0x4d,0x2f,0xbb,0xda,0xff,0xff,0xfe,0xb0,
|
||||
0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdf,0x5f,0x36,0xaf,0x3f,0xed,0xb7,
|
||||
0xf5,0xfd,0xf3,0x2b,0xef,0x77,0xff,0xfb,0xda,0xb1,0xbd,0xa3,0x77,0x69,0x7f,0x4f,
|
||||
0xff,0xdb,0xfa,0x5b,0xff,0xf2,0xfe,0xff,0x96,0xff,0xff,0xfe,0xdf,0xff,0xd0,0xaf,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x8f,0xfd,0x40,0x6f,0x9e,0x83,0x5a,0x0f,
|
||||
0xfa,0xc3,0xff,0xff,0xfc,0xe9,0x7f,0xf3,0x01,0xd0,0x00,0xfe,0xbf,0xcd,0x3f,0xf0,
|
||||
0xef,0xfc,0xc5,0x0c,0x3f,0xfd,0x68,0x0b,0xff,0xff,0xff,0xfe,0xdf,0xf0,0xff,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xbb,0xff,0xfd,0x85,0xff,0xd4,0x6f,0x9f,0xc3,0x5a,0x0f,0xff,
|
||||
0xff,0xff,0xff,0xfc,0xe9,0x7f,0xf3,0x01,0xf0,0xfb,0xc2,0xbf,0xfc,0x00,0x37,0xef,
|
||||
0xfc,0xcd,0xbc,0x3f,0xff,0x0c,0xbf,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,
|
||||
0xff,0xfe,0xff,0xff,0xff,0xff,0xd9,0xf7,0xd1,0xb7,0x7e,0x7f,0xf1,0xe4,0xfd,0xff,
|
||||
0xfb,0xfb,0xff,0x5f,0xff,0x7f,0xb1,0xbc,0x0f,0x67,0xeb,0xb8,0x3f,0xff,0xe2,0xff,
|
||||
0xe9,0xff,0xfd,0xe3,0xff,0x3f,0x9f,0xc2,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,
|
||||
0xfe,0xf5,0x7f,0xff,0xf0,0x3f,0xbc,0xff,0xd5,0xf5,0xce,0x3f,0xfe,0xff,0xfe,0x6d,
|
||||
0xff,0xf1,0xbf,0x7b,0xff,0xf1,0xfd,0xff,0x4f,0xff,0x87,0xff,0xae,0xff,0xb1,0xf8,
|
||||
0xfe,0xff,0xff,0x78,0x01,0xb9,0xff,0xff,0xff,0xfa,0xf0,0x2f,0xff,0xff,0xff,0xfe,
|
||||
0xf3,0xc0,0x00,0x00,0x00,0x04,0x02,0x13,0x02,0x00,0x80,0x40,0x00,0x90,0x10,0x00,
|
||||
0x10,0x00,0x02,0x00,0x01,0x20,0x80,0x12,0x10,0x00,0x40,0x08,0x00,0x04,0x00,0x00,
|
||||
0x02,0x00,0x01,0x40,0x00,0x80,0x00,0x00,0x3c,0xf0,0xef,0xff,0xff,0xff,0xfe,0xfd,
|
||||
0x1f,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0x7f,0xff,0x7f,0xf7,0xdf,0xf7,0xff,
|
||||
0xf7,0xfb,0xeb,0xd1,0xff,0xff,0xff,0xff,0xef,0xf7,0xff,0xff,0xfb,0xff,0xfe,0xff,
|
||||
0xff,0x7e,0xff,0xfb,0xff,0xff,0xff,0xdb,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf0,0xff,
|
||||
0xff,0xb7,0xeb,0xf7,0xdf,0xff,0xfe,0xf5,0x6b,0xe7,0xed,0xf7,0x3e,0xec,0xff,0x54,
|
||||
0xef,0x6f,0xf1,0xf5,0xaf,0x6f,0xf6,0xfd,0xff,0xdd,0x7b,0xff,0xef,0xbf,0x7f,0xff,
|
||||
0xff,0xf7,0xff,0xf3,0x5f,0xf7,0xd0,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x00,
|
||||
0x80,0x40,0x04,0x00,0x81,0x2c,0x04,0x24,0x00,0x02,0x01,0xc8,0x02,0x00,0x02,0x24,
|
||||
0x00,0x01,0xb4,0x42,0xdc,0x44,0x02,0x15,0x90,0x02,0x03,0x48,0x39,0x10,0x02,0x24,
|
||||
0xa0,0xba,0x00,0x00,0x40,0xc1,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
|
||||
0xfe,0xfc,0xf7,0xf0,0xee,0xb6,0x5d,0xfd,0xf5,0xff,0xdb,0xf7,0x7f,0x7f,0xbe,0xff,
|
||||
0xc1,0xfe,0xbf,0xfa,0xfa,0x5f,0xff,0xad,0xff,0xef,0xff,0x7f,0xdf,0x7f,0xfe,0xbf,
|
||||
0xb7,0x94,0xbf,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xd7,0xff,0xff,0xfb,0xb5,0xff,
|
||||
0xef,0x7c,0xeb,0x2b,0x52,0x5b,0x3b,0xda,0xd4,0xf3,0x36,0x96,0xb5,0xbd,0xf1,0xfb,
|
||||
0xda,0xee,0xf6,0xfe,0xd3,0x35,0xbd,0xdf,0xad,0xcf,0xef,0x7e,0xcd,0x6b,0xbb,0xdf,
|
||||
0xff,0xff,0xfd,0xb0,0xef,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xd3,0x5f,0xf6,
|
||||
0xff,0xf6,0xff,0xfd,0xad,0xfd,0xff,0x7f,0xef,0xff,0x6f,0x7f,0xdb,0xf1,0xa5,0xa3,
|
||||
0x7f,0x6f,0x6b,0x4f,0xff,0xdb,0xfb,0xcb,0xff,0xf6,0xff,0xf4,0xd7,0xfd,0xbf,0xfe,
|
||||
0xdf,0xff,0xd0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdf,0xff,0xff,0xff,
|
||||
0x3f,0x7f,0xfc,0xe5,0xff,0x20,0xfe,0xff,0xff,0xdf,0x7f,0xff,0xf1,0x7f,0xff,0xfe,
|
||||
0xff,0xf0,0x7c,0x3d,0x4f,0xf3,0xc3,0x3f,0xff,0xff,0x6f,0xc3,0xff,0x0f,0xff,0xff,
|
||||
0xaf,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xfb,0xb7,0xe0,0x0f,0xff,0xff,0x2b,
|
||||
0xff,0x7d,0xbf,0xff,0xdf,0xff,0xff,0xf8,0x9f,0x7f,0xff,0xf1,0x55,0xff,0xff,0xff,
|
||||
0xfd,0x7c,0x3c,0xff,0xf3,0xc3,0x3f,0xff,0xff,0xef,0xc3,0xff,0xdf,0xff,0xff,0xff,
|
||||
0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xef,0xff,0xff,0x9f,0xbf,0x7f,
|
||||
0xf9,0x19,0x47,0x8e,0xe7,0x9f,0x3f,0x17,0xff,0xfc,0x81,0xc1,0x7e,0xf3,0xd9,0xf9,
|
||||
0x73,0xdf,0xf4,0x7f,0xfa,0xff,0xff,0xff,0xfb,0x7f,0x77,0xc7,0xff,0xff,0xff,0xf0,
|
||||
0x2f,0xff,0xff,0xff,0xfe,0xf5,0xf7,0xff,0xfb,0xff,0xf7,0x3f,0xfc,0xbf,0x3e,0x3f,
|
||||
0xec,0xff,0x81,0xaf,0xfe,0x4f,0xf3,0xbb,0xff,0xf0,0x7e,0xff,0x6f,0xff,0x87,0xff,
|
||||
0xbb,0xff,0xd5,0xfc,0xff,0x7f,0xfc,0x6f,0xff,0xef,0xe7,0xff,0xff,0xfa,0xf0,0x3f,
|
||||
0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0x00,0x30,0x10,0x60,0x20,0x00,0x08,0x00,0x01,0x20,0x80,0x00,0x10,0x00,0x04,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x80,0x40,0x00,0x08,0x20,0x3c,0xf0,0x6f,0xff,
|
||||
0xff,0xff,0xfe,0xf5,0xbf,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0x7f,0xfe,0x3f,0xff,
|
||||
0xff,0xff,0xff,0xff,0xef,0xff,0xff,0xf1,0xdf,0xdf,0xff,0xff,0xff,0x7f,0xdf,0xff,
|
||||
0xfd,0xbd,0xff,0xff,0xff,0xfb,0xdf,0xff,0xff,0xff,0xff,0x5b,0xf0,0xff,0xff,0xff,
|
||||
0xff,0xfe,0xf0,0xbf,0xbf,0xbf,0xff,0xf7,0xfb,0xff,0xfe,0xee,0xfa,0xff,0xff,0xff,
|
||||
0x3d,0x3b,0xff,0xff,0xfe,0xfb,0xf1,0xff,0xbf,0x7b,0xff,0xff,0xef,0xff,0xbf,0xff,
|
||||
0xff,0xff,0xff,0xff,0xfe,0xff,0xf7,0xef,0xff,0xfb,0xd0,0xf0,0xdf,0xff,0xff,0xff,
|
||||
0xfe,0xf8,0x30,0x00,0x00,0x00,0x00,0x00,0x0b,0x10,0x05,0x01,0x00,0x08,0x00,0x02,
|
||||
0x01,0x01,0x00,0x00,0x10,0x01,0xc8,0x08,0x00,0x00,0x00,0x00,0x42,0x02,0x00,0x00,
|
||||
0x00,0x80,0x02,0x00,0x00,0x40,0x24,0x80,0x00,0xc1,0xf0,0x3f,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0xf7,0xfd,0xf7,0xfa,0xef,0xee,0xf9,0xfd,0xff,0xf7,0xfe,0xbf,
|
||||
0x1f,0xfd,0x9e,0xfd,0xd1,0xef,0xff,0xf7,0x7f,0x9f,0xff,0xef,0xff,0xf6,0xff,0xfe,
|
||||
0xfe,0x7b,0xff,0xbd,0xff,0x7e,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xff,0xff,
|
||||
0xff,0xf7,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xdf,0xfd,0xff,0xff,0xdf,0xff,
|
||||
0xff,0x5f,0xf1,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xef,0xff,
|
||||
0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0xfb,0xff,0xff,0xef,0xfb,0xfd,
|
||||
0xff,0xf1,0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xf7,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0xff,0xe7,0xff,
|
||||
0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xcf,0xff,0xfb,0xff,0xfb,0xf1,
|
||||
0xff,0xff,0xfb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7b,0xff,0xff,0xff,0x7f,0xff,0xf1,0xff,
|
||||
0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xef,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0x57,0xff,0xfe,0xbf,0xfb,0xf1,0xff,0xff,
|
||||
0xfd,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xd7,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdb,0xff,0xdb,0xfd,
|
||||
0xf6,0xff,0xf6,0xff,0x3c,0xbc,0xbc,0xbf,0xdf,0x6f,0xef,0x2f,0xf1,0x3c,0xbf,0xbc,
|
||||
0xbf,0xdf,0x6f,0xff,0x6f,0xf7,0xdb,0xff,0xdb,0xfd,0xf6,0xff,0xf6,0xff,0xff,0xff,
|
||||
0x01,0xe2,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff };
|
343
drivers/net/hamradio/yam9600.h
Normal file
343
drivers/net/hamradio/yam9600.h
Normal file
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
*
|
||||
* File yam111.mcs converted to h format by mcs2h
|
||||
*
|
||||
* (C) F6FBB 1998
|
||||
*
|
||||
* Tue Aug 25 20:23:03 1998
|
||||
*
|
||||
*/
|
||||
|
||||
static unsigned char bits_9600[]= {
|
||||
0xff,0xf2,0x00,0xa5,0xad,0xff,0xfe,0x9f,0xff,0xef,0xfb,0xcb,0xff,0xdb,0xfe,0xf2,
|
||||
0xff,0xf6,0xff,0x9c,0xbf,0xfd,0xbf,0xef,0x2e,0x3f,0x6f,0xf1,0xfd,0xb4,0xfd,0xbf,
|
||||
0xff,0x6f,0xff,0x6f,0xff,0x0b,0xff,0xdb,0xff,0xf2,0xff,0xf6,0xff,0xff,0xff,0xff,
|
||||
0xf0,0x6f,0xff,0xff,0xff,0xfe,0xff,0xfd,0xdf,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,
|
||||
0xfb,0xff,0xff,0xf7,0xff,0xff,0xff,0xfe,0xff,0x7f,0xf1,0xff,0xfe,0xff,0xbf,0xbf,
|
||||
0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xff,0xff,0xfe,0xff,0xfe,0xff,0xff,0xff,0xf0,
|
||||
0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xf7,
|
||||
0xff,0xff,0xf7,0xef,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0x7e,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xf0,0xdf,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xef,0xff,0xf3,0xfb,0xfe,0xff,0xf1,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xdf,0xff,0xf0,0x7f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xdf,0xff,0xff,0xff,0xf7,0xf1,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,0xff,
|
||||
0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf5,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,
|
||||
0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0xff,0xef,0xff,0x7f,0xff,0xef,
|
||||
0xff,0xef,0xff,0x7f,0xef,0xf1,0xff,0xef,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xff,0xbd,0xff,0xef,0x7f,0xef,0x7f,0xfb,0xdf,0xd3,0x5a,0xfe,0xd7,0xd6,
|
||||
0xf7,0x7f,0xbd,0xf1,0xbb,0x5d,0xd6,0xf7,0xfe,0x96,0xff,0xbd,0xaf,0xad,0xbf,0xef,
|
||||
0x7f,0x6b,0x7f,0xfb,0xd6,0xfe,0xf7,0xff,0x10,0xef,0xff,0xff,0xff,0xfe,0xbe,0xef,
|
||||
0xff,0xff,0xdb,0xff,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xbf,0xff,0x7f,0xff,0x7f,
|
||||
0xdf,0xdb,0xf1,0xfd,0x35,0xff,0x6f,0xff,0x6f,0xff,0xdb,0xff,0xcb,0xff,0xf6,0xff,
|
||||
0xf2,0xfd,0xfd,0xbf,0xff,0xff,0xff,0xd0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xcc,0xc0,0x3f,0xff,
|
||||
0xff,0xf1,0x24,0xf0,0xff,0xff,0xcf,0xef,0x3f,0xff,0xf0,0xff,0xff,0xff,0xfc,0x3f,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x55,0xff,0xcc,0xc0,0x3f,0xff,0xff,
|
||||
0xf1,0x00,0xf0,0xff,0xff,0xcf,0xdf,0xff,0xff,0xf0,0xff,0xff,0xff,0xfc,0x3f,0xff,
|
||||
0xff,0xff,0x7d,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xfe,0x7f,0xdf,0xff,0xff,0xff,0xf1,
|
||||
0xff,0xcf,0xff,0xf3,0xff,0x97,0xff,0xff,0x8f,0xe7,0xff,0xff,0xfc,0x71,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xf5,0xff,0xbf,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xe3,0xf7,0xef,0xff,0xff,0xfc,0x7b,0xff,0xf1,0x3f,
|
||||
0xff,0xef,0xff,0xcf,0xe3,0xe3,0xff,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xbf,0xff,
|
||||
0xbf,0xff,0xda,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf2,0xc0,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
|
||||
0x01,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xdb,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0x9f,0xff,
|
||||
0xff,0xff,0xf7,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xdb,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf0,0xbb,0xdf,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xdf,0xbf,0xf1,0xfe,0xfd,0xf7,0xff,
|
||||
0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x77,0xfd,0xf2,
|
||||
0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf8,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,
|
||||
0x00,0x00,0x00,0x02,0x00,0x90,0x00,0x00,0x00,0x0c,0x01,0x00,0x00,0x04,0x24,0x00,
|
||||
0x40,0x01,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x01,0xc0,0xf0,
|
||||
0x4f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xbf,0xff,0xff,0x6f,0xff,0xdf,0xff,0xd1,0xff,0xfe,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xdf,0xff,0xfb,0xff,0xfb,0xef,0xff,0xff,0xee,0xff,0xff,0x7f,0xf0,0xdf,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xad,0xff,0x69,0x2a,0xed,0x6b,0xfb,0xdf,0x3a,
|
||||
0xdc,0xf4,0x96,0xee,0xb3,0x3d,0x35,0xc1,0xbb,0xdd,0xfe,0xf6,0xfe,0xd6,0xb5,0xad,
|
||||
0xbf,0xa5,0xad,0x49,0x2f,0x4f,0x2b,0xda,0x5f,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,
|
||||
0xff,0xfe,0xbf,0xff,0xff,0xfb,0x5b,0xf7,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xa5,
|
||||
0xf3,0x6f,0xf3,0x6e,0xfa,0x7b,0xd1,0xfd,0xb5,0x77,0x6f,0xe9,0x6f,0xff,0xdb,0xfb,
|
||||
0xdb,0xdf,0xf6,0xff,0xf6,0xff,0xfd,0x3f,0xfe,0xf7,0xff,0xd0,0x4f,0xff,0xff,0xff,
|
||||
0xfe,0xff,0x9f,0xff,0xff,0x0f,0xff,0xc0,0x3f,0x9c,0x03,0xff,0xff,0x8b,0xa5,0xfe,
|
||||
0x80,0x3e,0xc2,0xbf,0xac,0xb1,0x24,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,0xa3,
|
||||
0xff,0xfd,0x6b,0xff,0xff,0xf0,0xa5,0xff,0xff,0xff,0xf0,0xaf,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0x0f,0xff,0xc0,0x3f,0xd4,0x6b,0xff,0xff,0xdb,0xff,0xfe,0x86,
|
||||
0xbf,0xc2,0xbf,0x30,0xa1,0x24,0xff,0xff,0xff,0xff,0xcc,0xff,0x0f,0xff,0xa3,0xff,
|
||||
0x05,0x6b,0xff,0xff,0xf0,0xa5,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xfb,0xc7,0xff,0xc4,0xff,0xff,0x7f,0xff,0xec,0xfe,0x7f,0xdf,0xd8,0xb9,
|
||||
0x47,0xfc,0x36,0xc1,0xdf,0xff,0xff,0xf9,0xff,0xf3,0xff,0xf7,0xff,0xfc,0xff,0xfd,
|
||||
0x3f,0xff,0xff,0xff,0x3f,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf5,0xff,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0x7e,0xbd,0x3f,0xff,0x2b,0xfe,0x2f,0xf5,0xa3,0xfc,
|
||||
0x5b,0xfe,0x61,0x9f,0x7f,0xef,0xff,0xff,0xa7,0xfb,0xff,0xff,0xfa,0xfe,0xff,0x33,
|
||||
0xf1,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xf1,0xc0,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x30,0x24,0x04,
|
||||
0x00,0x01,0x00,0x80,0x40,0x00,0x08,0x00,0x00,0x00,0x02,0x01,0x01,0x00,0x02,0x00,
|
||||
0x00,0x00,0x00,0x00,0x01,0x3d,0xf0,0x2f,0xff,0xff,0xff,0xfe,0xfd,0xbd,0xff,0xfd,
|
||||
0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xff,0x7f,0xf6,0xef,0xbf,0xf7,0xff,0x73,0xeb,
|
||||
0xf1,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xff,0xf9,0xff,0xfd,0xfe,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xd9,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf0,0xbf,0x7f,0xff,0xff,
|
||||
0xff,0x7f,0xff,0xff,0xde,0xff,0xff,0xef,0xdd,0xde,0x77,0xf2,0xfb,0xed,0xe7,0xf1,
|
||||
0x73,0xfd,0xfd,0xdf,0xff,0x7d,0xbe,0xdf,0xff,0xfb,0xff,0xef,0xff,0xef,0xff,0xff,
|
||||
0xff,0xff,0xff,0xd0,0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x20,0x02,0x00,0x22,
|
||||
0x40,0xc0,0x00,0x00,0x00,0x08,0x00,0x02,0x41,0x02,0x12,0x00,0x21,0x87,0x81,0x00,
|
||||
0x00,0x80,0x04,0x0b,0x28,0x01,0xb0,0x00,0x82,0x00,0x40,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0xc1,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xfd,0xff,
|
||||
0xf7,0xff,0xfe,0x7f,0xed,0x79,0xff,0xde,0xeb,0x7f,0x74,0xf7,0xf7,0xe1,0xf9,0xff,
|
||||
0xf6,0x5f,0x7f,0xff,0xff,0xff,0xd7,0xdb,0xef,0xff,0xbb,0xff,0xff,0xff,0xcc,0xff,
|
||||
0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xf0,0x0f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x3d,0xcd,0x49,0x7f,0x6f,
|
||||
0x2b,0xba,0x5c,0xd2,0xda,0xf6,0xf3,0x3e,0xf7,0xff,0xbd,0xf1,0xfa,0xdf,0xfe,0xf7,
|
||||
0xcc,0xf6,0xbb,0xa5,0xb3,0xad,0xbf,0x6f,0x7d,0x6f,0x6b,0xdb,0xdf,0xbd,0xff,0xfe,
|
||||
0xb0,0x5f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xfb,0xdb,0x57,0xf6,0xfe,0x9f,0xd5,
|
||||
0xb7,0xff,0xaf,0xe5,0x3f,0xff,0xff,0x6f,0xff,0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0x69,
|
||||
0x6c,0xdf,0xda,0xdf,0xcb,0xff,0xf6,0xff,0x76,0xfd,0xfd,0xbf,0xff,0xff,0xff,0xd0,
|
||||
0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfd,0xbd,0x08,0x03,0x89,0x4f,0x5a,
|
||||
0x0f,0xf0,0xff,0xf8,0xbf,0xff,0xff,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,0xff,0xf3,
|
||||
0xfa,0xa0,0xf0,0xf2,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xfd,0x00,0x6b,0xff,0xff,0x5a,0x0f,
|
||||
0xf0,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,0xff,0xb3,0xf5,
|
||||
0x50,0xf0,0xf0,0xff,0xff,0xff,0xd7,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x7f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xbc,0xff,0xe4,0xe7,0x71,0xff,0xf9,0xc4,0xf4,
|
||||
0x7f,0x7f,0xcf,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xfb,0xf7,0x73,0xbf,0x14,
|
||||
0xff,0xe6,0xff,0xff,0xe1,0x7d,0xff,0xff,0xe7,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,
|
||||
0xff,0xfe,0xf5,0xff,0xff,0xfe,0xd2,0xfa,0xff,0xc4,0xf4,0x5c,0xbf,0xfa,0xff,0xff,
|
||||
0xec,0x7e,0xbf,0xff,0xff,0xff,0xf1,0xff,0xff,0xef,0xff,0xff,0x6b,0xdb,0xff,0xdf,
|
||||
0xf9,0xfb,0xbf,0xff,0xf1,0xff,0xbf,0xff,0xff,0xff,0xfb,0xf0,0xbf,0xff,0xff,0xff,
|
||||
0xfe,0xf3,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x82,0x00,0x00,0x00,0x00,0x80,0x00,
|
||||
0x00,0x00,0x00,0x40,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x20,0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0x01,0x00,0x00,0x80,0x02,0x00,0x01,0x3c,0xf0,0x5f,0xff,0xff,0xff,0xfe,
|
||||
0xfd,0xbf,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0x7f,0xff,0xdf,0xff,0xef,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xf7,0xff,0xfb,0xff,0xfd,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xfd,0xff,0xff,0xc3,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf0,
|
||||
0xff,0xdf,0xff,0xff,0xf7,0x23,0xff,0xff,0xfd,0xff,0xef,0xff,0xfe,0x7f,0x7d,0xf7,
|
||||
0xfe,0xff,0x7f,0x71,0xff,0xfb,0x7f,0xff,0xff,0xff,0x6e,0xfd,0xf7,0xfd,0xff,0xbf,
|
||||
0xff,0xbf,0xf9,0xfd,0xff,0xdf,0xef,0xf0,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xf8,0x30,
|
||||
0x40,0x01,0x00,0x83,0x00,0x00,0x00,0x0c,0x06,0x08,0x04,0x26,0x26,0x00,0x00,0x06,
|
||||
0x03,0x00,0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x70,0x08,0x80,0x00,0x20,0x01,0x20,
|
||||
0x00,0x02,0x00,0x30,0x00,0x00,0xc1,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xff,0x7b,0x3f,0xf7,0xff,0xd7,0xfe,0xfe,0xfb,0xfe,0x3b,0xfe,0xbd,0xff,0x2f,
|
||||
0xff,0x71,0xff,0xfb,0x7f,0xe7,0xff,0xf9,0xef,0xff,0xd7,0xfa,0xff,0xb7,0xbb,0xfe,
|
||||
0xff,0xff,0x74,0xff,0xf7,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xb5,
|
||||
0xbd,0x6f,0x7c,0xeb,0x7f,0xfb,0xdb,0xd3,0x4b,0xee,0xd6,0xf6,0xb7,0xfd,0xac,0xa1,
|
||||
0xfb,0xdf,0xfe,0xf7,0xf4,0x96,0xbd,0xb4,0xc5,0xa5,0xaf,0x6f,0x69,0x4f,0x7f,0xba,
|
||||
0xdb,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,
|
||||
0xf6,0xff,0xf6,0xff,0xbd,0xbf,0xa5,0xbf,0xff,0x7d,0x7f,0xef,0xff,0xfb,0xf1,0xfd,
|
||||
0xbf,0xff,0x6f,0xff,0x6b,0x7a,0xdb,0xff,0xdb,0xdf,0xf6,0xfe,0xb6,0xfd,0xfd,0xbf,
|
||||
0xfe,0xf7,0xff,0xd0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xf4,0x2f,0xff,
|
||||
0xfc,0x43,0x6b,0xff,0xff,0xff,0x0d,0xff,0xfc,0x33,0x3f,0xf0,0x5f,0xf1,0xff,0xff,
|
||||
0xff,0xff,0xf9,0xde,0xf0,0x4c,0xfe,0x77,0xaf,0xff,0xff,0xef,0xff,0xf0,0xff,0xdb,
|
||||
0xff,0x5f,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xfe,0xf7,0xff,0xf0,0x2f,0xff,0xfd,
|
||||
0x43,0x7f,0xff,0xff,0xf1,0x0f,0xff,0xfc,0x33,0x3f,0xff,0xaf,0xf1,0xff,0xff,0xff,
|
||||
0xff,0xf6,0xd7,0xff,0xbc,0xfd,0xbd,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,
|
||||
0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0xfb,0xf1,
|
||||
0xbf,0xff,0xf9,0xfd,0xcf,0xf2,0x70,0xff,0x1f,0x9f,0xf3,0xf1,0xff,0xff,0xff,0xff,
|
||||
0xfc,0xf7,0xff,0x13,0x9f,0xfc,0xff,0xff,0x84,0xf7,0xff,0xff,0x47,0xff,0xff,0xff,
|
||||
0xf0,0xbf,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xf1,0xfc,0xff,0xfe,0xfe,0x79,
|
||||
0x3f,0xff,0x1d,0x46,0xcf,0xff,0xcf,0xfc,0x7b,0xff,0xf1,0xff,0xff,0xff,0xff,0xed,
|
||||
0xf3,0xab,0xff,0xcb,0xff,0xf8,0xff,0xfc,0xf5,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,
|
||||
0x8f,0xff,0xff,0xff,0xfe,0xf3,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,
|
||||
0x00,0x00,0x20,0x00,0x20,0x00,0x00,0x04,0x08,0x01,0x00,0x00,0x00,0x00,0x00,0x20,
|
||||
0x0c,0x00,0x00,0x04,0x01,0x00,0x01,0x00,0x00,0x80,0x00,0x00,0x01,0x3c,0xf0,0x7f,
|
||||
0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xfd,0xfe,0xff,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xdf,0xff,0xff,0xf7,0xff,0xff,0xff,0xef,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xeb,
|
||||
0xff,0xdf,0xff,0xff,0xfb,0xf7,0x7f,0xff,0xfe,0xff,0xff,0xbf,0xdb,0xf0,0xff,0xff,
|
||||
0xff,0xff,0xfe,0xf0,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0x7f,0xf7,0xff,
|
||||
0xbf,0xbf,0xcf,0xff,0xff,0xff,0x3e,0xf1,0x7f,0xff,0xff,0xef,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xfd,0xff,0xbf,0xbd,0xfe,0xff,0xfb,0xf7,0xdf,0xfb,0xd0,0xf0,0x9f,0xff,0xff,
|
||||
0xff,0xfe,0xf8,0x30,0x20,0x00,0x40,0x01,0x80,0xc0,0x30,0x00,0x00,0x20,0x00,0x10,
|
||||
0x50,0x88,0x20,0x00,0x00,0x13,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,
|
||||
0x00,0x00,0x01,0x80,0x08,0x00,0x00,0xa0,0x00,0x10,0xc1,0xf0,0xef,0xff,0xff,0xff,
|
||||
0xfe,0xfd,0xef,0x7f,0xff,0xff,0xbf,0xff,0xf7,0xff,0xef,0xfb,0xfd,0x77,0xef,0xbf,
|
||||
0xf7,0x7f,0xff,0xff,0xbf,0xd1,0x7f,0xff,0xff,0xf7,0xff,0xff,0xff,0xff,0xaf,0xff,
|
||||
0xdf,0xf7,0xfb,0xff,0xfd,0xff,0xfc,0xff,0xfd,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xe0,0x3f,0xff,0xff,0xff,0xfe,0xdd,0xff,
|
||||
0xff,0xff,0xa5,0xfd,0x6f,0x7d,0x6d,0x7f,0x52,0xdf,0x5a,0x4b,0xee,0xb6,0xee,0xf2,
|
||||
0xbb,0xac,0xa1,0x5b,0x4d,0xd6,0xf7,0xfe,0xb2,0xbd,0x35,0xb5,0xb5,0xdd,0x6f,0x7f,
|
||||
0xe9,0x5f,0x52,0xdf,0xbd,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,
|
||||
0xff,0xdb,0xfe,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfd,0xb5,0xbf,0xf9,0x7f,0x6f,0xff,
|
||||
0xdb,0xf1,0xfd,0xbf,0xff,0x6f,0xff,0x69,0x7f,0xdb,0xff,0xd3,0xff,0xf6,0xfe,0xf2,
|
||||
0xff,0xad,0xbf,0xff,0xff,0xff,0xd0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,
|
||||
0x30,0x0f,0xff,0xff,0xfd,0x6b,0xca,0xff,0xf0,0x0f,0xd6,0xbf,0xcf,0x3f,0xff,0xff,
|
||||
0xf1,0xff,0xff,0xff,0xca,0xfe,0xbf,0xff,0xf0,0x05,0xaf,0x0f,0xff,0xfc,0xf0,0xcf,
|
||||
0xf0,0xff,0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0x30,
|
||||
0x0f,0xff,0xff,0xfc,0x3f,0xca,0xff,0x0f,0x0f,0xd6,0xbf,0xff,0xff,0xf5,0x5f,0xf1,
|
||||
0xff,0x8b,0xff,0xc3,0xff,0xff,0xff,0xff,0xff,0xff,0x0f,0xff,0xfc,0xf0,0xcf,0xf0,
|
||||
0xff,0xff,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xcf,0xff,
|
||||
0xff,0xbf,0x9f,0x3f,0xfe,0xfc,0xff,0x4f,0xff,0xff,0xff,0xff,0xff,0xf7,0xf1,0xff,
|
||||
0xdf,0xfe,0x7e,0x3f,0x9f,0xf4,0xfc,0x7f,0xfc,0xff,0xff,0x3f,0xff,0x3f,0xfe,0x3f,
|
||||
0xff,0xff,0xff,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xfb,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xff,0xbf,0xfb,0xff,0xf8,0xed,0xff,0x8f,0xff,0xbb,0xff,0xb1,0xf3,0xef,
|
||||
0x8f,0xf7,0xff,0xff,0xdb,0xff,0xff,0xff,0xef,0xbf,0xfd,0x79,0xbf,0xbf,0xff,0xff,
|
||||
0xff,0xfb,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x00,0x04,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x04,0x08,0x08,0x01,0x01,0x00,0x90,
|
||||
0x00,0x00,0x00,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x04,0x00,0x00,0x01,
|
||||
0x3c,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0x9f,0xff,0xaf,0xdf,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,
|
||||
0xbf,0xef,0xff,0xff,0xff,0xed,0xff,0xff,0xff,0xef,0xff,0xbf,0xff,0xff,0xff,0xc3,
|
||||
0xf0,0x3f,0xff,0xff,0xff,0xfe,0xf0,0xff,0xfd,0xff,0xff,0xff,0xfb,0xff,0xbb,0xff,
|
||||
0xff,0xff,0x7f,0xf6,0xff,0x7f,0xfb,0xfd,0xed,0xff,0xf1,0xff,0xfe,0x7f,0xff,0xff,
|
||||
0xff,0x5f,0xff,0xf7,0xff,0x7e,0xff,0xfd,0xff,0xef,0xff,0xff,0xff,0xef,0xf0,0xf0,
|
||||
0x8f,0xff,0xff,0xff,0xfe,0xf8,0x30,0x80,0x00,0x04,0x00,0x00,0x40,0x02,0x00,0x03,
|
||||
0x00,0x05,0x04,0x20,0x00,0x00,0x01,0xd0,0x00,0x81,0x00,0x20,0x04,0x04,0x00,0x00,
|
||||
0x81,0x04,0x08,0x80,0x10,0x00,0xc0,0x00,0x00,0x00,0x20,0x00,0x08,0xc1,0xf0,0x6f,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xf3,0xfd,0xff,0xed,0xfc,
|
||||
0xff,0xff,0x9f,0xfb,0xfd,0xff,0xff,0xff,0xf1,0xff,0xff,0x7f,0xfb,0x3e,0xff,0x9f,
|
||||
0xff,0xff,0xff,0xff,0xfd,0xf9,0xff,0xff,0xff,0xfd,0xff,0xff,0xff,0xf0,0x6f,0xff,
|
||||
0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,
|
||||
0xff,0xfe,0xff,0xff,0xff,0xfd,0xbd,0xff,0xef,0x7c,0xeb,0x7f,0xfb,0xdb,0xfa,0xdc,
|
||||
0xee,0xf7,0xf6,0xd7,0xf5,0x2d,0xa1,0xbb,0xdd,0xee,0xf7,0x54,0xf7,0xfb,0x2c,0xb5,
|
||||
0xb4,0xbd,0x6b,0x6f,0xef,0x6f,0xbb,0xdf,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,
|
||||
0xfe,0xbf,0xff,0xff,0xff,0xfb,0xff,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xff,0xbf,0xef,
|
||||
0x6f,0xff,0x6f,0xfa,0xdb,0xf1,0xc5,0xbd,0xf5,0x6f,0xff,0x6f,0xca,0xdb,0xff,0xdb,
|
||||
0xfb,0xf6,0x97,0xf6,0xff,0xfd,0xbf,0xfe,0xf7,0xff,0xd0,0x9f,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8b,0x7f,0xff,0xff,0xe7,0x63,0xff,0xff,
|
||||
0xff,0xfc,0x77,0xdf,0xf1,0xdb,0xff,0xd6,0xa8,0x3f,0xff,0xff,0x08,0x2f,0xf0,0xff,
|
||||
0xc3,0xff,0xeb,0xff,0xff,0xff,0xff,0xff,0x5f,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x8b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xfc,0xff,0xcf,0xf1,0xdb,0xff,0xd6,0xa8,0x3f,0xff,0xff,0x08,0x2f,0xf0,0xff,0xc3,
|
||||
0xff,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0xbf,0xff,0xca,0xff,0x9f,0xff,0xfa,0xb9,0xe7,
|
||||
0x9f,0xf3,0x81,0xff,0xff,0xfc,0x73,0xd7,0xff,0xff,0x77,0xff,0xfd,0xff,0xfc,0xff,
|
||||
0xff,0xff,0xff,0xcf,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,
|
||||
0xff,0xf7,0xde,0xff,0xfe,0x7e,0xff,0xbf,0xff,0xbf,0xf1,0xb3,0xff,0xff,0xe3,0xfb,
|
||||
0xff,0xe1,0x1f,0x7f,0xff,0xf8,0x78,0xff,0xfb,0x1e,0xff,0xf7,0xfe,0xe7,0xff,0xff,
|
||||
0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x00,0x00,0x00,0x04,0x00,
|
||||
0x01,0x80,0x40,0x40,0x20,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
|
||||
0x80,0x00,0x00,0x01,0x3c,0xf0,0xaf,0xff,0xff,0xff,0xfe,0xfd,0xbf,0xff,0xfb,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xf7,0xf1,
|
||||
0xfd,0xff,0xff,0xff,0xdf,0xff,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,
|
||||
0xff,0xff,0xff,0xdb,0xf0,0x8f,0xff,0xff,0xff,0xfe,0xf0,0xff,0xdf,0xff,0xff,0x7f,
|
||||
0xff,0xff,0xff,0xbe,0xd7,0xff,0xed,0xbd,0x7e,0xbf,0xfe,0xf6,0x7f,0xbf,0x71,0xff,
|
||||
0xff,0xda,0xff,0xf9,0xff,0xbf,0x7f,0xfe,0xff,0x6f,0x7f,0xff,0xff,0xff,0xff,0xff,
|
||||
0x7f,0xff,0xd0,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xf8,0x30,0x42,0x00,0x00,0x00,0x00,
|
||||
0x80,0xc1,0x00,0x00,0x90,0x00,0xc4,0x00,0x00,0x12,0x20,0x43,0x22,0x81,0x84,0x00,
|
||||
0x00,0x14,0x00,0x01,0x00,0x08,0x80,0x00,0x02,0x00,0x02,0x00,0x04,0x02,0x00,0x00,
|
||||
0x10,0xc1,0xf0,0x1f,0xff,0xff,0xff,0xfe,0xff,0xff,0xfd,0xff,0xff,0xdd,0xfe,0xff,
|
||||
0xb6,0x76,0xe5,0xbc,0xf9,0xf7,0xaf,0x5f,0xbf,0xfc,0xdf,0xcf,0xf1,0xff,0xef,0x79,
|
||||
0xff,0xbd,0xff,0xef,0xff,0xff,0xf7,0x6f,0x5f,0xff,0xff,0xfd,0xef,0xef,0xbf,0xff,
|
||||
0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xf0,0xff,0xff,0xff,0xff,0xfe,0xdb,0xff,0xff,0xfd,0x2d,0xff,0x69,0x2a,0xef,0x77,
|
||||
0xbb,0xdd,0x5a,0xdf,0xf6,0xf6,0xd6,0xf7,0x7d,0xbd,0xd1,0xb2,0x4a,0xd6,0xb2,0xbe,
|
||||
0x97,0xf5,0xbd,0xb3,0xad,0xff,0xef,0x7f,0x69,0x6b,0xfb,0xdf,0xff,0xff,0xff,0xf0,
|
||||
0x2f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,0xfe,0x9f,0xd4,0xbf,
|
||||
0xed,0xaf,0xff,0x6b,0x6f,0xf7,0xff,0xdd,0xdb,0x31,0xfd,0xbf,0xff,0x6f,0x7f,0xff,
|
||||
0xff,0xdb,0xff,0xcb,0xdf,0xf6,0xff,0xf6,0xff,0xfd,0xbf,0xfe,0xf7,0xff,0xd0,0x8f,
|
||||
0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0x1f,0xff,0x46,0x2f,0x9f,0xff,0xff,0xff,
|
||||
0xa5,0xff,0xff,0xff,0xdf,0xb7,0xff,0xff,0xf1,0xff,0xff,0xff,0xf7,0xe9,0x6a,0xbf,
|
||||
0xff,0xff,0xfd,0xff,0xff,0xfd,0x55,0x57,0xff,0xff,0xff,0xff,0xaf,0xf0,0x4f,0xff,
|
||||
0xff,0xff,0xfe,0xfe,0xdf,0xff,0xfd,0x1f,0xff,0x46,0x2f,0x9f,0xff,0xff,0xff,0xa5,
|
||||
0xff,0xff,0xff,0xc0,0x37,0xff,0xff,0xf1,0x99,0x8e,0xdc,0x7f,0xe9,0x6a,0xbf,0xff,
|
||||
0xf0,0x0f,0xff,0xff,0xfd,0x55,0x57,0xff,0xff,0xff,0xff,0xff,0xf0,0x0f,0xff,0xff,
|
||||
0xff,0xfe,0xff,0xff,0xff,0xff,0x07,0xff,0xc0,0xbe,0xff,0xff,0xcf,0xef,0x9f,0xff,
|
||||
0xff,0xfb,0xff,0xe7,0xff,0xff,0xa1,0xe3,0xce,0x3c,0x58,0x3f,0xf3,0xff,0xfd,0xef,
|
||||
0xf9,0xff,0xff,0xf7,0xf1,0x7f,0xff,0xcb,0xff,0xff,0xff,0xf0,0x2f,0xff,0xff,0xff,
|
||||
0xfe,0xf5,0x7f,0xff,0xf0,0xff,0xfe,0xff,0xc4,0x75,0xe7,0xb9,0xff,0xff,0xff,0xef,
|
||||
0xff,0xc7,0x37,0x3b,0xff,0xf0,0x13,0x9e,0x0f,0xf4,0xff,0xfe,0xfb,0xff,0xff,0xf9,
|
||||
0xfc,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xfa,0xf0,0xef,0xff,0xff,0xff,0xfe,
|
||||
0xf3,0xc0,0x01,0x00,0x00,0x02,0x00,0x02,0x22,0x00,0x00,0xc0,0x40,0x00,0x40,0x00,
|
||||
0x04,0x08,0x04,0x0a,0x01,0x01,0x10,0x20,0x20,0x00,0x00,0x04,0x08,0x08,0x04,0x00,
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x3c,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xfd,
|
||||
0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,0xff,0x7f,0xff,0x7f,0xff,0xcf,0x9d,0xff,
|
||||
0xff,0xf7,0xfd,0xf1,0xff,0xff,0xff,0xee,0xbf,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xf0,0xff,
|
||||
0xff,0xff,0xf7,0xf7,0xff,0xff,0xfe,0xbf,0xf7,0xff,0xff,0x5b,0xff,0xbf,0xf7,0xff,
|
||||
0xfd,0x7f,0x71,0xfd,0xff,0xed,0xf7,0xfe,0xef,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xef,0xff,0x7f,0xff,0xd0,0xf0,0xff,0xff,0xff,0xff,0xfe,0xf8,0x30,0x11,
|
||||
0x00,0x48,0x60,0x40,0x82,0x60,0x24,0x60,0x00,0xcc,0x00,0x80,0x04,0x01,0x00,0x00,
|
||||
0x14,0x01,0x0c,0x04,0x00,0x30,0x00,0x00,0x00,0x08,0x08,0x00,0x01,0x00,0xc2,0x00,
|
||||
0x00,0x02,0x00,0x80,0x00,0xc1,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,
|
||||
0xf7,0x7b,0xff,0xf3,0xeb,0xbf,0xff,0xf7,0xff,0xff,0xff,0xe7,0x5d,0x3f,0xff,0xf6,
|
||||
0xd1,0xfd,0xff,0xeb,0xf7,0x3d,0xff,0xff,0xff,0x5f,0xff,0x7f,0x7f,0xf3,0xff,0xff,
|
||||
0xef,0xfd,0xbf,0xff,0xff,0xf0,0x5f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf0,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xb5,0xdf,
|
||||
0x6f,0x7d,0x69,0x7f,0xfb,0xdf,0x52,0x5f,0xf6,0xf7,0xfe,0xf6,0xf3,0xbd,0xb1,0xda,
|
||||
0xcd,0xfe,0xf6,0xee,0xd2,0xbd,0xa5,0xaf,0xbd,0xff,0x6f,0x7c,0xeb,0x2b,0xfa,0xda,
|
||||
0xff,0xfe,0xdf,0xf0,0x4f,0xff,0xff,0xff,0xfe,0xbf,0xff,0xff,0xff,0xdb,0xff,0xf6,
|
||||
0xff,0xf6,0xff,0xbd,0xbf,0xcd,0xbf,0xeb,0x6f,0xf7,0x6f,0xdf,0xdb,0x51,0xfd,0xbd,
|
||||
0xff,0x6f,0xff,0x6f,0xfb,0x5b,0xff,0xdb,0xff,0xf6,0xfe,0xf6,0xfd,0xfd,0xbf,0xfe,
|
||||
0xf7,0xff,0xd0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xfa,0x50,0xff,0xff,0xff,
|
||||
0xf0,0x6f,0xff,0xff,0xf0,0x96,0xff,0xff,0xc6,0x2b,0xff,0xff,0xf1,0xfc,0xff,0xff,
|
||||
0xf7,0xdb,0xc3,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xc1,0x4f,0xc3,0xff,0xff,0xff,
|
||||
0xaf,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf5,0xa0,0xff,0xff,0xff,0xf0,
|
||||
0x6f,0xff,0xff,0xf0,0x96,0xff,0xff,0xc6,0x2b,0xff,0xff,0xf1,0x5a,0xff,0xff,0xff,
|
||||
0xf3,0xc3,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xc1,0x4f,0xc3,0xff,0xff,0xff,0xff,
|
||||
0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xfc,0xff,0xff,0x9f,0xf0,0x7f,
|
||||
0xff,0xf9,0xfc,0x4f,0xf3,0xff,0x27,0xeb,0xff,0xfc,0x81,0xfc,0x7f,0xfe,0x7b,0xff,
|
||||
0xf7,0xff,0x12,0x7f,0xff,0xff,0xff,0xff,0x18,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,
|
||||
0x7f,0xff,0xff,0xff,0xfe,0xf5,0xff,0xff,0xff,0xdf,0xfe,0xff,0xfc,0x7e,0x7f,0xbf,
|
||||
0xff,0xff,0xaf,0xef,0xff,0xdf,0xdf,0xfb,0xff,0xf1,0xc3,0xfe,0x6f,0xf1,0xcf,0x3f,
|
||||
0xfb,0xff,0xff,0xcf,0xfe,0xff,0xff,0xfe,0x7f,0xbf,0xff,0xff,0xbf,0xfa,0xf0,0xdf,
|
||||
0xff,0xff,0xff,0xfe,0xf3,0xc0,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x01,0x00,0x00,
|
||||
0x20,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x02,0x00,0x00,0x80,0x00,0x02,0x80,0x00,0x02,0x3c,0xf0,0x2f,0xff,
|
||||
0xff,0xff,0xfe,0xfd,0xbf,0xff,0xfb,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xf5,0xf1,0xff,0x7f,0xff,0xff,0xff,0xff,0xef,0xff,
|
||||
0xff,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xdb,0xf0,0x2f,0xff,0xff,
|
||||
0xff,0xfe,0xf0,0xff,0xff,0xff,0xfb,0xff,0xbf,0xff,0xff,0xff,0xff,0xf7,0xbf,0xfb,
|
||||
0xff,0xff,0xff,0xdf,0xf7,0xff,0xf1,0xf7,0xbf,0xfb,0xff,0xff,0xff,0x7f,0xde,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xed,0xf7,0xff,0xff,0x7f,0xd0,0xf0,0x3f,0xff,0xff,0xff,
|
||||
0xfe,0xf8,0x30,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0xe0,0x00,0x00,0x80,
|
||||
0x20,0x01,0x01,0x92,0x00,0x01,0x01,0x00,0xe0,0x1c,0x60,0x20,0x30,0x08,0x08,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0xc1,0xf0,0x6f,0xff,0xff,0xff,0xfe,
|
||||
0xff,0xff,0xff,0xff,0xff,0xdb,0xfe,0xff,0xff,0xdf,0xff,0xfc,0x7f,0xfb,0xbf,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf1,0xf6,0xff,0xf7,0x7e,0x3f,0xff,0x7f,0xff,0xff,0xff,0xf7,
|
||||
0xff,0xff,0xff,0xed,0xff,0xdf,0xff,0xb7,0xff,0xf0,0x3f,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xff,0xff,0xff,0xff,0xfe,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xdf,0xff,0xff,0xff,0xff,0xbf,0xff,0xdf,
|
||||
0x57,0xef,0xf1,0xfd,0xfe,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xdf,0xfb,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0x7f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfb,0xff,0xdf,0xff,
|
||||
0xff,0xf1,0xfd,0xff,0x7f,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xfe,0xff,0xff,0xff,0xff,0xf0,0x9f,0xff,0xff,0xff,0xfe,0xf7,0xfd,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,
|
||||
0xf1,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xf0,0x6f,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf1,
|
||||
0xff,0xff,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xfb,0x6f,0xff,0xfe,0xbf,0xff,0xf1,0xff,
|
||||
0xf7,0xff,0xff,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,
|
||||
0xff,0xff,0xff,0xf0,0xef,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xfb,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0x57,0xff,0xfd,0xbf,0xff,0xf1,0xff,0xef,
|
||||
0xfe,0xff,0xbf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xff,
|
||||
0xde,0xff,0xf0,0xcf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xf7,0xdb,0xff,0xdb,0xfd,
|
||||
0xf6,0xff,0xf6,0xff,0x3c,0xbc,0xbc,0xbf,0xdf,0x6f,0xe7,0x2f,0xf1,0x3c,0xbf,0xfd,
|
||||
0xbf,0xdf,0x6f,0xff,0x6f,0xf7,0xdb,0xff,0xdb,0xfd,0xf6,0xff,0xf6,0xff,0xff,0xff,
|
||||
0x02,0x01,0xdf,0xff,0xff,0xff,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff };
|
245
drivers/net/hamradio/z8530.h
Normal file
245
drivers/net/hamradio/z8530.h
Normal file
@@ -0,0 +1,245 @@
|
||||
|
||||
/* 8530 Serial Communications Controller Register definitions */
|
||||
#define FLAG 0x7e
|
||||
|
||||
/* Write Register 0 */
|
||||
#define R0 0 /* Register selects */
|
||||
#define R1 1
|
||||
#define R2 2
|
||||
#define R3 3
|
||||
#define R4 4
|
||||
#define R5 5
|
||||
#define R6 6
|
||||
#define R7 7
|
||||
#define R8 8
|
||||
#define R9 9
|
||||
#define R10 10
|
||||
#define R11 11
|
||||
#define R12 12
|
||||
#define R13 13
|
||||
#define R14 14
|
||||
#define R15 15
|
||||
|
||||
#define NULLCODE 0 /* Null Code */
|
||||
#define POINT_HIGH 0x8 /* Select upper half of registers */
|
||||
#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */
|
||||
#define SEND_ABORT 0x18 /* HDLC Abort */
|
||||
#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */
|
||||
#define RES_Tx_P 0x28 /* Reset TxINT Pending */
|
||||
#define ERR_RES 0x30 /* Error Reset */
|
||||
#define RES_H_IUS 0x38 /* Reset highest IUS */
|
||||
|
||||
#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */
|
||||
#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */
|
||||
#define RES_EOM_L 0xC0 /* Reset EOM latch */
|
||||
|
||||
/* Write Register 1 */
|
||||
|
||||
#define EXT_INT_ENAB 0x1 /* Ext Int Enable */
|
||||
#define TxINT_ENAB 0x2 /* Tx Int Enable */
|
||||
#define PAR_SPEC 0x4 /* Parity is special condition */
|
||||
|
||||
#define RxINT_DISAB 0 /* Rx Int Disable */
|
||||
#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */
|
||||
#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */
|
||||
#define INT_ERR_Rx 0x18 /* Int on error only */
|
||||
|
||||
#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */
|
||||
#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */
|
||||
#define WT_RDY_ENAB 0x80 /* Wait/Ready Enable */
|
||||
|
||||
/* Write Register #2 (Interrupt Vector) */
|
||||
|
||||
/* Write Register 3 */
|
||||
|
||||
#define RxENABLE 0x1 /* Rx Enable */
|
||||
#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */
|
||||
#define ADD_SM 0x4 /* Address Search Mode (SDLC) */
|
||||
#define RxCRC_ENAB 0x8 /* Rx CRC Enable */
|
||||
#define ENT_HM 0x10 /* Enter Hunt Mode */
|
||||
#define AUTO_ENAB 0x20 /* Auto Enables */
|
||||
#define Rx5 0x0 /* Rx 5 Bits/Character */
|
||||
#define Rx7 0x40 /* Rx 7 Bits/Character */
|
||||
#define Rx6 0x80 /* Rx 6 Bits/Character */
|
||||
#define Rx8 0xc0 /* Rx 8 Bits/Character */
|
||||
|
||||
/* Write Register 4 */
|
||||
|
||||
#define PAR_ENA 0x1 /* Parity Enable */
|
||||
#define PAR_EVEN 0x2 /* Parity Even/Odd* */
|
||||
|
||||
#define SYNC_ENAB 0 /* Sync Modes Enable */
|
||||
#define SB1 0x4 /* 1 stop bit/char */
|
||||
#define SB15 0x8 /* 1.5 stop bits/char */
|
||||
#define SB2 0xc /* 2 stop bits/char */
|
||||
|
||||
#define MONSYNC 0 /* 8 Bit Sync character */
|
||||
#define BISYNC 0x10 /* 16 bit sync character */
|
||||
#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */
|
||||
#define EXTSYNC 0x30 /* External Sync Mode */
|
||||
|
||||
#define X1CLK 0x0 /* x1 clock mode */
|
||||
#define X16CLK 0x40 /* x16 clock mode */
|
||||
#define X32CLK 0x80 /* x32 clock mode */
|
||||
#define X64CLK 0xC0 /* x64 clock mode */
|
||||
|
||||
/* Write Register 5 */
|
||||
|
||||
#define TxCRC_ENAB 0x1 /* Tx CRC Enable */
|
||||
#define RTS 0x2 /* RTS */
|
||||
#define SDLC_CRC 0x4 /* SDLC/CRC-16 */
|
||||
#define TxENAB 0x8 /* Tx Enable */
|
||||
#define SND_BRK 0x10 /* Send Break */
|
||||
#define Tx5 0x0 /* Tx 5 bits (or less)/character */
|
||||
#define Tx7 0x20 /* Tx 7 bits/character */
|
||||
#define Tx6 0x40 /* Tx 6 bits/character */
|
||||
#define Tx8 0x60 /* Tx 8 bits/character */
|
||||
#define DTR 0x80 /* DTR */
|
||||
|
||||
/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */
|
||||
|
||||
/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */
|
||||
|
||||
/* Write Register 8 (transmit buffer) */
|
||||
|
||||
/* Write Register 9 (Master interrupt control) */
|
||||
#define VIS 1 /* Vector Includes Status */
|
||||
#define NV 2 /* No Vector */
|
||||
#define DLC 4 /* Disable Lower Chain */
|
||||
#define MIE 8 /* Master Interrupt Enable */
|
||||
#define STATHI 0x10 /* Status high */
|
||||
#define NORESET 0 /* No reset on write to R9 */
|
||||
#define CHRB 0x40 /* Reset channel B */
|
||||
#define CHRA 0x80 /* Reset channel A */
|
||||
#define FHWRES 0xc0 /* Force hardware reset */
|
||||
|
||||
/* Write Register 10 (misc control bits) */
|
||||
#define BIT6 1 /* 6 bit/8bit sync */
|
||||
#define LOOPMODE 2 /* SDLC Loop mode */
|
||||
#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */
|
||||
#define MARKIDLE 8 /* Mark/flag on idle */
|
||||
#define GAOP 0x10 /* Go active on poll */
|
||||
#define NRZ 0 /* NRZ mode */
|
||||
#define NRZI 0x20 /* NRZI mode */
|
||||
#define FM1 0x40 /* FM1 (transition = 1) */
|
||||
#define FM0 0x60 /* FM0 (transition = 0) */
|
||||
#define CRCPS 0x80 /* CRC Preset I/O */
|
||||
|
||||
/* Write Register 11 (Clock Mode control) */
|
||||
#define TRxCXT 0 /* TRxC = Xtal output */
|
||||
#define TRxCTC 1 /* TRxC = Transmit clock */
|
||||
#define TRxCBR 2 /* TRxC = BR Generator Output */
|
||||
#define TRxCDP 3 /* TRxC = DPLL output */
|
||||
#define TRxCOI 4 /* TRxC O/I */
|
||||
#define TCRTxCP 0 /* Transmit clock = RTxC pin */
|
||||
#define TCTRxCP 8 /* Transmit clock = TRxC pin */
|
||||
#define TCBR 0x10 /* Transmit clock = BR Generator output */
|
||||
#define TCDPLL 0x18 /* Transmit clock = DPLL output */
|
||||
#define RCRTxCP 0 /* Receive clock = RTxC pin */
|
||||
#define RCTRxCP 0x20 /* Receive clock = TRxC pin */
|
||||
#define RCBR 0x40 /* Receive clock = BR Generator output */
|
||||
#define RCDPLL 0x60 /* Receive clock = DPLL output */
|
||||
#define RTxCX 0x80 /* RTxC Xtal/No Xtal */
|
||||
|
||||
/* Write Register 12 (lower byte of baud rate generator time constant) */
|
||||
|
||||
/* Write Register 13 (upper byte of baud rate generator time constant) */
|
||||
|
||||
/* Write Register 14 (Misc control bits) */
|
||||
#define BRENABL 1 /* Baud rate generator enable */
|
||||
#define BRSRC 2 /* Baud rate generator source */
|
||||
#define DTRREQ 4 /* DTR/Request function */
|
||||
#define AUTOECHO 8 /* Auto Echo */
|
||||
#define LOOPBAK 0x10 /* Local loopback */
|
||||
#define SEARCH 0x20 /* Enter search mode */
|
||||
#define RMC 0x40 /* Reset missing clock */
|
||||
#define DISDPLL 0x60 /* Disable DPLL */
|
||||
#define SSBR 0x80 /* Set DPLL source = BR generator */
|
||||
#define SSRTxC 0xa0 /* Set DPLL source = RTxC */
|
||||
#define SFMM 0xc0 /* Set FM mode */
|
||||
#define SNRZI 0xe0 /* Set NRZI mode */
|
||||
|
||||
/* Write Register 15 (external/status interrupt control) */
|
||||
#define ZCIE 2 /* Zero count IE */
|
||||
#define DCDIE 8 /* DCD IE */
|
||||
#define SYNCIE 0x10 /* Sync/hunt IE */
|
||||
#define CTSIE 0x20 /* CTS IE */
|
||||
#define TxUIE 0x40 /* Tx Underrun/EOM IE */
|
||||
#define BRKIE 0x80 /* Break/Abort IE */
|
||||
|
||||
|
||||
/* Read Register 0 */
|
||||
#define Rx_CH_AV 0x1 /* Rx Character Available */
|
||||
#define ZCOUNT 0x2 /* Zero count */
|
||||
#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */
|
||||
#define DCD 0x8 /* DCD */
|
||||
#define SYNC_HUNT 0x10 /* Sync/hunt */
|
||||
#define CTS 0x20 /* CTS */
|
||||
#define TxEOM 0x40 /* Tx underrun */
|
||||
#define BRK_ABRT 0x80 /* Break/Abort */
|
||||
|
||||
/* Read Register 1 */
|
||||
#define ALL_SNT 0x1 /* All sent */
|
||||
/* Residue Data for 8 Rx bits/char programmed */
|
||||
#define RES3 0x8 /* 0/3 */
|
||||
#define RES4 0x4 /* 0/4 */
|
||||
#define RES5 0xc /* 0/5 */
|
||||
#define RES6 0x2 /* 0/6 */
|
||||
#define RES7 0xa /* 0/7 */
|
||||
#define RES8 0x6 /* 0/8 */
|
||||
#define RES18 0xe /* 1/8 */
|
||||
#define RES28 0x0 /* 2/8 */
|
||||
/* Special Rx Condition Interrupts */
|
||||
#define PAR_ERR 0x10 /* Parity error */
|
||||
#define Rx_OVR 0x20 /* Rx Overrun Error */
|
||||
#define CRC_ERR 0x40 /* CRC/Framing Error */
|
||||
#define END_FR 0x80 /* End of Frame (SDLC) */
|
||||
|
||||
/* Read Register 2 (channel b only) - Interrupt vector */
|
||||
|
||||
/* Read Register 3 (interrupt pending register) ch a only */
|
||||
#define CHBEXT 0x1 /* Channel B Ext/Stat IP */
|
||||
#define CHBTxIP 0x2 /* Channel B Tx IP */
|
||||
#define CHBRxIP 0x4 /* Channel B Rx IP */
|
||||
#define CHAEXT 0x8 /* Channel A Ext/Stat IP */
|
||||
#define CHATxIP 0x10 /* Channel A Tx IP */
|
||||
#define CHARxIP 0x20 /* Channel A Rx IP */
|
||||
|
||||
/* Read Register 8 (receive data register) */
|
||||
|
||||
/* Read Register 10 (misc status bits) */
|
||||
#define ONLOOP 2 /* On loop */
|
||||
#define LOOPSEND 0x10 /* Loop sending */
|
||||
#define CLK2MIS 0x40 /* Two clocks missing */
|
||||
#define CLK1MIS 0x80 /* One clock missing */
|
||||
|
||||
/* Read Register 12 (lower byte of baud rate generator constant) */
|
||||
|
||||
/* Read Register 13 (upper byte of baud rate generator constant) */
|
||||
|
||||
/* Read Register 15 (value of WR 15) */
|
||||
|
||||
/* Z85C30/Z85230 Enhanced SCC register definitions */
|
||||
|
||||
/* Write Register 7' (SDLC/HDLC Programmable Enhancements) */
|
||||
#define AUTOTXF 0x01 /* Auto Tx Flag */
|
||||
#define AUTOEOM 0x02 /* Auto EOM Latch Reset */
|
||||
#define AUTORTS 0x04 /* Auto RTS */
|
||||
#define TXDNRZI 0x08 /* TxD Pulled High in SDLC NRZI mode */
|
||||
#define RXFIFOH 0x08 /* Z85230: Int on RX FIFO half full */
|
||||
#define FASTDTR 0x10 /* Fast DTR/REQ Mode */
|
||||
#define CRCCBCR 0x20 /* CRC Check Bytes Completely Received */
|
||||
#define TXFIFOE 0x20 /* Z85230: Int on TX FIFO completely empty */
|
||||
#define EXTRDEN 0x40 /* Extended Read Enabled */
|
||||
|
||||
/* Write Register 15 (external/status interrupt control) */
|
||||
#define SHDLCE 1 /* SDLC/HDLC Enhancements Enable */
|
||||
#define FIFOE 4 /* FIFO Enable */
|
||||
|
||||
/* Read Register 6 (frame status FIFO) */
|
||||
#define BCLSB 0xff /* LSB of 14 bits count */
|
||||
|
||||
/* Read Register 7 (frame status FIFO) */
|
||||
#define BCMSB 0x3f /* MSB of 14 bits count */
|
||||
#define FDA 0x40 /* FIFO Data Available Status */
|
||||
#define FOS 0x80 /* FIFO Overflow Status */
|
Reference in New Issue
Block a user