net: wan: remove support for Z85230-based devices

Looks like all the changes to this driver had been automated
churn since git era begun. The driver is using virt_to_bus(),
it's just a maintenance burden unlikely to have any users.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jakub Kicinski 2022-04-26 10:54:35 -07:00 committed by David S. Miller
parent 89fbca3307
commit bc6df26f1f
9 changed files with 0 additions and 3035 deletions

View File

@ -17,7 +17,6 @@ Contents:
fddi/index
hamradio/index
qlogic/index
wan/index
wifi/index
wwan/index

View File

@ -1,18 +0,0 @@
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
Classic WAN Device Drivers
==========================
Contents:
.. toctree::
:maxdepth: 2
z8530book
.. only:: subproject and html
Indices
=======
* :ref:`genindex`

View File

@ -1,256 +0,0 @@
=======================
Z8530 Programming Guide
=======================
:Author: Alan Cox
Introduction
============
The Z85x30 family synchronous/asynchronous controller chips are used on
a large number of cheap network interface cards. The kernel provides a
core interface layer that is designed to make it easy to provide WAN
services using this chip.
The current driver only support synchronous operation. Merging the
asynchronous driver support into this code to allow any Z85x30 device to
be used as both a tty interface and as a synchronous controller is a
project for Linux post the 2.4 release
Driver Modes
============
The Z85230 driver layer can drive Z8530, Z85C30 and Z85230 devices in
three different modes. Each mode can be applied to an individual channel
on the chip (each chip has two channels).
The PIO synchronous mode supports the most common Z8530 wiring. Here the
chip is interface to the I/O and interrupt facilities of the host
machine but not to the DMA subsystem. When running PIO the Z8530 has
extremely tight timing requirements. Doing high speeds, even with a
Z85230 will be tricky. Typically you should expect to achieve at best
9600 baud with a Z8C530 and 64Kbits with a Z85230.
The DMA mode supports the chip when it is configured to use dual DMA
channels on an ISA bus. The better cards tend to support this mode of
operation for a single channel. With DMA running the Z85230 tops out
when it starts to hit ISA DMA constraints at about 512Kbits. It is worth
noting here that many PC machines hang or crash when the chip is driven
fast enough to hold the ISA bus solid.
Transmit DMA mode uses a single DMA channel. The DMA channel is used for
transmission as the transmit FIFO is smaller than the receive FIFO. it
gives better performance than pure PIO mode but is nowhere near as ideal
as pure DMA mode.
Using the Z85230 driver
=======================
The Z85230 driver provides the back end interface to your board. To
configure a Z8530 interface you need to detect the board and to identify
its ports and interrupt resources. It is also your problem to verify the
resources are available.
Having identified the chip you need to fill in a struct z8530_dev,
which describes each chip. This object must exist until you finally
shutdown the board. Firstly zero the active field. This ensures nothing
goes off without you intending it. The irq field should be set to the
interrupt number of the chip. (Each chip has a single interrupt source
rather than each channel). You are responsible for allocating the
interrupt line. The interrupt handler should be set to
:c:func:`z8530_interrupt()`. The device id should be set to the
z8530_dev structure pointer. Whether the interrupt can be shared or not
is board dependent, and up to you to initialise.
The structure holds two channel structures. Initialise chanA.ctrlio and
chanA.dataio with the address of the control and data ports. You can or
this with Z8530_PORT_SLEEP to indicate your interface needs the 5uS
delay for chip settling done in software. The PORT_SLEEP option is
architecture specific. Other flags may become available on future
platforms, eg for MMIO. Initialise the chanA.irqs to &z8530_nop to
start the chip up as disabled and discarding interrupt events. This
ensures that stray interrupts will be mopped up and not hang the bus.
Set chanA.dev to point to the device structure itself. The private and
name field you may use as you wish. The private field is unused by the
Z85230 layer. The name is used for error reporting and it may thus make
sense to make it match the network name.
Repeat the same operation with the B channel if your chip has both
channels wired to something useful. This isn't always the case. If it is
not wired then the I/O values do not matter, but you must initialise
chanB.dev.
If your board has DMA facilities then initialise the txdma and rxdma
fields for the relevant channels. You must also allocate the ISA DMA
channels and do any necessary board level initialisation to configure
them. The low level driver will do the Z8530 and DMA controller
programming but not board specific magic.
Having initialised the device you can then call
:c:func:`z8530_init()`. This will probe the chip and reset it into
a known state. An identification sequence is then run to identify the
chip type. If the checks fail to pass the function returns a non zero
error code. Typically this indicates that the port given is not valid.
After this call the type field of the z8530_dev structure is
initialised to either Z8530, Z85C30 or Z85230 according to the chip
found.
Once you have called z8530_init you can also make use of the utility
function :c:func:`z8530_describe()`. This provides a consistent
reporting format for the Z8530 devices, and allows all the drivers to
provide consistent reporting.
Attaching Network Interfaces
============================
If you wish to use the network interface facilities of the driver, then
you need to attach a network device to each channel that is present and
in use. In addition to use the generic HDLC you need to follow some
additional plumbing rules. They may seem complex but a look at the
example hostess_sv11 driver should reassure you.
The network device used for each channel should be pointed to by the
netdevice field of each channel. The hdlc-> priv field of the network
device points to your private data - you will need to be able to find
your private data from this.
The way most drivers approach this particular problem is to create a
structure holding the Z8530 device definition and put that into the
private field of the network device. The network device fields of the
channels then point back to the network devices.
If you wish to use the generic HDLC then you need to register the HDLC
device.
Before you register your network device you will also need to provide
suitable handlers for most of the network device callbacks. See the
network device documentation for more details on this.
Configuring And Activating The Port
===================================
The Z85230 driver provides helper functions and tables to load the port
registers on the Z8530 chips. When programming the register settings for
a channel be aware that the documentation recommends initialisation
orders. Strange things happen when these are not followed.
:c:func:`z8530_channel_load()` takes an array of pairs of
initialisation values in an array of u8 type. The first value is the
Z8530 register number. Add 16 to indicate the alternate register bank on
the later chips. The array is terminated by a 255.
The driver provides a pair of public tables. The z8530_hdlc_kilostream
table is for the UK 'Kilostream' service and also happens to cover most
other end host configurations. The z8530_hdlc_kilostream_85230 table
is the same configuration using the enhancements of the 85230 chip. The
configuration loaded is standard NRZ encoded synchronous data with HDLC
bitstuffing. All of the timing is taken from the other end of the link.
When writing your own tables be aware that the driver internally tracks
register values. It may need to reload values. You should therefore be
sure to set registers 1-7, 9-11, 14 and 15 in all configurations. Where
the register settings depend on DMA selection the driver will update the
bits itself when you open or close. Loading a new table with the
interface open is not recommended.
There are three standard configurations supported by the core code. In
PIO mode the interface is programmed up to use interrupt driven PIO.
This places high demands on the host processor to avoid latency. The
driver is written to take account of latency issues but it cannot avoid
latencies caused by other drivers, notably IDE in PIO mode. Because the
drivers allocate buffers you must also prevent MTU changes while the
port is open.
Once the port is open it will call the rx_function of each channel
whenever a completed packet arrived. This is invoked from interrupt
context and passes you the channel and a network buffer (struct
sk_buff) holding the data. The data includes the CRC bytes so most
users will want to trim the last two bytes before processing the data.
This function is very timing critical. When you wish to simply discard
data the support code provides the function
:c:func:`z8530_null_rx()` to discard the data.
To active PIO mode sending and receiving the ``z8530_sync_open`` is called.
This expects to be passed the network device and the channel. Typically
this is called from your network device open callback. On a failure a
non zero error status is returned.
The :c:func:`z8530_sync_close()` function shuts down a PIO
channel. This must be done before the channel is opened again and before
the driver shuts down and unloads.
The ideal mode of operation is dual channel DMA mode. Here the kernel
driver will configure the board for DMA in both directions. The driver
also handles ISA DMA issues such as controller programming and the
memory range limit for you. This mode is activated by calling the
:c:func:`z8530_sync_dma_open()` function. On failure a non zero
error value is returned. Once this mode is activated it can be shut down
by calling the :c:func:`z8530_sync_dma_close()`. You must call
the close function matching the open mode you used.
The final supported mode uses a single DMA channel to drive the transmit
side. As the Z85C30 has a larger FIFO on the receive channel this tends
to increase the maximum speed a little. This is activated by calling the
``z8530_sync_txdma_open``. This returns a non zero error code on failure. The
:c:func:`z8530_sync_txdma_close()` function closes down the Z8530
interface from this mode.
Network Layer Functions
=======================
The Z8530 layer provides functions to queue packets for transmission.
The driver internally buffers the frame currently being transmitted and
one further frame (in order to keep back to back transmission running).
Any further buffering is up to the caller.
The function :c:func:`z8530_queue_xmit()` takes a network buffer
in sk_buff format and queues it for transmission. The caller must
provide the entire packet with the exception of the bitstuffing and CRC.
This is normally done by the caller via the generic HDLC interface
layer. It returns 0 if the buffer has been queued and non zero values
for queue full. If the function accepts the buffer it becomes property
of the Z8530 layer and the caller should not free it.
The function :c:func:`z8530_get_stats()` returns a pointer to an
internally maintained per interface statistics block. This provides most
of the interface code needed to implement the network layer get_stats
callback.
Porting The Z8530 Driver
========================
The Z8530 driver is written to be portable. In DMA mode it makes
assumptions about the use of ISA DMA. These are probably warranted in
most cases as the Z85230 in particular was designed to glue to PC type
machines. The PIO mode makes no real assumptions.
Should you need to retarget the Z8530 driver to another architecture the
only code that should need changing are the port I/O functions. At the
moment these assume PC I/O port accesses. This may not be appropriate
for all platforms. Replacing :c:func:`z8530_read_port()` and
``z8530_write_port`` is intended to be all that is required to port
this driver layer.
Known Bugs And Assumptions
==========================
Interrupt Locking
The locking in the driver is done via the global cli/sti lock. This
makes for relatively poor SMP performance. Switching this to use a
per device spin lock would probably materially improve performance.
Occasional Failures
We have reports of occasional failures when run for very long
periods of time and the driver starts to receive junk frames. At the
moment the cause of this is not clear.
Public Functions Provided
=========================
.. kernel-doc:: drivers/net/wan/z85230.c
:export:
Internal Functions
==================
.. kernel-doc:: drivers/net/wan/z85230.c
:internal:

View File

@ -23,28 +23,6 @@ menuconfig WAN
if WAN
# There is no way to detect a comtrol sv11 - force it modular for now.
config HOSTESS_SV11
tristate "Comtrol Hostess SV-11 support"
depends on ISA && m && ISA_DMA_API && INET && HDLC && VIRT_TO_BUS
help
Driver for Comtrol Hostess SV-11 network card which
operates on low speed synchronous serial links at up to
256Kbps, supporting PPP and Cisco HDLC.
The driver will be compiled as a module: the
module will be called hostess_sv11.
# There is no way to detect a Sealevel board. Force it modular
config SEALEVEL_4021
tristate "Sealevel Systems 4021 support"
depends on ISA && m && ISA_DMA_API && INET && HDLC && VIRT_TO_BUS
help
This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
The driver will be compiled as a module: the
module will be called sealevel.
# Generic HDLC
config HDLC
tristate "Generic HDLC layer"

View File

@ -14,8 +14,6 @@ obj-$(CONFIG_HDLC_FR) += hdlc_fr.o
obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o
obj-$(CONFIG_HDLC_X25) += hdlc_x25.o
obj-$(CONFIG_HOSTESS_SV11) += z85230.o hostess_sv11.o
obj-$(CONFIG_SEALEVEL_4021) += z85230.o sealevel.o
obj-$(CONFIG_FARSYNC) += farsync.o
obj-$(CONFIG_LAPBETHER) += lapbether.o

View File

@ -1,336 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Comtrol SV11 card driver
*
* This is a slightly odd Z85230 synchronous driver. All you need to
* know basically is
*
* Its a genuine Z85230
*
* It supports DMA using two DMA channels in SYNC mode. The driver doesn't
* use these facilities
*
* The control port is at io+1, the data at io+3 and turning off the DMA
* is done by writing 0 to io+4
*
* The hardware does the bus handling to avoid the need for delays between
* touching control registers.
*
* Port B isn't wired (why - beats me)
*
* Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <net/arp.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/byteorder.h>
#include "z85230.h"
static int dma;
/* Network driver support routines
*/
static inline struct z8530_dev *dev_to_sv(struct net_device *dev)
{
return (struct z8530_dev *)dev_to_hdlc(dev)->priv;
}
/* Frame receive. Simple for our card as we do HDLC and there
* is no funny garbage involved
*/
static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
{
/* Drop the CRC - it's not a good idea to try and negotiate it ;) */
skb_trim(skb, skb->len - 2);
skb->protocol = hdlc_type_trans(skb, c->netdevice);
skb_reset_mac_header(skb);
skb->dev = c->netdevice;
/* Send it to the PPP layer. We don't have time to process
* it right now.
*/
netif_rx(skb);
}
/* We've been placed in the UP state
*/
static int hostess_open(struct net_device *d)
{
struct z8530_dev *sv11 = dev_to_sv(d);
int err = -1;
/* Link layer up
*/
switch (dma) {
case 0:
err = z8530_sync_open(d, &sv11->chanA);
break;
case 1:
err = z8530_sync_dma_open(d, &sv11->chanA);
break;
case 2:
err = z8530_sync_txdma_open(d, &sv11->chanA);
break;
}
if (err)
return err;
err = hdlc_open(d);
if (err) {
switch (dma) {
case 0:
z8530_sync_close(d, &sv11->chanA);
break;
case 1:
z8530_sync_dma_close(d, &sv11->chanA);
break;
case 2:
z8530_sync_txdma_close(d, &sv11->chanA);
break;
}
return err;
}
sv11->chanA.rx_function = hostess_input;
/*
* Go go go
*/
netif_start_queue(d);
return 0;
}
static int hostess_close(struct net_device *d)
{
struct z8530_dev *sv11 = dev_to_sv(d);
/* Discard new frames
*/
sv11->chanA.rx_function = z8530_null_rx;
hdlc_close(d);
netif_stop_queue(d);
switch (dma) {
case 0:
z8530_sync_close(d, &sv11->chanA);
break;
case 1:
z8530_sync_dma_close(d, &sv11->chanA);
break;
case 2:
z8530_sync_txdma_close(d, &sv11->chanA);
break;
}
return 0;
}
/* Passed network frames, fire them downwind.
*/
static netdev_tx_t hostess_queue_xmit(struct sk_buff *skb,
struct net_device *d)
{
return z8530_queue_xmit(&dev_to_sv(d)->chanA, skb);
}
static int hostess_attach(struct net_device *dev, unsigned short encoding,
unsigned short parity)
{
if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
return 0;
return -EINVAL;
}
/* Description block for a Comtrol Hostess SV11 card
*/
static const struct net_device_ops hostess_ops = {
.ndo_open = hostess_open,
.ndo_stop = hostess_close,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_siocwandev = hdlc_ioctl,
};
static struct z8530_dev *sv11_init(int iobase, int irq)
{
struct z8530_dev *sv;
struct net_device *netdev;
/* Get the needed I/O space
*/
if (!request_region(iobase, 8, "Comtrol SV11")) {
pr_warn("I/O 0x%X already in use\n", iobase);
return NULL;
}
sv = kzalloc(sizeof(struct z8530_dev), GFP_KERNEL);
if (!sv)
goto err_kzalloc;
/* Stuff in the I/O addressing
*/
sv->active = 0;
sv->chanA.ctrlio = iobase + 1;
sv->chanA.dataio = iobase + 3;
sv->chanB.ctrlio = -1;
sv->chanB.dataio = -1;
sv->chanA.irqs = &z8530_nop;
sv->chanB.irqs = &z8530_nop;
outb(0, iobase + 4); /* DMA off */
/* We want a fast IRQ for this device. Actually we'd like an even faster
* IRQ ;) - This is one driver RtLinux is made for
*/
if (request_irq(irq, z8530_interrupt, 0,
"Hostess SV11", sv) < 0) {
pr_warn("IRQ %d already in use\n", irq);
goto err_irq;
}
sv->irq = irq;
sv->chanA.private = sv;
sv->chanA.dev = sv;
sv->chanB.dev = sv;
if (dma) {
/* You can have DMA off or 1 and 3 thats the lot
* on the Comtrol.
*/
sv->chanA.txdma = 3;
sv->chanA.rxdma = 1;
outb(0x03 | 0x08, iobase + 4); /* DMA on */
if (request_dma(sv->chanA.txdma, "Hostess SV/11 (TX)"))
goto err_txdma;
if (dma == 1)
if (request_dma(sv->chanA.rxdma, "Hostess SV/11 (RX)"))
goto err_rxdma;
}
/* Kill our private IRQ line the hostess can end up chattering
* until the configuration is set
*/
disable_irq(irq);
/* Begin normal initialise
*/
if (z8530_init(sv)) {
pr_err("Z8530 series device not found\n");
enable_irq(irq);
goto free_dma;
}
z8530_channel_load(&sv->chanB, z8530_dead_port);
if (sv->type == Z85C30)
z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream);
else
z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream_85230);
enable_irq(irq);
/* Now we can take the IRQ
*/
sv->chanA.netdevice = netdev = alloc_hdlcdev(sv);
if (!netdev)
goto free_dma;
dev_to_hdlc(netdev)->attach = hostess_attach;
dev_to_hdlc(netdev)->xmit = hostess_queue_xmit;
netdev->netdev_ops = &hostess_ops;
netdev->base_addr = iobase;
netdev->irq = irq;
if (register_hdlc_device(netdev)) {
pr_err("unable to register HDLC device\n");
free_netdev(netdev);
goto free_dma;
}
z8530_describe(sv, "I/O", iobase);
sv->active = 1;
return sv;
free_dma:
if (dma == 1)
free_dma(sv->chanA.rxdma);
err_rxdma:
if (dma)
free_dma(sv->chanA.txdma);
err_txdma:
free_irq(irq, sv);
err_irq:
kfree(sv);
err_kzalloc:
release_region(iobase, 8);
return NULL;
}
static void sv11_shutdown(struct z8530_dev *dev)
{
unregister_hdlc_device(dev->chanA.netdevice);
z8530_shutdown(dev);
free_irq(dev->irq, dev);
if (dma) {
if (dma == 1)
free_dma(dev->chanA.rxdma);
free_dma(dev->chanA.txdma);
}
release_region(dev->chanA.ctrlio - 1, 8);
free_netdev(dev->chanA.netdevice);
kfree(dev);
}
static int io = 0x200;
static int irq = 9;
module_param_hw(io, int, ioport, 0);
MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
module_param_hw(dma, int, dma, 0);
MODULE_PARM_DESC(dma, "Set this to 1 to use DMA1/DMA3 for TX/RX");
module_param_hw(irq, int, irq, 0);
MODULE_PARM_DESC(irq, "The interrupt line setting for the Comtrol Hostess SV11 card");
MODULE_AUTHOR("Alan Cox");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
static struct z8530_dev *sv11_unit;
static int sv11_module_init(void)
{
sv11_unit = sv11_init(io, irq);
if (!sv11_unit)
return -ENODEV;
return 0;
}
module_init(sv11_module_init);
static void sv11_module_cleanup(void)
{
if (sv11_unit)
sv11_shutdown(sv11_unit);
}
module_exit(sv11_module_cleanup);

View File

@ -1,352 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/* Sealevel Systems 4021 driver.
*
* (c) Copyright 1999, 2001 Alan Cox
* (c) Copyright 2001 Red Hat Inc.
* Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/net.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
#include <linux/hdlc.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <net/arp.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/byteorder.h>
#include "z85230.h"
struct slvl_device {
struct z8530_channel *chan;
int channel;
};
struct slvl_board {
struct slvl_device dev[2];
struct z8530_dev board;
int iobase;
};
/* Network driver support routines */
static inline struct slvl_device *dev_to_chan(struct net_device *dev)
{
return (struct slvl_device *)dev_to_hdlc(dev)->priv;
}
/* Frame receive. Simple for our card as we do HDLC and there
* is no funny garbage involved
*/
static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb)
{
/* Drop the CRC - it's not a good idea to try and negotiate it ;) */
skb_trim(skb, skb->len - 2);
skb->protocol = hdlc_type_trans(skb, c->netdevice);
skb_reset_mac_header(skb);
skb->dev = c->netdevice;
netif_rx(skb);
}
/* We've been placed in the UP state */
static int sealevel_open(struct net_device *d)
{
struct slvl_device *slvl = dev_to_chan(d);
int err = -1;
int unit = slvl->channel;
/* Link layer up. */
switch (unit) {
case 0:
err = z8530_sync_dma_open(d, slvl->chan);
break;
case 1:
err = z8530_sync_open(d, slvl->chan);
break;
}
if (err)
return err;
err = hdlc_open(d);
if (err) {
switch (unit) {
case 0:
z8530_sync_dma_close(d, slvl->chan);
break;
case 1:
z8530_sync_close(d, slvl->chan);
break;
}
return err;
}
slvl->chan->rx_function = sealevel_input;
netif_start_queue(d);
return 0;
}
static int sealevel_close(struct net_device *d)
{
struct slvl_device *slvl = dev_to_chan(d);
int unit = slvl->channel;
/* Discard new frames */
slvl->chan->rx_function = z8530_null_rx;
hdlc_close(d);
netif_stop_queue(d);
switch (unit) {
case 0:
z8530_sync_dma_close(d, slvl->chan);
break;
case 1:
z8530_sync_close(d, slvl->chan);
break;
}
return 0;
}
/* Passed network frames, fire them downwind. */
static netdev_tx_t sealevel_queue_xmit(struct sk_buff *skb,
struct net_device *d)
{
return z8530_queue_xmit(dev_to_chan(d)->chan, skb);
}
static int sealevel_attach(struct net_device *dev, unsigned short encoding,
unsigned short parity)
{
if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
return 0;
return -EINVAL;
}
static const struct net_device_ops sealevel_ops = {
.ndo_open = sealevel_open,
.ndo_stop = sealevel_close,
.ndo_start_xmit = hdlc_start_xmit,
.ndo_siocwandev = hdlc_ioctl,
};
static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
{
struct net_device *dev = alloc_hdlcdev(sv);
if (!dev)
return -1;
dev_to_hdlc(dev)->attach = sealevel_attach;
dev_to_hdlc(dev)->xmit = sealevel_queue_xmit;
dev->netdev_ops = &sealevel_ops;
dev->base_addr = iobase;
dev->irq = irq;
if (register_hdlc_device(dev)) {
pr_err("unable to register HDLC device\n");
free_netdev(dev);
return -1;
}
sv->chan->netdevice = dev;
return 0;
}
/* Allocate and setup Sealevel board. */
static __init struct slvl_board *slvl_init(int iobase, int irq,
int txdma, int rxdma, int slow)
{
struct z8530_dev *dev;
struct slvl_board *b;
/* Get the needed I/O space */
if (!request_region(iobase, 8, "Sealevel 4021")) {
pr_warn("I/O 0x%X already in use\n", iobase);
return NULL;
}
b = kzalloc(sizeof(struct slvl_board), GFP_KERNEL);
if (!b)
goto err_kzalloc;
b->dev[0].chan = &b->board.chanA;
b->dev[0].channel = 0;
b->dev[1].chan = &b->board.chanB;
b->dev[1].channel = 1;
dev = &b->board;
/* Stuff in the I/O addressing */
dev->active = 0;
b->iobase = iobase;
/* Select 8530 delays for the old board */
if (slow)
iobase |= Z8530_PORT_SLEEP;
dev->chanA.ctrlio = iobase + 1;
dev->chanA.dataio = iobase;
dev->chanB.ctrlio = iobase + 3;
dev->chanB.dataio = iobase + 2;
dev->chanA.irqs = &z8530_nop;
dev->chanB.irqs = &z8530_nop;
/* Assert DTR enable DMA */
outb(3 | (1 << 7), b->iobase + 4);
/* We want a fast IRQ for this device. Actually we'd like an even faster
* IRQ ;) - This is one driver RtLinux is made for
*/
if (request_irq(irq, z8530_interrupt, 0,
"SeaLevel", dev) < 0) {
pr_warn("IRQ %d already in use\n", irq);
goto err_request_irq;
}
dev->irq = irq;
dev->chanA.private = &b->dev[0];
dev->chanB.private = &b->dev[1];
dev->chanA.dev = dev;
dev->chanB.dev = dev;
dev->chanA.txdma = 3;
dev->chanA.rxdma = 1;
if (request_dma(dev->chanA.txdma, "SeaLevel (TX)"))
goto err_dma_tx;
if (request_dma(dev->chanA.rxdma, "SeaLevel (RX)"))
goto err_dma_rx;
disable_irq(irq);
/* Begin normal initialise */
if (z8530_init(dev) != 0) {
pr_err("Z8530 series device not found\n");
enable_irq(irq);
goto free_hw;
}
if (dev->type == Z85C30) {
z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream);
} else {
z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230);
z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream_85230);
}
/* Now we can take the IRQ */
enable_irq(irq);
if (slvl_setup(&b->dev[0], iobase, irq))
goto free_hw;
if (slvl_setup(&b->dev[1], iobase, irq))
goto free_netdev0;
z8530_describe(dev, "I/O", iobase);
dev->active = 1;
return b;
free_netdev0:
unregister_hdlc_device(b->dev[0].chan->netdevice);
free_netdev(b->dev[0].chan->netdevice);
free_hw:
free_dma(dev->chanA.rxdma);
err_dma_rx:
free_dma(dev->chanA.txdma);
err_dma_tx:
free_irq(irq, dev);
err_request_irq:
kfree(b);
err_kzalloc:
release_region(iobase, 8);
return NULL;
}
static void __exit slvl_shutdown(struct slvl_board *b)
{
int u;
z8530_shutdown(&b->board);
for (u = 0; u < 2; u++) {
struct net_device *d = b->dev[u].chan->netdevice;
unregister_hdlc_device(d);
free_netdev(d);
}
free_irq(b->board.irq, &b->board);
free_dma(b->board.chanA.rxdma);
free_dma(b->board.chanA.txdma);
/* DMA off on the card, drop DTR */
outb(0, b->iobase);
release_region(b->iobase, 8);
kfree(b);
}
static int io = 0x238;
static int txdma = 1;
static int rxdma = 3;
static int irq = 5;
static bool slow;
module_param_hw(io, int, ioport, 0);
MODULE_PARM_DESC(io, "The I/O base of the Sealevel card");
module_param_hw(txdma, int, dma, 0);
MODULE_PARM_DESC(txdma, "Transmit DMA channel");
module_param_hw(rxdma, int, dma, 0);
MODULE_PARM_DESC(rxdma, "Receive DMA channel");
module_param_hw(irq, int, irq, 0);
MODULE_PARM_DESC(irq, "The interrupt line setting for the SeaLevel card");
module_param(slow, bool, 0);
MODULE_PARM_DESC(slow, "Set this for an older Sealevel card such as the 4012");
MODULE_AUTHOR("Alan Cox");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Modular driver for the SeaLevel 4021");
static struct slvl_board *slvl_unit;
static int __init slvl_init_module(void)
{
slvl_unit = slvl_init(io, irq, txdma, rxdma, slow);
return slvl_unit ? 0 : -ENODEV;
}
static void __exit slvl_cleanup_module(void)
{
if (slvl_unit)
slvl_shutdown(slvl_unit);
}
module_init(slvl_init_module);
module_exit(slvl_cleanup_module);

File diff suppressed because it is too large Load Diff

View File

@ -1,407 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Description of Z8530 Z85C30 and Z85230 communications chips
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1998 Alan Cox <alan@lxorguk.ukuu.org.uk>
*/
#ifndef _Z8530_H
#define _Z8530_H
#include <linux/tty.h>
#include <linux/interrupt.h>
/* Conversion routines to/from brg time constants from/to bits
* per second.
*/
#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2))
#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2)
/* The Zilog register set */
#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 RPRIME 16 /* Indicate a prime register access on 230 */
#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 PRIME 1 /* R5' etc register access (Z85C30/230 only) */
#define ZCIE 2 /* Zero count IE */
#define FIFOE 4 /* Z85230 only */
#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) */
/*
* Interrupt handling functions for this SCC
*/
struct z8530_channel;
struct z8530_irqhandler
{
void (*rx)(struct z8530_channel *);
void (*tx)(struct z8530_channel *);
void (*status)(struct z8530_channel *);
};
/*
* A channel of the Z8530
*/
struct z8530_channel
{
struct z8530_irqhandler *irqs; /* IRQ handlers */
/*
* Synchronous
*/
u16 count; /* Buyes received */
u16 max; /* Most we can receive this frame */
u16 mtu; /* MTU of the device */
u8 *dptr; /* Pointer into rx buffer */
struct sk_buff *skb; /* Buffer dptr points into */
struct sk_buff *skb2; /* Pending buffer */
u8 status; /* Current DCD */
u8 dcdcheck; /* which bit to check for line */
u8 sync; /* Set if in sync mode */
u8 regs[32]; /* Register map for the chip */
u8 pendregs[32]; /* Pending register values */
struct sk_buff *tx_skb; /* Buffer being transmitted */
struct sk_buff *tx_next_skb; /* Next transmit buffer */
u8 *tx_ptr; /* Byte pointer into the buffer */
u8 *tx_next_ptr; /* Next pointer to use */
u8 *tx_dma_buf[2]; /* TX flip buffers for DMA */
u8 tx_dma_used; /* Flip buffer usage toggler */
u16 txcount; /* Count of bytes to transmit */
void (*rx_function)(struct z8530_channel *, struct sk_buff *);
/*
* Sync DMA
*/
u8 rxdma; /* DMA channels */
u8 txdma;
u8 rxdma_on; /* DMA active if flag set */
u8 txdma_on;
u8 dma_num; /* Buffer we are DMAing into */
u8 dma_ready; /* Is the other buffer free */
u8 dma_tx; /* TX is to use DMA */
u8 *rx_buf[2]; /* The flip buffers */
/*
* System
*/
struct z8530_dev *dev; /* Z85230 chip instance we are from */
unsigned long ctrlio; /* I/O ports */
unsigned long dataio;
/*
* For PC we encode this way.
*/
#define Z8530_PORT_SLEEP 0x80000000
#define Z8530_PORT_OF(x) ((x)&0xFFFF)
u32 rx_overrun; /* Overruns - not done yet */
u32 rx_crc_err;
/*
* Bound device pointers
*/
void *private; /* For our owner */
struct net_device *netdevice; /* Network layer device */
spinlock_t *lock; /* Device lock */
};
/*
* Each Z853x0 device.
*/
struct z8530_dev
{
char *name; /* Device instance name */
struct z8530_channel chanA; /* SCC channel A */
struct z8530_channel chanB; /* SCC channel B */
int type;
#define Z8530 0 /* NMOS dinosaur */
#define Z85C30 1 /* CMOS - better */
#define Z85230 2 /* CMOS with real FIFO */
int irq; /* Interrupt for the device */
int active; /* Soft interrupt enable - the Mac doesn't
always have a hard disable on its 8530s... */
spinlock_t lock;
};
/*
* Functions
*/
extern u8 z8530_dead_port[];
extern u8 z8530_hdlc_kilostream_85230[];
extern u8 z8530_hdlc_kilostream[];
irqreturn_t z8530_interrupt(int, void *);
void z8530_describe(struct z8530_dev *, char *mapping, unsigned long io);
int z8530_init(struct z8530_dev *);
int z8530_shutdown(struct z8530_dev *);
int z8530_sync_open(struct net_device *, struct z8530_channel *);
int z8530_sync_close(struct net_device *, struct z8530_channel *);
int z8530_sync_dma_open(struct net_device *, struct z8530_channel *);
int z8530_sync_dma_close(struct net_device *, struct z8530_channel *);
int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *);
int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *);
int z8530_channel_load(struct z8530_channel *, u8 *);
netdev_tx_t z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb);
void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb);
/*
* Standard interrupt vector sets
*/
extern struct z8530_irqhandler z8530_sync, z8530_async, z8530_nop;
/*
* Asynchronous Interfacing
*/
/*
* The size of the serial xmit buffer is 1 page, or 4096 bytes
*/
#define SERIAL_XMIT_SIZE 4096
#define WAKEUP_CHARS 256
/*
* Events are used to schedule things to happen at timer-interrupt
* time, instead of at rs interrupt time.
*/
#define RS_EVENT_WRITE_WAKEUP 0
/* Internal flags used only by kernel/chr_drv/serial.c */
#define ZILOG_INITIALIZED 0x80000000 /* Serial port was initialized */
#define ZILOG_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */
#define ZILOG_NORMAL_ACTIVE 0x20000000 /* Normal device is active */
#define ZILOG_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */
#define ZILOG_CLOSING 0x08000000 /* Serial port is closing */
#define ZILOG_CTS_FLOW 0x04000000 /* Do CTS flow control */
#define ZILOG_CHECK_CD 0x02000000 /* i.e., CLOCAL */
#endif /* !(_Z8530_H) */