Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

401
drivers/atm/Kconfig Normal file
View file

@ -0,0 +1,401 @@
#
# ATM device configuration
#
menuconfig ATM_DRIVERS
bool "ATM drivers"
depends on NETDEVICES && ATM
default y
---help---
Say Y here to get to see options for Asynchronous Transfer Mode
device drivers. This option alone does not add any kernel code.
If you say N, all options in this submenu will be skipped and disabled.
if ATM_DRIVERS && NETDEVICES && ATM
config ATM_DUMMY
tristate "Dummy ATM driver"
help
Dummy ATM driver. Useful for proxy signalling, testing,
and development. If unsure, say N.
config ATM_TCP
tristate "ATM over TCP"
depends on INET
help
ATM over TCP driver. Useful mainly for development and for
experiments. If unsure, say N.
config ATM_LANAI
tristate "Efficient Networks Speedstream 3010"
depends on PCI && ATM
help
Supports ATM cards based on the Efficient Networks "Lanai"
chipset such as the Speedstream 3010 and the ENI-25p. The
Speedstream 3060 is currently not supported since we don't
have the code to drive the on-board Alcatel DSL chipset (yet).
config ATM_ENI
tristate "Efficient Networks ENI155P"
depends on PCI
---help---
Driver for the Efficient Networks ENI155p series and SMC ATM
Power155 155 Mbps ATM adapters. Both, the versions with 512KB and
2MB on-board RAM (Efficient calls them "C" and "S", respectively),
and the FPGA and the ASIC Tonga versions of the board are supported.
The driver works with MMF (-MF or ...F) and UTP-5 (-U5 or ...D)
adapters.
To compile this driver as a module, choose M here: the module will
be called eni.
config ATM_ENI_DEBUG
bool "Enable extended debugging"
depends on ATM_ENI
help
Extended debugging records various events and displays that list
when an inconsistency is detected. This mechanism is faster than
generally using printks, but still has some impact on performance.
Note that extended debugging may create certain race conditions
itself. Enable this ONLY if you suspect problems with the driver.
config ATM_ENI_TUNE_BURST
bool "Fine-tune burst settings"
depends on ATM_ENI
---help---
In order to obtain good throughput, the ENI NIC can transfer
multiple words of data per PCI bus access cycle. Such a multi-word
transfer is called a burst.
The default settings for the burst sizes are suitable for most PCI
chipsets. However, in some cases, large bursts may overrun buffers
in the PCI chipset and cause data corruption. In such cases, large
bursts must be disabled and only (slower) small bursts can be used.
The burst sizes can be set independently in the send (TX) and
receive (RX) direction.
Note that enabling many different burst sizes in the same direction
may increase the cost of setting up a transfer such that the
resulting throughput is lower than when using only the largest
available burst size.
Also, sometimes larger bursts lead to lower throughput, e.g. on an
Intel 440FX board, a drop from 135 Mbps to 103 Mbps was observed
when going from 8W to 16W bursts.
config ATM_ENI_BURST_TX_16W
bool "Enable 16W TX bursts (discouraged)"
depends on ATM_ENI_TUNE_BURST
help
Burst sixteen words at once in the send direction. This may work
with recent PCI chipsets, but is known to fail with older chipsets.
config ATM_ENI_BURST_TX_8W
bool "Enable 8W TX bursts (recommended)"
depends on ATM_ENI_TUNE_BURST
help
Burst eight words at once in the send direction. This is the default
setting.
config ATM_ENI_BURST_TX_4W
bool "Enable 4W TX bursts (optional)"
depends on ATM_ENI_TUNE_BURST
help
Burst four words at once in the send direction. You may want to try
this if you have disabled 8W bursts. Enabling 4W if 8W is also set
may or may not improve throughput.
config ATM_ENI_BURST_TX_2W
bool "Enable 2W TX bursts (optional)"
depends on ATM_ENI_TUNE_BURST
help
Burst two words at once in the send direction. You may want to try
this if you have disabled 4W and 8W bursts. Enabling 2W if 4W or 8W
are also set may or may not improve throughput.
config ATM_ENI_BURST_RX_16W
bool "Enable 16W RX bursts (discouraged)"
depends on ATM_ENI_TUNE_BURST
help
Burst sixteen words at once in the receive direction. This may work
with recent PCI chipsets, but is known to fail with older chipsets.
config ATM_ENI_BURST_RX_8W
bool "Enable 8W RX bursts (discouraged)"
depends on ATM_ENI_TUNE_BURST
help
Burst eight words at once in the receive direction. This may work
with recent PCI chipsets, but is known to fail with older chipsets,
such as the Intel Neptune series.
config ATM_ENI_BURST_RX_4W
bool "Enable 4W RX bursts (recommended)"
depends on ATM_ENI_TUNE_BURST
help
Burst four words at once in the receive direction. This is the
default setting. Enabling 4W if 8W is also set may or may not
improve throughput.
config ATM_ENI_BURST_RX_2W
bool "Enable 2W RX bursts (optional)"
depends on ATM_ENI_TUNE_BURST
help
Burst two words at once in the receive direction. You may want to
try this if you have disabled 4W and 8W bursts. Enabling 2W if 4W or
8W are also set may or may not improve throughput.
config ATM_FIRESTREAM
tristate "Fujitsu FireStream (FS50/FS155) "
depends on PCI && VIRT_TO_BUS
help
Driver for the Fujitsu FireStream 155 (MB86697) and
FireStream 50 (MB86695) ATM PCI chips.
To compile this driver as a module, choose M here: the module will
be called firestream.
config ATM_ZATM
tristate "ZeitNet ZN1221/ZN1225"
depends on PCI && VIRT_TO_BUS
help
Driver for the ZeitNet ZN1221 (MMF) and ZN1225 (UTP-5) 155 Mbps ATM
adapters.
To compile this driver as a module, choose M here: the module will
be called zatm.
config ATM_ZATM_DEBUG
bool "Enable extended debugging"
depends on ATM_ZATM
help
Extended debugging records various events and displays that list
when an inconsistency is detected. This mechanism is faster than
generally using printks, but still has some impact on performance.
Note that extended debugging may create certain race conditions
itself. Enable this ONLY if you suspect problems with the driver.
config ATM_NICSTAR
tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
depends on PCI
help
The NICStAR chipset family is used in a large number of ATM NICs for
25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE
series. Say Y if you have one of those.
To compile this driver as a module, choose M here: the module will
be called nicstar.
config ATM_NICSTAR_USE_SUNI
bool "Use suni PHY driver (155Mbps)"
depends on ATM_NICSTAR
help
Support for the S-UNI and compatible PHYsical layer chips. These are
found in most 155Mbps NICStAR based ATM cards, namely in the
ForeRunner LE155 cards. This driver provides detection of cable~
removal and reinsertion and provides some statistics. This driver
doesn't have removal capability when compiled as a module, so if you
need that capability don't include S-UNI support (it's not needed to
make the card work).
config ATM_NICSTAR_USE_IDT77105
bool "Use IDT77015 PHY driver (25Mbps)"
depends on ATM_NICSTAR
help
Support for the PHYsical layer chip in ForeRunner LE25 cards. In
addition to cable removal/reinsertion detection, this driver allows
you to control the loopback mode of the chip via a dedicated IOCTL.
This driver is required for proper handling of temporary carrier
loss, so if you have a 25Mbps NICStAR based ATM card you must say Y.
config ATM_IDT77252
tristate "IDT 77252 (NICStAR II)"
depends on PCI
help
Driver for the IDT 77252 ATM PCI chips.
To compile this driver as a module, choose M here: the module will
be called idt77252.
config ATM_IDT77252_DEBUG
bool "Enable debugging messages"
depends on ATM_IDT77252
help
Somewhat useful debugging messages are available. The choice of
messages is controlled by a bitmap. This may be specified as a
module argument. See the file <file:drivers/atm/idt77252.h> for
the meanings of the bits in the mask.
When active, these messages can have a significant impact on the
speed of the driver, and the size of your syslog files! When
inactive, they will have only a modest impact on performance.
config ATM_IDT77252_RCV_ALL
bool "Receive ALL cells in raw queue"
depends on ATM_IDT77252
help
Enable receiving of all cells on the ATM link, that do not match
an open connection in the raw cell queue of the driver. Useful
for debugging or special applications only, so the safe answer is N.
config ATM_IDT77252_USE_SUNI
bool
depends on ATM_IDT77252
default y
config ATM_AMBASSADOR
tristate "Madge Ambassador (Collage PCI 155 Server)"
depends on PCI && VIRT_TO_BUS
select BITREVERSE
help
This is a driver for ATMizer based ATM card produced by Madge
Networks Ltd. Say Y (or M to compile as a module named ambassador)
here if you have one of these cards.
config ATM_AMBASSADOR_DEBUG
bool "Enable debugging messages"
depends on ATM_AMBASSADOR
---help---
Somewhat useful debugging messages are available. The choice of
messages is controlled by a bitmap. This may be specified as a
module argument (kernel command line argument as well?), changed
dynamically using an ioctl (not yet) or changed by sending the
string "Dxxxx" to VCI 1023 (where x is a hex digit). See the file
<file:drivers/atm/ambassador.h> for the meanings of the bits in the
mask.
When active, these messages can have a significant impact on the
speed of the driver, and the size of your syslog files! When
inactive, they will have only a modest impact on performance.
config ATM_HORIZON
tristate "Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)"
depends on PCI && VIRT_TO_BUS
help
This is a driver for the Horizon chipset ATM adapter cards once
produced by Madge Networks Ltd. Say Y (or M to compile as a module
named horizon) here if you have one of these cards.
config ATM_HORIZON_DEBUG
bool "Enable debugging messages"
depends on ATM_HORIZON
---help---
Somewhat useful debugging messages are available. The choice of
messages is controlled by a bitmap. This may be specified as a
module argument (kernel command line argument as well?), changed
dynamically using an ioctl (not yet) or changed by sending the
string "Dxxxx" to VCI 1023 (where x is a hex digit). See the file
<file:drivers/atm/horizon.h> for the meanings of the bits in the
mask.
When active, these messages can have a significant impact on the
speed of the driver, and the size of your syslog files! When
inactive, they will have only a modest impact on performance.
config ATM_IA
tristate "Interphase ATM PCI x575/x525/x531"
depends on PCI
---help---
This is a driver for the Interphase (i)ChipSAR adapter cards
which include a variety of variants in term of the size of the
control memory (128K-1KVC, 512K-4KVC), the size of the packet
memory (128K, 512K, 1M), and the PHY type (Single/Multi mode OC3,
UTP155, UTP25, DS3 and E3). Go to:
<http://www.iphase.com/>
for more info about the cards. Say Y (or M to compile as a module
named iphase) here if you have one of these cards.
See the file <file:Documentation/networking/iphase.txt> for further
details.
config ATM_IA_DEBUG
bool "Enable debugging messages"
depends on ATM_IA
---help---
Somewhat useful debugging messages are available. The choice of
messages is controlled by a bitmap. This may be specified as a
module argument (kernel command line argument as well?), changed
dynamically using an ioctl (Get the debug utility, iadbg, from
<ftp://ftp.iphase.com/pub/atm/pci/>).
See the file <file:drivers/atm/iphase.h> for the meanings of the
bits in the mask.
When active, these messages can have a significant impact on the
speed of the driver, and the size of your syslog files! When
inactive, they will have only a modest impact on performance.
config ATM_FORE200E
tristate "FORE Systems 200E-series"
depends on (PCI || SBUS)
select FW_LOADER
---help---
This is a driver for the FORE Systems 200E-series ATM adapter
cards. It simultaneously supports PCA-200E and SBA-200E models
on PCI and SBUS hosts. Say Y (or M to compile as a module
named fore_200e) here if you have one of these ATM adapters.
See the file <file:Documentation/networking/fore200e.txt> for
further details.
config ATM_FORE200E_USE_TASKLET
bool "Defer interrupt work to a tasklet"
depends on ATM_FORE200E
default n
help
This defers work to be done by the interrupt handler to a
tasklet instead of handling everything at interrupt time. This
may improve the responsive of the host.
config ATM_FORE200E_TX_RETRY
int "Maximum number of tx retries"
depends on ATM_FORE200E
default "16"
---help---
Specifies the number of times the driver attempts to transmit
a message before giving up, if the transmit queue of the ATM card
is transiently saturated.
Saturation of the transmit queue may occur only under extreme
conditions, e.g. when a fast host continuously submits very small
frames (<64 bytes) or raw AAL0 cells (48 bytes) to the ATM adapter.
Note that under common conditions, it is unlikely that you encounter
a saturation of the transmit queue, so the retry mechanism never
comes into play.
config ATM_FORE200E_DEBUG
int "Debugging level (0-3)"
depends on ATM_FORE200E
default "0"
help
Specifies the level of debugging messages issued by the driver.
The verbosity of the driver increases with the value of this
parameter.
When active, these messages can have a significant impact on
the performances of the driver, and the size of your syslog files!
Keep the debugging level to 0 during normal operations.
config ATM_HE
tristate "ForeRunner HE Series"
depends on PCI
help
This is a driver for the Marconi ForeRunner HE-series ATM adapter
cards. It simultaneously supports the 155 and 622 versions.
config ATM_HE_USE_SUNI
bool "Use S/UNI PHY driver"
depends on ATM_HE
help
Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner
HE cards. This driver provides carrier detection some statistics.
config ATM_SOLOS
tristate "Solos ADSL2+ PCI Multiport card driver"
depends on PCI
select FW_LOADER
help
Support for the Solos multiport ADSL2+ card.
endif # ATM

35
drivers/atm/Makefile Normal file
View file

@ -0,0 +1,35 @@
#
# Makefile for the Linux network (ATM) device drivers.
#
fore_200e-y := fore200e.o
obj-$(CONFIG_ATM_ZATM) += zatm.o uPD98402.o
obj-$(CONFIG_ATM_NICSTAR) += nicstar.o
obj-$(CONFIG_ATM_AMBASSADOR) += ambassador.o
obj-$(CONFIG_ATM_HORIZON) += horizon.o
obj-$(CONFIG_ATM_IA) += iphase.o suni.o
obj-$(CONFIG_ATM_FORE200E) += fore_200e.o
obj-$(CONFIG_ATM_ENI) += eni.o suni.o
obj-$(CONFIG_ATM_IDT77252) += idt77252.o
obj-$(CONFIG_ATM_SOLOS) += solos-pci.o
ifeq ($(CONFIG_ATM_NICSTAR_USE_SUNI),y)
obj-$(CONFIG_ATM_NICSTAR) += suni.o
endif
ifeq ($(CONFIG_ATM_NICSTAR_USE_IDT77105),y)
obj-$(CONFIG_ATM_NICSTAR) += idt77105.o
endif
ifeq ($(CONFIG_ATM_IDT77252_USE_SUNI),y)
obj-$(CONFIG_ATM_IDT77252) += suni.o
endif
obj-$(CONFIG_ATM_DUMMY) += adummy.o
obj-$(CONFIG_ATM_TCP) += atmtcp.o
obj-$(CONFIG_ATM_FIRESTREAM) += firestream.o
obj-$(CONFIG_ATM_LANAI) += lanai.o
obj-$(CONFIG_ATM_HE) += he.o
ifeq ($(CONFIG_ATM_HE_USE_SUNI),y)
obj-$(CONFIG_ATM_HE) += suni.o
endif

202
drivers/atm/adummy.c Normal file
View file

@ -0,0 +1,202 @@
/*
* adummy.c: a dummy ATM driver
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <linux/atmdev.h>
#include <linux/atm.h>
#include <linux/sonet.h>
/* version definition */
#define DRV_VERSION "1.0"
#define DEV_LABEL "adummy"
#define ADUMMY_DEV(dev) ((struct adummy_dev *) (dev)->dev_data)
struct adummy_dev {
struct atm_dev *atm_dev;
struct list_head entry;
};
/* globals */
static LIST_HEAD(adummy_devs);
static ssize_t __set_signal(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
int signal;
if (sscanf(buf, "%d", &signal) == 1) {
if (signal < ATM_PHY_SIG_LOST || signal > ATM_PHY_SIG_FOUND)
signal = ATM_PHY_SIG_UNKNOWN;
atm_dev_signal_change(atm_dev, signal);
return 1;
}
return -EINVAL;
}
static ssize_t __show_signal(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct atm_dev *atm_dev = container_of(dev, struct atm_dev, class_dev);
return sprintf(buf, "%d\n", atm_dev->signal);
}
static DEVICE_ATTR(signal, 0644, __show_signal, __set_signal);
static struct attribute *adummy_attrs[] = {
&dev_attr_signal.attr,
NULL
};
static struct attribute_group adummy_group_attrs = {
.name = NULL, /* We want them in dev's root folder */
.attrs = adummy_attrs
};
static int __init
adummy_start(struct atm_dev *dev)
{
dev->ci_range.vpi_bits = 4;
dev->ci_range.vci_bits = 12;
return 0;
}
static int
adummy_open(struct atm_vcc *vcc)
{
short vpi = vcc->vpi;
int vci = vcc->vci;
if (vci == ATM_VCI_UNSPEC || vpi == ATM_VPI_UNSPEC)
return 0;
set_bit(ATM_VF_ADDR, &vcc->flags);
set_bit(ATM_VF_READY, &vcc->flags);
return 0;
}
static void
adummy_close(struct atm_vcc *vcc)
{
clear_bit(ATM_VF_READY, &vcc->flags);
clear_bit(ATM_VF_ADDR, &vcc->flags);
}
static int
adummy_send(struct atm_vcc *vcc, struct sk_buff *skb)
{
if (vcc->pop)
vcc->pop(vcc, skb);
else
dev_kfree_skb_any(skb);
atomic_inc(&vcc->stats->tx);
return 0;
}
static int
adummy_proc_read(struct atm_dev *dev, loff_t *pos, char *page)
{
int left = *pos;
if (!left--)
return sprintf(page, "version %s\n", DRV_VERSION);
return 0;
}
static struct atmdev_ops adummy_ops =
{
.open = adummy_open,
.close = adummy_close,
.send = adummy_send,
.proc_read = adummy_proc_read,
.owner = THIS_MODULE
};
static int __init adummy_init(void)
{
struct atm_dev *atm_dev;
struct adummy_dev *adummy_dev;
int err = 0;
printk(KERN_ERR "adummy: version %s\n", DRV_VERSION);
adummy_dev = kzalloc(sizeof(struct adummy_dev),
GFP_KERNEL);
if (!adummy_dev) {
printk(KERN_ERR DEV_LABEL ": kzalloc() failed\n");
err = -ENOMEM;
goto out;
}
atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL);
if (!atm_dev) {
printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n");
err = -ENODEV;
goto out_kfree;
}
adummy_dev->atm_dev = atm_dev;
atm_dev->dev_data = adummy_dev;
if (sysfs_create_group(&atm_dev->class_dev.kobj, &adummy_group_attrs))
dev_err(&atm_dev->class_dev, "Could not register attrs for adummy\n");
if (adummy_start(atm_dev)) {
printk(KERN_ERR DEV_LABEL ": adummy_start() failed\n");
err = -ENODEV;
goto out_unregister;
}
list_add(&adummy_dev->entry, &adummy_devs);
out:
return err;
out_unregister:
atm_dev_deregister(atm_dev);
out_kfree:
kfree(adummy_dev);
goto out;
}
static void __exit adummy_cleanup(void)
{
struct adummy_dev *adummy_dev, *next;
list_for_each_entry_safe(adummy_dev, next, &adummy_devs, entry) {
atm_dev_deregister(adummy_dev->atm_dev);
kfree(adummy_dev);
}
}
module_init(adummy_init);
module_exit(adummy_cleanup);
MODULE_AUTHOR("chas williams <chas@cmf.nrl.navy.mil>");
MODULE_DESCRIPTION("dummy ATM driver");
MODULE_LICENSE("GPL");

2422
drivers/atm/ambassador.c Normal file

File diff suppressed because it is too large Load diff

663
drivers/atm/ambassador.h Normal file
View file

@ -0,0 +1,663 @@
/*
Madge Ambassador ATM Adapter driver.
Copyright (C) 1995-1999 Madge Networks Ltd.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The GNU GPL is contained in /usr/doc/copyright/GPL on a Debian
system and in the file COPYING in the Linux kernel source.
*/
#ifndef AMBASSADOR_H
#define AMBASSADOR_H
#ifdef CONFIG_ATM_AMBASSADOR_DEBUG
#define DEBUG_AMBASSADOR
#endif
#define DEV_LABEL "amb"
#ifndef PCI_VENDOR_ID_MADGE
#define PCI_VENDOR_ID_MADGE 0x10B6
#endif
#ifndef PCI_VENDOR_ID_MADGE_AMBASSADOR
#define PCI_DEVICE_ID_MADGE_AMBASSADOR 0x1001
#endif
#ifndef PCI_VENDOR_ID_MADGE_AMBASSADOR_BAD
#define PCI_DEVICE_ID_MADGE_AMBASSADOR_BAD 0x1002
#endif
// diagnostic output
#define PRINTK(severity,format,args...) \
printk(severity DEV_LABEL ": " format "\n" , ## args)
#ifdef DEBUG_AMBASSADOR
#define DBG_ERR 0x0001
#define DBG_WARN 0x0002
#define DBG_INFO 0x0004
#define DBG_INIT 0x0008
#define DBG_LOAD 0x0010
#define DBG_VCC 0x0020
#define DBG_QOS 0x0040
#define DBG_CMD 0x0080
#define DBG_TX 0x0100
#define DBG_RX 0x0200
#define DBG_SKB 0x0400
#define DBG_POOL 0x0800
#define DBG_IRQ 0x1000
#define DBG_FLOW 0x2000
#define DBG_REGS 0x4000
#define DBG_DATA 0x8000
#define DBG_MASK 0xffff
/* the ## prevents the annoying double expansion of the macro arguments */
/* KERN_INFO is used since KERN_DEBUG often does not make it to the console */
#define PRINTDB(bits,format,args...) \
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format , ## args) : 1 )
#define PRINTDM(bits,format,args...) \
( (debug & (bits)) ? printk (format , ## args) : 1 )
#define PRINTDE(bits,format,args...) \
( (debug & (bits)) ? printk (format "\n" , ## args) : 1 )
#define PRINTD(bits,format,args...) \
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format "\n" , ## args) : 1 )
#else
#define PRINTD(bits,format,args...)
#define PRINTDB(bits,format,args...)
#define PRINTDM(bits,format,args...)
#define PRINTDE(bits,format,args...)
#endif
#define PRINTDD(bits,format,args...)
#define PRINTDDB(sec,fmt,args...)
#define PRINTDDM(sec,fmt,args...)
#define PRINTDDE(sec,fmt,args...)
// tunable values (?)
/* MUST be powers of two -- why ? */
#define COM_Q_ENTRIES 8
#define TX_Q_ENTRIES 32
#define RX_Q_ENTRIES 64
// fixed values
// guessing
#define AMB_EXTENT 0x80
// Minimum allowed size for an Ambassador queue
#define MIN_QUEUE_SIZE 2
// Ambassador microcode allows 1 to 4 pools, we use 4 (simpler)
#define NUM_RX_POOLS 4
// minimum RX buffers required to cope with replenishing delay
#define MIN_RX_BUFFERS 1
// minimum PCI latency we will tolerate (32 IS TOO SMALL)
#define MIN_PCI_LATENCY 64 // 255
// VCs supported by card (VPI always 0)
#define NUM_VPI_BITS 0
#define NUM_VCI_BITS 10
#define NUM_VCS 1024
/* The status field bits defined so far. */
#define RX_ERR 0x8000 // always present if there is an error (hmm)
#define CRC_ERR 0x4000 // AAL5 CRC error
#define LEN_ERR 0x2000 // overlength frame
#define ABORT_ERR 0x1000 // zero length field in received frame
#define UNUSED_ERR 0x0800 // buffer returned unused
// Adaptor commands
#define SRB_OPEN_VC 0
/* par_0: dwordswap(VC_number) */
/* par_1: dwordswap(flags<<16) or wordswap(flags)*/
/* flags: */
/* LANE: 0x0004 */
/* NOT_UBR: 0x0008 */
/* ABR: 0x0010 */
/* RxPool0: 0x0000 */
/* RxPool1: 0x0020 */
/* RxPool2: 0x0040 */
/* RxPool3: 0x0060 */
/* par_2: dwordswap(fp_rate<<16) or wordswap(fp_rate) */
#define SRB_CLOSE_VC 1
/* par_0: dwordswap(VC_number) */
#define SRB_GET_BIA 2
/* returns */
/* par_0: dwordswap(half BIA) */
/* par_1: dwordswap(half BIA) */
#define SRB_GET_SUNI_STATS 3
/* par_0: dwordswap(physical_host_address) */
#define SRB_SET_BITS_8 4
#define SRB_SET_BITS_16 5
#define SRB_SET_BITS_32 6
#define SRB_CLEAR_BITS_8 7
#define SRB_CLEAR_BITS_16 8
#define SRB_CLEAR_BITS_32 9
/* par_0: dwordswap(ATMizer address) */
/* par_1: dwordswap(mask) */
#define SRB_SET_8 10
#define SRB_SET_16 11
#define SRB_SET_32 12
/* par_0: dwordswap(ATMizer address) */
/* par_1: dwordswap(data) */
#define SRB_GET_32 13
/* par_0: dwordswap(ATMizer address) */
/* returns */
/* par_1: dwordswap(ATMizer data) */
#define SRB_GET_VERSION 14
/* returns */
/* par_0: dwordswap(Major Version) */
/* par_1: dwordswap(Minor Version) */
#define SRB_FLUSH_BUFFER_Q 15
/* Only flags to define which buffer pool; all others must be zero */
/* par_0: dwordswap(flags<<16) or wordswap(flags)*/
#define SRB_GET_DMA_SPEEDS 16
/* returns */
/* par_0: dwordswap(Read speed (bytes/sec)) */
/* par_1: dwordswap(Write speed (bytes/sec)) */
#define SRB_MODIFY_VC_RATE 17
/* par_0: dwordswap(VC_number) */
/* par_1: dwordswap(fp_rate<<16) or wordswap(fp_rate) */
#define SRB_MODIFY_VC_FLAGS 18
/* par_0: dwordswap(VC_number) */
/* par_1: dwordswap(flags<<16) or wordswap(flags)*/
/* flags: */
/* LANE: 0x0004 */
/* NOT_UBR: 0x0008 */
/* ABR: 0x0010 */
/* RxPool0: 0x0000 */
/* RxPool1: 0x0020 */
/* RxPool2: 0x0040 */
/* RxPool3: 0x0060 */
#define SRB_RATE_SHIFT 16
#define SRB_POOL_SHIFT (SRB_FLAGS_SHIFT+5)
#define SRB_FLAGS_SHIFT 16
#define SRB_STOP_TASKING 19
#define SRB_START_TASKING 20
#define SRB_SHUT_DOWN 21
#define MAX_SRB 21
#define SRB_COMPLETE 0xffffffff
#define TX_FRAME 0x80000000
// number of types of SRB MUST be a power of two -- why?
#define NUM_OF_SRB 32
// number of bits of period info for rate
#define MAX_RATE_BITS 6
#define TX_UBR 0x0000
#define TX_UBR_CAPPED 0x0008
#define TX_ABR 0x0018
#define TX_FRAME_NOTCAP 0x0000
#define TX_FRAME_CAPPED 0x8000
#define FP_155_RATE 0x24b1
#define FP_25_RATE 0x1f9d
/* #define VERSION_NUMBER 0x01000000 // initial release */
/* #define VERSION_NUMBER 0x01010000 // fixed startup probs PLX MB0 not cleared */
/* #define VERSION_NUMBER 0x01020000 // changed SUNI reset timings; allowed r/w onchip */
/* #define VERSION_NUMBER 0x01030000 // clear local doorbell int reg on reset */
/* #define VERSION_NUMBER 0x01040000 // PLX bug work around version PLUS */
/* remove race conditions on basic interface */
/* indicate to the host that diagnostics */
/* have finished; if failed, how and what */
/* failed */
/* fix host memory test to fix PLX bug */
/* allow flash upgrade and BIA upgrade directly */
/* */
#define VERSION_NUMBER 0x01050025 /* Jason's first hacked version. */
/* Change in download algorithm */
#define DMA_VALID 0xb728e149 /* completely random */
#define FLASH_BASE 0xa0c00000
#define FLASH_SIZE 0x00020000 /* 128K */
#define BIA_BASE (FLASH_BASE+0x0001c000) /* Flash Sector 7 */
#define BIA_ADDRESS ((void *)0xa0c1c000)
#define PLX_BASE 0xe0000000
typedef enum {
host_memory_test = 1,
read_adapter_memory,
write_adapter_memory,
adapter_start,
get_version_number,
interrupt_host,
flash_erase_sector,
adap_download_block = 0x20,
adap_erase_flash,
adap_run_in_iram,
adap_end_download
} loader_command;
#define BAD_COMMAND (-1)
#define COMMAND_IN_PROGRESS 1
#define COMMAND_PASSED_TEST 2
#define COMMAND_FAILED_TEST 3
#define COMMAND_READ_DATA_OK 4
#define COMMAND_READ_BAD_ADDRESS 5
#define COMMAND_WRITE_DATA_OK 6
#define COMMAND_WRITE_BAD_ADDRESS 7
#define COMMAND_WRITE_FLASH_FAILURE 8
#define COMMAND_COMPLETE 9
#define COMMAND_FLASH_ERASE_FAILURE 10
#define COMMAND_WRITE_BAD_DATA 11
/* bit fields for mailbox[0] return values */
#define GPINT_TST_FAILURE 0x00000001
#define SUNI_DATA_PATTERN_FAILURE 0x00000002
#define SUNI_DATA_BITS_FAILURE 0x00000004
#define SUNI_UTOPIA_FAILURE 0x00000008
#define SUNI_FIFO_FAILURE 0x00000010
#define SRAM_FAILURE 0x00000020
#define SELF_TEST_FAILURE 0x0000003f
/* mailbox[1] = 0 in progress, -1 on completion */
/* mailbox[2] = current test 00 00 test(8 bit) phase(8 bit) */
/* mailbox[3] = last failure, 00 00 test(8 bit) phase(8 bit) */
/* mailbox[4],mailbox[5],mailbox[6] random failure values */
/* PLX/etc. memory map including command structure */
/* These registers may also be memory mapped in PCI memory */
#define UNUSED_LOADER_MAILBOXES 6
typedef struct {
u32 stuff[16];
union {
struct {
u32 result;
u32 ready;
u32 stuff[UNUSED_LOADER_MAILBOXES];
} loader;
struct {
u32 cmd_address;
u32 tx_address;
u32 rx_address[NUM_RX_POOLS];
u32 gen_counter;
u32 spare;
} adapter;
} mb;
u32 doorbell;
u32 interrupt;
u32 interrupt_control;
u32 reset_control;
} amb_mem;
/* RESET bit, IRQ (card to host) and doorbell (host to card) enable bits */
#define AMB_RESET_BITS 0x40000000
#define AMB_INTERRUPT_BITS 0x00000300
#define AMB_DOORBELL_BITS 0x00030000
/* loader commands */
#define MAX_COMMAND_DATA 13
#define MAX_TRANSFER_DATA 11
typedef struct {
__be32 address;
__be32 count;
__be32 data[MAX_TRANSFER_DATA];
} transfer_block;
typedef struct {
__be32 result;
__be32 command;
union {
transfer_block transfer;
__be32 version;
__be32 start;
__be32 data[MAX_COMMAND_DATA];
} payload;
__be32 valid;
} loader_block;
/* command queue */
/* Again all data are BIG ENDIAN */
typedef struct {
union {
struct {
__be32 vc;
__be32 flags;
__be32 rate;
} open;
struct {
__be32 vc;
__be32 rate;
} modify_rate;
struct {
__be32 vc;
__be32 flags;
} modify_flags;
struct {
__be32 vc;
} close;
struct {
__be32 lower4;
__be32 upper2;
} bia;
struct {
__be32 address;
} suni;
struct {
__be32 major;
__be32 minor;
} version;
struct {
__be32 read;
__be32 write;
} speed;
struct {
__be32 flags;
} flush;
struct {
__be32 address;
__be32 data;
} memory;
__be32 par[3];
} args;
__be32 request;
} command;
/* transmit queues and associated structures */
/* The hosts transmit structure. All BIG ENDIAN; host address
restricted to first 1GByte, but address passed to the card must
have the top MS bit or'ed in. -- check this */
/* TX is described by 1+ tx_frags followed by a tx_frag_end */
typedef struct {
__be32 bytes;
__be32 address;
} tx_frag;
/* apart from handle the fields here are for the adapter to play with
and should be set to zero */
typedef struct {
u32 handle;
u16 vc;
u16 next_descriptor_length;
u32 next_descriptor;
#ifdef AMB_NEW_MICROCODE
u8 cpcs_uu;
u8 cpi;
u16 pad;
#endif
} tx_frag_end;
typedef struct {
tx_frag tx_frag;
tx_frag_end tx_frag_end;
struct sk_buff * skb;
} tx_simple;
#if 0
typedef union {
tx_frag fragment;
tx_frag_end end_of_list;
} tx_descr;
#endif
/* this "points" to the sequence of fragments and trailer */
typedef struct {
__be16 vc;
__be16 tx_descr_length;
__be32 tx_descr_addr;
} tx_in;
/* handle is the handle from tx_in */
typedef struct {
u32 handle;
} tx_out;
/* receive frame structure */
/* All BIG ENDIAN; handle is as passed from host; length is zero for
aborted frames, and frames with errors. Header is actually VC
number, lec-id is NOT yet supported. */
typedef struct {
u32 handle;
__be16 vc;
__be16 lec_id; // unused
__be16 status;
__be16 length;
} rx_out;
/* buffer supply structure */
typedef struct {
u32 handle;
__be32 host_address;
} rx_in;
/* This first structure is the area in host memory where the adapter
writes its pointer values. These pointer values are BIG ENDIAN and
reside in the same 4MB 'page' as this structure. The host gives the
adapter the address of this block by sending a doorbell interrupt
to the adapter after downloading the code and setting it going. The
addresses have the top 10 bits set to 1010000010b -- really?
The host must initialise these before handing the block to the
adapter. */
typedef struct {
__be32 command_start; /* SRB commands completions */
__be32 command_end; /* SRB commands completions */
__be32 tx_start;
__be32 tx_end;
__be32 txcom_start; /* tx completions */
__be32 txcom_end; /* tx completions */
struct {
__be32 buffer_start;
__be32 buffer_end;
u32 buffer_q_get;
u32 buffer_q_end;
u32 buffer_aptr;
__be32 rx_start; /* rx completions */
__be32 rx_end;
u32 rx_ptr;
__be32 buffer_size; /* size of host buffer */
} rec_struct[NUM_RX_POOLS];
#ifdef AMB_NEW_MICROCODE
u16 init_flags;
u16 talk_block_spare;
#endif
} adap_talk_block;
/* This structure must be kept in line with the vcr image in sarmain.h
This is the structure in the host filled in by the adapter by
GET_SUNI_STATS */
typedef struct {
u8 racp_chcs;
u8 racp_uhcs;
u16 spare;
u32 racp_rcell;
u32 tacp_tcell;
u32 flags;
u32 dropped_cells;
u32 dropped_frames;
} suni_stats;
typedef enum {
dead
} amb_flags;
#define NEXTQ(current,start,limit) \
( (current)+1 < (limit) ? (current)+1 : (start) )
typedef struct {
command * start;
command * in;
command * out;
command * limit;
} amb_cq_ptrs;
typedef struct {
spinlock_t lock;
unsigned int pending;
unsigned int high;
unsigned int filled;
unsigned int maximum; // size - 1 (q implementation)
amb_cq_ptrs ptrs;
} amb_cq;
typedef struct {
spinlock_t lock;
unsigned int pending;
unsigned int high;
unsigned int filled;
unsigned int maximum; // size - 1 (q implementation)
struct {
tx_in * start;
tx_in * ptr;
tx_in * limit;
} in;
struct {
tx_out * start;
tx_out * ptr;
tx_out * limit;
} out;
} amb_txq;
typedef struct {
spinlock_t lock;
unsigned int pending;
unsigned int low;
unsigned int emptied;
unsigned int maximum; // size - 1 (q implementation)
struct {
rx_in * start;
rx_in * ptr;
rx_in * limit;
} in;
struct {
rx_out * start;
rx_out * ptr;
rx_out * limit;
} out;
unsigned int buffers_wanted;
unsigned int buffer_size;
} amb_rxq;
typedef struct {
unsigned long tx_ok;
struct {
unsigned long ok;
unsigned long error;
unsigned long badcrc;
unsigned long toolong;
unsigned long aborted;
unsigned long unused;
} rx;
} amb_stats;
// a single struct pointed to by atm_vcc->dev_data
typedef struct {
u8 tx_vc_bits:7;
u8 tx_present:1;
} amb_tx_info;
typedef struct {
unsigned char pool;
} amb_rx_info;
typedef struct {
amb_rx_info rx_info;
u16 tx_frame_bits;
unsigned int tx_rate;
unsigned int rx_rate;
} amb_vcc;
struct amb_dev {
u8 irq;
unsigned long flags;
u32 iobase;
u32 * membase;
amb_cq cq;
amb_txq txq;
amb_rxq rxq[NUM_RX_POOLS];
struct mutex vcc_sf;
amb_tx_info txer[NUM_VCS];
struct atm_vcc * rxer[NUM_VCS];
unsigned int tx_avail;
unsigned int rx_avail;
amb_stats stats;
struct atm_dev * atm_dev;
struct pci_dev * pci_dev;
struct timer_list housekeeping;
};
typedef struct amb_dev amb_dev;
#define AMB_DEV(atm_dev) ((amb_dev *) (atm_dev)->dev_data)
#define AMB_VCC(atm_vcc) ((amb_vcc *) (atm_vcc)->dev_data)
/* rate rounding */
typedef enum {
round_up,
round_down,
round_nearest
} rounding;
#endif

492
drivers/atm/atmtcp.c Normal file
View file

@ -0,0 +1,492 @@
/* drivers/atm/atmtcp.c - ATM over TCP "device" driver */
/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/atmdev.h>
#include <linux/atm_tcp.h>
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/atomic.h>
extern int atm_init_aal5(struct atm_vcc *vcc); /* "raw" AAL5 transport */
#define PRIV(dev) ((struct atmtcp_dev_data *) ((dev)->dev_data))
struct atmtcp_dev_data {
struct atm_vcc *vcc; /* control VCC; NULL if detached */
int persist; /* non-zero if persistent */
};
#define DEV_LABEL "atmtcp"
#define MAX_VPI_BITS 8 /* simplifies life */
#define MAX_VCI_BITS 16
/*
* Hairy code ahead: the control VCC may be closed while we're still
* waiting for an answer, so we need to re-validate out_vcc every once
* in a while.
*/
static int atmtcp_send_control(struct atm_vcc *vcc,int type,
const struct atmtcp_control *msg,int flag)
{
DECLARE_WAITQUEUE(wait,current);
struct atm_vcc *out_vcc;
struct sk_buff *skb;
struct atmtcp_control *new_msg;
int old_test;
int error = 0;
out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
if (!out_vcc) return -EUNATCH;
skb = alloc_skb(sizeof(*msg),GFP_KERNEL);
if (!skb) return -ENOMEM;
mb();
out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
if (!out_vcc) {
dev_kfree_skb(skb);
return -EUNATCH;
}
atm_force_charge(out_vcc,skb->truesize);
new_msg = (struct atmtcp_control *) skb_put(skb,sizeof(*new_msg));
*new_msg = *msg;
new_msg->hdr.length = ATMTCP_HDR_MAGIC;
new_msg->type = type;
memset(&new_msg->vcc,0,sizeof(atm_kptr_t));
*(struct atm_vcc **) &new_msg->vcc = vcc;
old_test = test_bit(flag,&vcc->flags);
out_vcc->push(out_vcc,skb);
add_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
while (test_bit(flag,&vcc->flags) == old_test) {
mb();
out_vcc = PRIV(vcc->dev) ? PRIV(vcc->dev)->vcc : NULL;
if (!out_vcc) {
error = -EUNATCH;
break;
}
set_current_state(TASK_UNINTERRUPTIBLE);
schedule();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(sk_sleep(sk_atm(vcc)), &wait);
return error;
}
static int atmtcp_recv_control(const struct atmtcp_control *msg)
{
struct atm_vcc *vcc = *(struct atm_vcc **) &msg->vcc;
vcc->vpi = msg->addr.sap_addr.vpi;
vcc->vci = msg->addr.sap_addr.vci;
vcc->qos = msg->qos;
sk_atm(vcc)->sk_err = -msg->result;
switch (msg->type) {
case ATMTCP_CTRL_OPEN:
change_bit(ATM_VF_READY,&vcc->flags);
break;
case ATMTCP_CTRL_CLOSE:
change_bit(ATM_VF_ADDR,&vcc->flags);
break;
default:
printk(KERN_ERR "atmtcp_recv_control: unknown type %d\n",
msg->type);
return -EINVAL;
}
wake_up(sk_sleep(sk_atm(vcc)));
return 0;
}
static void atmtcp_v_dev_close(struct atm_dev *dev)
{
/* Nothing.... Isn't this simple :-) -- REW */
}
static int atmtcp_v_open(struct atm_vcc *vcc)
{
struct atmtcp_control msg;
int error;
short vpi = vcc->vpi;
int vci = vcc->vci;
memset(&msg,0,sizeof(msg));
msg.addr.sap_family = AF_ATMPVC;
msg.hdr.vpi = htons(vpi);
msg.addr.sap_addr.vpi = vpi;
msg.hdr.vci = htons(vci);
msg.addr.sap_addr.vci = vci;
if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC) return 0;
msg.type = ATMTCP_CTRL_OPEN;
msg.qos = vcc->qos;
set_bit(ATM_VF_ADDR,&vcc->flags);
clear_bit(ATM_VF_READY,&vcc->flags); /* just in case ... */
error = atmtcp_send_control(vcc,ATMTCP_CTRL_OPEN,&msg,ATM_VF_READY);
if (error) return error;
return -sk_atm(vcc)->sk_err;
}
static void atmtcp_v_close(struct atm_vcc *vcc)
{
struct atmtcp_control msg;
memset(&msg,0,sizeof(msg));
msg.addr.sap_family = AF_ATMPVC;
msg.addr.sap_addr.vpi = vcc->vpi;
msg.addr.sap_addr.vci = vcc->vci;
clear_bit(ATM_VF_READY,&vcc->flags);
(void) atmtcp_send_control(vcc,ATMTCP_CTRL_CLOSE,&msg,ATM_VF_ADDR);
}
static int atmtcp_v_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
struct atm_cirange ci;
struct atm_vcc *vcc;
struct sock *s;
int i;
if (cmd != ATM_SETCIRANGE) return -ENOIOCTLCMD;
if (copy_from_user(&ci, arg,sizeof(ci))) return -EFAULT;
if (ci.vpi_bits == ATM_CI_MAX) ci.vpi_bits = MAX_VPI_BITS;
if (ci.vci_bits == ATM_CI_MAX) ci.vci_bits = MAX_VCI_BITS;
if (ci.vpi_bits > MAX_VPI_BITS || ci.vpi_bits < 0 ||
ci.vci_bits > MAX_VCI_BITS || ci.vci_bits < 0) return -EINVAL;
read_lock(&vcc_sklist_lock);
for(i = 0; i < VCC_HTABLE_SIZE; ++i) {
struct hlist_head *head = &vcc_hash[i];
sk_for_each(s, head) {
vcc = atm_sk(s);
if (vcc->dev != dev)
continue;
if ((vcc->vpi >> ci.vpi_bits) ||
(vcc->vci >> ci.vci_bits)) {
read_unlock(&vcc_sklist_lock);
return -EBUSY;
}
}
}
read_unlock(&vcc_sklist_lock);
dev->ci_range = ci;
return 0;
}
static int atmtcp_v_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
struct atmtcp_dev_data *dev_data;
struct atm_vcc *out_vcc=NULL; /* Initializer quietens GCC warning */
struct sk_buff *new_skb;
struct atmtcp_hdr *hdr;
int size;
if (vcc->qos.txtp.traffic_class == ATM_NONE) {
if (vcc->pop) vcc->pop(vcc,skb);
else dev_kfree_skb(skb);
return -EINVAL;
}
dev_data = PRIV(vcc->dev);
if (dev_data) out_vcc = dev_data->vcc;
if (!dev_data || !out_vcc) {
if (vcc->pop) vcc->pop(vcc,skb);
else dev_kfree_skb(skb);
if (dev_data) return 0;
atomic_inc(&vcc->stats->tx_err);
return -ENOLINK;
}
size = skb->len+sizeof(struct atmtcp_hdr);
new_skb = atm_alloc_charge(out_vcc,size,GFP_ATOMIC);
if (!new_skb) {
if (vcc->pop) vcc->pop(vcc,skb);
else dev_kfree_skb(skb);
atomic_inc(&vcc->stats->tx_err);
return -ENOBUFS;
}
hdr = (void *) skb_put(new_skb,sizeof(struct atmtcp_hdr));
hdr->vpi = htons(vcc->vpi);
hdr->vci = htons(vcc->vci);
hdr->length = htonl(skb->len);
skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
if (vcc->pop) vcc->pop(vcc,skb);
else dev_kfree_skb(skb);
out_vcc->push(out_vcc,new_skb);
atomic_inc(&vcc->stats->tx);
atomic_inc(&out_vcc->stats->rx);
return 0;
}
static int atmtcp_v_proc(struct atm_dev *dev,loff_t *pos,char *page)
{
struct atmtcp_dev_data *dev_data = PRIV(dev);
if (*pos) return 0;
if (!dev_data->persist) return sprintf(page,"ephemeral\n");
return sprintf(page,"persistent, %sconnected\n",
dev_data->vcc ? "" : "dis");
}
static void atmtcp_c_close(struct atm_vcc *vcc)
{
struct atm_dev *atmtcp_dev;
struct atmtcp_dev_data *dev_data;
atmtcp_dev = (struct atm_dev *) vcc->dev_data;
dev_data = PRIV(atmtcp_dev);
dev_data->vcc = NULL;
if (dev_data->persist) return;
atmtcp_dev->dev_data = NULL;
kfree(dev_data);
atm_dev_deregister(atmtcp_dev);
vcc->dev_data = NULL;
module_put(THIS_MODULE);
}
static struct atm_vcc *find_vcc(struct atm_dev *dev, short vpi, int vci)
{
struct hlist_head *head;
struct atm_vcc *vcc;
struct sock *s;
head = &vcc_hash[vci & (VCC_HTABLE_SIZE -1)];
sk_for_each(s, head) {
vcc = atm_sk(s);
if (vcc->dev == dev &&
vcc->vci == vci && vcc->vpi == vpi &&
vcc->qos.rxtp.traffic_class != ATM_NONE) {
return vcc;
}
}
return NULL;
}
static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
{
struct atm_dev *dev;
struct atmtcp_hdr *hdr;
struct atm_vcc *out_vcc;
struct sk_buff *new_skb;
int result = 0;
if (!skb->len) return 0;
dev = vcc->dev_data;
hdr = (struct atmtcp_hdr *) skb->data;
if (hdr->length == ATMTCP_HDR_MAGIC) {
result = atmtcp_recv_control(
(struct atmtcp_control *) skb->data);
goto done;
}
read_lock(&vcc_sklist_lock);
out_vcc = find_vcc(dev, ntohs(hdr->vpi), ntohs(hdr->vci));
read_unlock(&vcc_sklist_lock);
if (!out_vcc) {
result = -EUNATCH;
atomic_inc(&vcc->stats->tx_err);
goto done;
}
skb_pull(skb,sizeof(struct atmtcp_hdr));
new_skb = atm_alloc_charge(out_vcc,skb->len,GFP_KERNEL);
if (!new_skb) {
result = -ENOBUFS;
goto done;
}
__net_timestamp(new_skb);
skb_copy_from_linear_data(skb, skb_put(new_skb, skb->len), skb->len);
out_vcc->push(out_vcc,new_skb);
atomic_inc(&vcc->stats->tx);
atomic_inc(&out_vcc->stats->rx);
done:
if (vcc->pop) vcc->pop(vcc,skb);
else dev_kfree_skb(skb);
return result;
}
/*
* Device operations for the virtual ATM devices created by ATMTCP.
*/
static struct atmdev_ops atmtcp_v_dev_ops = {
.dev_close = atmtcp_v_dev_close,
.open = atmtcp_v_open,
.close = atmtcp_v_close,
.ioctl = atmtcp_v_ioctl,
.send = atmtcp_v_send,
.proc_read = atmtcp_v_proc,
.owner = THIS_MODULE
};
/*
* Device operations for the ATMTCP control device.
*/
static struct atmdev_ops atmtcp_c_dev_ops = {
.close = atmtcp_c_close,
.send = atmtcp_c_send
};
static struct atm_dev atmtcp_control_dev = {
.ops = &atmtcp_c_dev_ops,
.type = "atmtcp",
.number = 999,
.lock = __SPIN_LOCK_UNLOCKED(atmtcp_control_dev.lock)
};
static int atmtcp_create(int itf,int persist,struct atm_dev **result)
{
struct atmtcp_dev_data *dev_data;
struct atm_dev *dev;
dev_data = kmalloc(sizeof(*dev_data),GFP_KERNEL);
if (!dev_data)
return -ENOMEM;
dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL);
if (!dev) {
kfree(dev_data);
return itf == -1 ? -ENOMEM : -EBUSY;
}
dev->ci_range.vpi_bits = MAX_VPI_BITS;
dev->ci_range.vci_bits = MAX_VCI_BITS;
dev->dev_data = dev_data;
PRIV(dev)->vcc = NULL;
PRIV(dev)->persist = persist;
if (result) *result = dev;
return 0;
}
static int atmtcp_attach(struct atm_vcc *vcc,int itf)
{
struct atm_dev *dev;
dev = NULL;
if (itf != -1) dev = atm_dev_lookup(itf);
if (dev) {
if (dev->ops != &atmtcp_v_dev_ops) {
atm_dev_put(dev);
return -EMEDIUMTYPE;
}
if (PRIV(dev)->vcc) {
atm_dev_put(dev);
return -EBUSY;
}
}
else {
int error;
error = atmtcp_create(itf,0,&dev);
if (error) return error;
}
PRIV(dev)->vcc = vcc;
vcc->dev = &atmtcp_control_dev;
vcc_insert_socket(sk_atm(vcc));
set_bit(ATM_VF_META,&vcc->flags);
set_bit(ATM_VF_READY,&vcc->flags);
vcc->dev_data = dev;
(void) atm_init_aal5(vcc); /* @@@ losing AAL in transit ... */
vcc->stats = &atmtcp_control_dev.stats.aal5;
return dev->number;
}
static int atmtcp_create_persistent(int itf)
{
return atmtcp_create(itf,1,NULL);
}
static int atmtcp_remove_persistent(int itf)
{
struct atm_dev *dev;
struct atmtcp_dev_data *dev_data;
dev = atm_dev_lookup(itf);
if (!dev) return -ENODEV;
if (dev->ops != &atmtcp_v_dev_ops) {
atm_dev_put(dev);
return -EMEDIUMTYPE;
}
dev_data = PRIV(dev);
if (!dev_data->persist) return 0;
dev_data->persist = 0;
if (PRIV(dev)->vcc) return 0;
kfree(dev_data);
atm_dev_put(dev);
atm_dev_deregister(dev);
return 0;
}
static int atmtcp_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
int err = 0;
struct atm_vcc *vcc = ATM_SD(sock);
if (cmd != SIOCSIFATMTCP && cmd != ATMTCP_CREATE && cmd != ATMTCP_REMOVE)
return -ENOIOCTLCMD;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
switch (cmd) {
case SIOCSIFATMTCP:
err = atmtcp_attach(vcc, (int) arg);
if (err >= 0) {
sock->state = SS_CONNECTED;
__module_get(THIS_MODULE);
}
break;
case ATMTCP_CREATE:
err = atmtcp_create_persistent((int) arg);
break;
case ATMTCP_REMOVE:
err = atmtcp_remove_persistent((int) arg);
break;
}
return err;
}
static struct atm_ioctl atmtcp_ioctl_ops = {
.owner = THIS_MODULE,
.ioctl = atmtcp_ioctl,
};
static __init int atmtcp_init(void)
{
register_atm_ioctl(&atmtcp_ioctl_ops);
return 0;
}
static void __exit atmtcp_exit(void)
{
deregister_atm_ioctl(&atmtcp_ioctl_ops);
}
MODULE_LICENSE("GPL");
module_init(atmtcp_init);
module_exit(atmtcp_exit);

2332
drivers/atm/eni.c Normal file

File diff suppressed because it is too large Load diff

135
drivers/atm/eni.h Normal file
View file

@ -0,0 +1,135 @@
/* drivers/atm/eni.h - Efficient Networks ENI155P device driver declarations */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
#ifndef DRIVER_ATM_ENI_H
#define DRIVER_ATM_ENI_H
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/interrupt.h>
#include <linux/sonet.h>
#include <linux/skbuff.h>
#include <linux/time.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include "midway.h"
#define DEV_LABEL "eni"
#define UBR_BUFFER (128*1024) /* UBR buffer size */
#define RX_DMA_BUF 8 /* burst and skip a few things */
#define TX_DMA_BUF 100 /* should be enough for 64 kB */
#define DEFAULT_RX_MULT 300 /* max_sdu*3 */
#define DEFAULT_TX_MULT 300 /* max_sdu*3 */
#define ENI_ZEROES_SIZE 4 /* need that many DMA-able zero bytes */
struct eni_free {
void __iomem *start; /* counting in bytes */
int order;
};
struct eni_tx {
void __iomem *send; /* base, 0 if unused */
int prescaler; /* shaping prescaler */
int resolution; /* shaping divider */
unsigned long tx_pos; /* current TX write position */
unsigned long words; /* size of TX queue */
int index; /* TX channel number */
int reserved; /* reserved peak cell rate */
int shaping; /* shaped peak cell rate */
struct sk_buff_head backlog; /* queue of waiting TX buffers */
};
struct eni_vcc {
int (*rx)(struct atm_vcc *vcc); /* RX function, NULL if none */
void __iomem *recv; /* receive buffer */
unsigned long words; /* its size in words */
unsigned long descr; /* next descriptor (RX) */
unsigned long rx_pos; /* current RX descriptor pos */
struct eni_tx *tx; /* TXer, NULL if none */
int rxing; /* number of pending PDUs */
int servicing; /* number of waiting VCs (0 or 1) */
int txing; /* number of pending TX bytes */
ktime_t timestamp; /* for RX timing */
struct atm_vcc *next; /* next pending RX */
struct sk_buff *last; /* last PDU being DMAed (used to carry
discard information) */
};
struct eni_dev {
/*-------------------------------- spinlock */
spinlock_t lock; /* sync with interrupt */
struct tasklet_struct task; /* tasklet for interrupt work */
u32 events; /* pending events */
/*-------------------------------- base pointers into Midway address
space */
void __iomem *ioaddr;
void __iomem *phy; /* PHY interface chip registers */
void __iomem *reg; /* register base */
void __iomem *ram; /* RAM base */
void __iomem *vci; /* VCI table */
void __iomem *rx_dma; /* RX DMA queue */
void __iomem *tx_dma; /* TX DMA queue */
void __iomem *service; /* service list */
/*-------------------------------- TX part */
struct eni_tx tx[NR_CHAN]; /* TX channels */
struct eni_tx *ubr; /* UBR channel */
struct sk_buff_head tx_queue; /* PDUs currently being TX DMAed*/
wait_queue_head_t tx_wait; /* for close */
int tx_bw; /* remaining bandwidth */
u32 dma[TX_DMA_BUF*2]; /* DMA request scratch area */
struct eni_zero { /* aligned "magic" zeroes */
u32 *addr;
dma_addr_t dma;
} zero;
int tx_mult; /* buffer size multiplier (percent) */
/*-------------------------------- RX part */
u32 serv_read; /* host service read index */
struct atm_vcc *fast,*last_fast;/* queues of VCCs with pending PDUs */
struct atm_vcc *slow,*last_slow;
struct atm_vcc **rx_map; /* for fast lookups */
struct sk_buff_head rx_queue; /* PDUs currently being RX-DMAed */
wait_queue_head_t rx_wait; /* for close */
int rx_mult; /* buffer size multiplier (percent) */
/*-------------------------------- statistics */
unsigned long lost; /* number of lost cells (RX) */
/*-------------------------------- memory management */
unsigned long base_diff; /* virtual-real base address */
int free_len; /* free list length */
struct eni_free *free_list; /* free list */
int free_list_size; /* maximum size of free list */
/*-------------------------------- ENI links */
struct atm_dev *more; /* other ENI devices */
/*-------------------------------- general information */
int mem; /* RAM on board (in bytes) */
int asic; /* PCI interface type, 0 for FPGA */
unsigned int irq; /* IRQ */
struct pci_dev *pci_dev; /* PCI stuff */
};
#define ENI_DEV(d) ((struct eni_dev *) (d)->dev_data)
#define ENI_VCC(d) ((struct eni_vcc *) (d)->dev_data)
struct eni_skb_prv {
struct atm_skb_data _; /* reserved */
unsigned long pos; /* position of next descriptor */
int size; /* PDU size in reassembly buffer */
dma_addr_t paddr; /* DMA handle */
};
#define ENI_PRV_SIZE(skb) (((struct eni_skb_prv *) (skb)->cb)->size)
#define ENI_PRV_POS(skb) (((struct eni_skb_prv *) (skb)->cb)->pos)
#define ENI_PRV_PADDR(skb) (((struct eni_skb_prv *) (skb)->cb)->paddr)
#endif

2065
drivers/atm/firestream.c Normal file

File diff suppressed because it is too large Load diff

517
drivers/atm/firestream.h Normal file
View file

@ -0,0 +1,517 @@
/* drivers/atm/firestream.h - FireStream 155 (MB86697) and
* FireStream 50 (MB86695) device driver
*/
/* Written & (C) 2000 by R.E.Wolff@BitWizard.nl
* Copied snippets from zatm.c by Werner Almesberger, EPFL LRC/ICA
* and ambassador.c Copyright (C) 1995-1999 Madge Networks Ltd
*/
/*
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The GNU GPL is contained in /usr/doc/copyright/GPL on a Debian
system and in the file COPYING in the Linux kernel source.
*/
/***********************************************************************
* first the defines for the chip. *
***********************************************************************/
/********************* General chip parameters. ************************/
#define FS_NR_FREE_POOLS 8
#define FS_NR_RX_QUEUES 4
/********************* queues and queue access macros ******************/
/* A queue entry. */
struct FS_QENTRY {
u32 cmd;
u32 p0, p1, p2;
};
/* A freepool entry. */
struct FS_BPENTRY {
u32 flags;
u32 next;
u32 bsa;
u32 aal_bufsize;
/* The hardware doesn't look at this, but we need the SKB somewhere... */
struct sk_buff *skb;
struct freepool *fp;
struct fs_dev *dev;
};
#define STATUS_CODE(qe) ((qe->cmd >> 22) & 0x3f)
/* OFFSETS against the base of a QUEUE... */
#define QSA 0x00
#define QEA 0x04
#define QRP 0x08
#define QWP 0x0c
#define QCNF 0x10 /* Only for Release queues! */
/* Not for the transmit pending queue. */
/* OFFSETS against the base of a FREE POOL... */
#define FPCNF 0x00
#define FPSA 0x04
#define FPEA 0x08
#define FPCNT 0x0c
#define FPCTU 0x10
#define Q_SA(b) (b + QSA )
#define Q_EA(b) (b + QEA )
#define Q_RP(b) (b + QRP )
#define Q_WP(b) (b + QWP )
#define Q_CNF(b) (b + QCNF)
#define FP_CNF(b) (b + FPCNF)
#define FP_SA(b) (b + FPSA)
#define FP_EA(b) (b + FPEA)
#define FP_CNT(b) (b + FPCNT)
#define FP_CTU(b) (b + FPCTU)
/* bits in a queue register. */
#define Q_FULL 0x1
#define Q_EMPTY 0x2
#define Q_INCWRAP 0x4
#define Q_ADDR_MASK 0xfffffff0
/* bits in a FreePool config register */
#define RBFP_RBS (0x1 << 16)
#define RBFP_RBSVAL (0x1 << 15)
#define RBFP_CME (0x1 << 12)
#define RBFP_DLP (0x1 << 11)
#define RBFP_BFPWT (0x1 << 0)
/* FireStream commands. */
#define QE_CMD_NULL (0x00 << 22)
#define QE_CMD_REG_RD (0x01 << 22)
#define QE_CMD_REG_RDM (0x02 << 22)
#define QE_CMD_REG_WR (0x03 << 22)
#define QE_CMD_REG_WRM (0x04 << 22)
#define QE_CMD_CONFIG_TX (0x05 << 22)
#define QE_CMD_CONFIG_RX (0x06 << 22)
#define QE_CMD_PRP_RD (0x07 << 22)
#define QE_CMD_PRP_RDM (0x2a << 22)
#define QE_CMD_PRP_WR (0x09 << 22)
#define QE_CMD_PRP_WRM (0x2b << 22)
#define QE_CMD_RX_EN (0x0a << 22)
#define QE_CMD_RX_PURGE (0x0b << 22)
#define QE_CMD_RX_PURGE_INH (0x0c << 22)
#define QE_CMD_TX_EN (0x0d << 22)
#define QE_CMD_TX_PURGE (0x0e << 22)
#define QE_CMD_TX_PURGE_INH (0x0f << 22)
#define QE_CMD_RST_CG (0x10 << 22)
#define QE_CMD_SET_CG (0x11 << 22)
#define QE_CMD_RST_CLP (0x12 << 22)
#define QE_CMD_SET_CLP (0x13 << 22)
#define QE_CMD_OVERRIDE (0x14 << 22)
#define QE_CMD_ADD_BFP (0x15 << 22)
#define QE_CMD_DUMP_TX (0x16 << 22)
#define QE_CMD_DUMP_RX (0x17 << 22)
#define QE_CMD_LRAM_RD (0x18 << 22)
#define QE_CMD_LRAM_RDM (0x28 << 22)
#define QE_CMD_LRAM_WR (0x19 << 22)
#define QE_CMD_LRAM_WRM (0x29 << 22)
#define QE_CMD_LRAM_BSET (0x1a << 22)
#define QE_CMD_LRAM_BCLR (0x1b << 22)
#define QE_CMD_CONFIG_SEGM (0x1c << 22)
#define QE_CMD_READ_SEGM (0x1d << 22)
#define QE_CMD_CONFIG_ROUT (0x1e << 22)
#define QE_CMD_READ_ROUT (0x1f << 22)
#define QE_CMD_CONFIG_TM (0x20 << 22)
#define QE_CMD_READ_TM (0x21 << 22)
#define QE_CMD_CONFIG_TXBM (0x22 << 22)
#define QE_CMD_READ_TXBM (0x23 << 22)
#define QE_CMD_CONFIG_RXBM (0x24 << 22)
#define QE_CMD_READ_RXBM (0x25 << 22)
#define QE_CMD_CONFIG_REAS (0x26 << 22)
#define QE_CMD_READ_REAS (0x27 << 22)
#define QE_TRANSMIT_DE (0x0 << 30)
#define QE_CMD_LINKED (0x1 << 30)
#define QE_CMD_IMM (0x2 << 30)
#define QE_CMD_IMM_INQ (0x3 << 30)
#define TD_EPI (0x1 << 27)
#define TD_COMMAND (0x1 << 28)
#define TD_DATA (0x0 << 29)
#define TD_RM_CELL (0x1 << 29)
#define TD_OAM_CELL (0x2 << 29)
#define TD_OAM_CELL_SEGMENT (0x3 << 29)
#define TD_BPI (0x1 << 20)
#define FP_FLAGS_EPI (0x1 << 27)
#define TX_PQ(i) (0x00 + (i) * 0x10)
#define TXB_RQ (0x20)
#define ST_Q (0x48)
#define RXB_FP(i) (0x90 + (i) * 0x14)
#define RXB_RQ(i) (0x134 + (i) * 0x14)
#define TXQ_HP 0
#define TXQ_LP 1
/* Phew. You don't want to know how many revisions these simple queue
* address macros went through before I got them nice and compact as
* they are now. -- REW
*/
/* And now for something completely different:
* The rest of the registers... */
#define CMDR0 0x34
#define CMDR1 0x38
#define CMDR2 0x3c
#define CMDR3 0x40
#define SARMODE0 0x5c
#define SARMODE0_TXVCS_0 (0x0 << 0)
#define SARMODE0_TXVCS_1k (0x1 << 0)
#define SARMODE0_TXVCS_2k (0x2 << 0)
#define SARMODE0_TXVCS_4k (0x3 << 0)
#define SARMODE0_TXVCS_8k (0x4 << 0)
#define SARMODE0_TXVCS_16k (0x5 << 0)
#define SARMODE0_TXVCS_32k (0x6 << 0)
#define SARMODE0_TXVCS_64k (0x7 << 0)
#define SARMODE0_TXVCS_32 (0x8 << 0)
#define SARMODE0_ABRVCS_0 (0x0 << 4)
#define SARMODE0_ABRVCS_512 (0x1 << 4)
#define SARMODE0_ABRVCS_1k (0x2 << 4)
#define SARMODE0_ABRVCS_2k (0x3 << 4)
#define SARMODE0_ABRVCS_4k (0x4 << 4)
#define SARMODE0_ABRVCS_8k (0x5 << 4)
#define SARMODE0_ABRVCS_16k (0x6 << 4)
#define SARMODE0_ABRVCS_32k (0x7 << 4)
#define SARMODE0_ABRVCS_32 (0x9 << 4) /* The others are "8", this one really has to
be 9. Tell me you don't believe me. -- REW */
#define SARMODE0_RXVCS_0 (0x0 << 8)
#define SARMODE0_RXVCS_1k (0x1 << 8)
#define SARMODE0_RXVCS_2k (0x2 << 8)
#define SARMODE0_RXVCS_4k (0x3 << 8)
#define SARMODE0_RXVCS_8k (0x4 << 8)
#define SARMODE0_RXVCS_16k (0x5 << 8)
#define SARMODE0_RXVCS_32k (0x6 << 8)
#define SARMODE0_RXVCS_64k (0x7 << 8)
#define SARMODE0_RXVCS_32 (0x8 << 8)
#define SARMODE0_CALSUP_1 (0x0 << 12)
#define SARMODE0_CALSUP_2 (0x1 << 12)
#define SARMODE0_CALSUP_3 (0x2 << 12)
#define SARMODE0_CALSUP_4 (0x3 << 12)
#define SARMODE0_PRPWT_FS50_0 (0x0 << 14)
#define SARMODE0_PRPWT_FS50_2 (0x1 << 14)
#define SARMODE0_PRPWT_FS50_5 (0x2 << 14)
#define SARMODE0_PRPWT_FS50_11 (0x3 << 14)
#define SARMODE0_PRPWT_FS155_0 (0x0 << 14)
#define SARMODE0_PRPWT_FS155_1 (0x1 << 14)
#define SARMODE0_PRPWT_FS155_2 (0x2 << 14)
#define SARMODE0_PRPWT_FS155_3 (0x3 << 14)
#define SARMODE0_SRTS0 (0x1 << 23)
#define SARMODE0_SRTS1 (0x1 << 24)
#define SARMODE0_RUN (0x1 << 25)
#define SARMODE0_UNLOCK (0x1 << 26)
#define SARMODE0_CWRE (0x1 << 27)
#define SARMODE0_INTMODE_READCLEAR (0x0 << 28)
#define SARMODE0_INTMODE_READNOCLEAR (0x1 << 28)
#define SARMODE0_INTMODE_READNOCLEARINHIBIT (0x2 << 28)
#define SARMODE0_INTMODE_READCLEARINHIBIT (0x3 << 28) /* Tell me you don't believe me. */
#define SARMODE0_GINT (0x1 << 30)
#define SARMODE0_SHADEN (0x1 << 31)
#define SARMODE1 0x60
#define SARMODE1_TRTL_SHIFT 0 /* Program to 0 */
#define SARMODE1_RRTL_SHIFT 4 /* Program to 0 */
#define SARMODE1_TAGM (0x1 << 8) /* Program to 0 */
#define SARMODE1_HECM0 (0x1 << 9)
#define SARMODE1_HECM1 (0x1 << 10)
#define SARMODE1_HECM2 (0x1 << 11)
#define SARMODE1_GFCE (0x1 << 14)
#define SARMODE1_GFCR (0x1 << 15)
#define SARMODE1_PMS (0x1 << 18)
#define SARMODE1_GPRI (0x1 << 19)
#define SARMODE1_GPAS (0x1 << 20)
#define SARMODE1_GVAS (0x1 << 21)
#define SARMODE1_GNAM (0x1 << 22)
#define SARMODE1_GPLEN (0x1 << 23)
#define SARMODE1_DUMPE (0x1 << 24)
#define SARMODE1_OAMCRC (0x1 << 25)
#define SARMODE1_DCOAM (0x1 << 26)
#define SARMODE1_DCRM (0x1 << 27)
#define SARMODE1_TSTLP (0x1 << 28)
#define SARMODE1_DEFHEC (0x1 << 29)
#define ISR 0x64
#define IUSR 0x68
#define IMR 0x6c
#define ISR_LPCO (0x1 << 0)
#define ISR_DPCO (0x1 << 1)
#define ISR_RBRQ0_W (0x1 << 2)
#define ISR_RBRQ1_W (0x1 << 3)
#define ISR_RBRQ2_W (0x1 << 4)
#define ISR_RBRQ3_W (0x1 << 5)
#define ISR_RBRQ0_NF (0x1 << 6)
#define ISR_RBRQ1_NF (0x1 << 7)
#define ISR_RBRQ2_NF (0x1 << 8)
#define ISR_RBRQ3_NF (0x1 << 9)
#define ISR_BFP_SC (0x1 << 10)
#define ISR_INIT (0x1 << 11)
#define ISR_INIT_ERR (0x1 << 12) /* Documented as "reserved" */
#define ISR_USCEO (0x1 << 13)
#define ISR_UPEC0 (0x1 << 14)
#define ISR_VPFCO (0x1 << 15)
#define ISR_CRCCO (0x1 << 16)
#define ISR_HECO (0x1 << 17)
#define ISR_TBRQ_W (0x1 << 18)
#define ISR_TBRQ_NF (0x1 << 19)
#define ISR_CTPQ_E (0x1 << 20)
#define ISR_GFC_C0 (0x1 << 21)
#define ISR_PCI_FTL (0x1 << 22)
#define ISR_CSQ_W (0x1 << 23)
#define ISR_CSQ_NF (0x1 << 24)
#define ISR_EXT_INT (0x1 << 25)
#define ISR_RXDMA_S (0x1 << 26)
#define TMCONF 0x78
/* Bits? */
#define CALPRESCALE 0x7c
/* Bits? */
#define CELLOSCONF 0x84
#define CELLOSCONF_COTS (0x1 << 28)
#define CELLOSCONF_CEN (0x1 << 27)
#define CELLOSCONF_SC8 (0x3 << 24)
#define CELLOSCONF_SC4 (0x2 << 24)
#define CELLOSCONF_SC2 (0x1 << 24)
#define CELLOSCONF_SC1 (0x0 << 24)
#define CELLOSCONF_COBS (0x1 << 16)
#define CELLOSCONF_COPK (0x1 << 8)
#define CELLOSCONF_COST (0x1 << 0)
/* Bits? */
#define RAS0 0x1bc
#define RAS0_DCD_XHLT (0x1 << 31)
#define RAS0_VPSEL (0x1 << 16)
#define RAS0_VCSEL (0x1 << 0)
#define RAS1 0x1c0
#define RAS1_UTREG (0x1 << 5)
#define DMAMR 0x1cc
#define DMAMR_TX_MODE_FULL (0x0 << 0)
#define DMAMR_TX_MODE_PART (0x1 << 0)
#define DMAMR_TX_MODE_NONE (0x2 << 0) /* And 3 */
#define RAS2 0x280
#define RAS2_NNI (0x1 << 0)
#define RAS2_USEL (0x1 << 1)
#define RAS2_UBS (0x1 << 2)
struct fs_transmit_config {
u32 flags;
u32 atm_hdr;
u32 TMC[4];
u32 spec;
u32 rtag[3];
};
#define TC_FLAGS_AAL5 (0x0 << 29)
#define TC_FLAGS_TRANSPARENT_PAYLOAD (0x1 << 29)
#define TC_FLAGS_TRANSPARENT_CELL (0x2 << 29)
#define TC_FLAGS_STREAMING (0x1 << 28)
#define TC_FLAGS_PACKET (0x0)
#define TC_FLAGS_TYPE_ABR (0x0 << 22)
#define TC_FLAGS_TYPE_CBR (0x1 << 22)
#define TC_FLAGS_TYPE_VBR (0x2 << 22)
#define TC_FLAGS_TYPE_UBR (0x3 << 22)
#define TC_FLAGS_CAL0 (0x0 << 20)
#define TC_FLAGS_CAL1 (0x1 << 20)
#define TC_FLAGS_CAL2 (0x2 << 20)
#define TC_FLAGS_CAL3 (0x3 << 20)
#define RC_FLAGS_NAM (0x1 << 13)
#define RC_FLAGS_RXBM_PSB (0x0 << 14)
#define RC_FLAGS_RXBM_CIF (0x1 << 14)
#define RC_FLAGS_RXBM_PMB (0x2 << 14)
#define RC_FLAGS_RXBM_STR (0x4 << 14)
#define RC_FLAGS_RXBM_SAF (0x6 << 14)
#define RC_FLAGS_RXBM_POS (0x6 << 14)
#define RC_FLAGS_BFPS (0x1 << 17)
#define RC_FLAGS_BFPS_BFP (0x1 << 17)
#define RC_FLAGS_BFPS_BFP0 (0x0 << 17)
#define RC_FLAGS_BFPS_BFP1 (0x1 << 17)
#define RC_FLAGS_BFPS_BFP2 (0x2 << 17)
#define RC_FLAGS_BFPS_BFP3 (0x3 << 17)
#define RC_FLAGS_BFPS_BFP4 (0x4 << 17)
#define RC_FLAGS_BFPS_BFP5 (0x5 << 17)
#define RC_FLAGS_BFPS_BFP6 (0x6 << 17)
#define RC_FLAGS_BFPS_BFP7 (0x7 << 17)
#define RC_FLAGS_BFPS_BFP01 (0x8 << 17)
#define RC_FLAGS_BFPS_BFP23 (0x9 << 17)
#define RC_FLAGS_BFPS_BFP45 (0xa << 17)
#define RC_FLAGS_BFPS_BFP67 (0xb << 17)
#define RC_FLAGS_BFPS_BFP07 (0xc << 17)
#define RC_FLAGS_BFPS_BFP27 (0xd << 17)
#define RC_FLAGS_BFPS_BFP47 (0xe << 17)
#define RC_FLAGS_BFPP (0x1 << 21)
#define RC_FLAGS_TEVC (0x1 << 22)
#define RC_FLAGS_TEP (0x1 << 23)
#define RC_FLAGS_AAL5 (0x0 << 24)
#define RC_FLAGS_TRANSP (0x1 << 24)
#define RC_FLAGS_TRANSC (0x2 << 24)
#define RC_FLAGS_ML (0x1 << 27)
#define RC_FLAGS_TRBRM (0x1 << 28)
#define RC_FLAGS_PRI (0x1 << 29)
#define RC_FLAGS_HOAM (0x1 << 30)
#define RC_FLAGS_CRC10 (0x1 << 31)
#define RAC 0x1c8
#define RAM 0x1c4
/************************************************************************
* Then the datastructures that the DRIVER uses. *
************************************************************************/
#define TXQ_NENTRIES 32
#define RXRQ_NENTRIES 1024
struct fs_vcc {
int channo;
wait_queue_head_t close_wait;
struct sk_buff *last_skb;
};
struct queue {
struct FS_QENTRY *sa, *ea;
int offset;
};
struct freepool {
int offset;
int bufsize;
int nr_buffers;
int n;
};
struct fs_dev {
struct fs_dev *next; /* other FS devices */
int flags;
unsigned char irq; /* IRQ */
struct pci_dev *pci_dev; /* PCI stuff */
struct atm_dev *atm_dev;
struct timer_list timer;
unsigned long hw_base; /* mem base address */
void __iomem *base; /* Mapping of base address */
int channo;
unsigned long channel_mask;
struct queue hp_txq, lp_txq, tx_relq, st_q;
struct freepool rx_fp[FS_NR_FREE_POOLS];
struct queue rx_rq[FS_NR_RX_QUEUES];
int nchannels;
struct atm_vcc **atm_vccs;
void *tx_inuse;
int ntxpckts;
};
/* Number of channesl that the FS50 supports. */
#define FS50_CHANNEL_BITS 5
#define FS50_NR_CHANNELS (1 << FS50_CHANNEL_BITS)
#define FS_DEV(atm_dev) ((struct fs_dev *) (atm_dev)->dev_data)
#define FS_VCC(atm_vcc) ((struct fs_vcc *) (atm_vcc)->dev_data)
#define FS_IS50 0x1
#define FS_IS155 0x2
#define IS_FS50(dev) (dev->flags & FS_IS50)
#define IS_FS155(dev) (dev->flags & FS_IS155)
/* Within limits this is user-configurable. */
/* Note: Currently the sum (10 -> 1k channels) is hardcoded in the driver. */
#define FS155_VPI_BITS 4
#define FS155_VCI_BITS 6
#define FS155_CHANNEL_BITS (FS155_VPI_BITS + FS155_VCI_BITS)
#define FS155_NR_CHANNELS (1 << FS155_CHANNEL_BITS)

3177
drivers/atm/fore200e.c Normal file

File diff suppressed because it is too large Load diff

979
drivers/atm/fore200e.h Normal file
View file

@ -0,0 +1,979 @@
#ifndef _FORE200E_H
#define _FORE200E_H
#ifdef __KERNEL__
/* rx buffer sizes */
#define SMALL_BUFFER_SIZE 384 /* size of small buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
#define LARGE_BUFFER_SIZE 4032 /* size of large buffers (multiple of 48 (PCA) and 64 (SBA) bytes) */
#define RBD_BLK_SIZE 32 /* nbr of supplied rx buffers per rbd */
#define MAX_PDU_SIZE 65535 /* maximum PDU size supported by AALs */
#define BUFFER_S1_SIZE SMALL_BUFFER_SIZE /* size of small buffers, scheme 1 */
#define BUFFER_L1_SIZE LARGE_BUFFER_SIZE /* size of large buffers, scheme 1 */
#define BUFFER_S2_SIZE SMALL_BUFFER_SIZE /* size of small buffers, scheme 2 */
#define BUFFER_L2_SIZE LARGE_BUFFER_SIZE /* size of large buffers, scheme 2 */
#define BUFFER_S1_NBR (RBD_BLK_SIZE * 6)
#define BUFFER_L1_NBR (RBD_BLK_SIZE * 4)
#define BUFFER_S2_NBR (RBD_BLK_SIZE * 6)
#define BUFFER_L2_NBR (RBD_BLK_SIZE * 4)
#define QUEUE_SIZE_CMD 16 /* command queue capacity */
#define QUEUE_SIZE_RX 64 /* receive queue capacity */
#define QUEUE_SIZE_TX 256 /* transmit queue capacity */
#define QUEUE_SIZE_BS 32 /* buffer supply queue capacity */
#define FORE200E_VPI_BITS 0
#define FORE200E_VCI_BITS 10
#define NBR_CONNECT (1 << (FORE200E_VPI_BITS + FORE200E_VCI_BITS)) /* number of connections */
#define TSD_FIXED 2
#define TSD_EXTENSION 0
#define TSD_NBR (TSD_FIXED + TSD_EXTENSION)
/* the cp starts putting a received PDU into one *small* buffer,
then it uses a number of *large* buffers for the trailing data.
we compute here the total number of receive segment descriptors
required to hold the largest possible PDU */
#define RSD_REQUIRED (((MAX_PDU_SIZE - SMALL_BUFFER_SIZE + LARGE_BUFFER_SIZE) / LARGE_BUFFER_SIZE) + 1)
#define RSD_FIXED 3
/* RSD_REQUIRED receive segment descriptors are enough to describe a max-sized PDU,
but we have to keep the size of the receive PDU descriptor multiple of 32 bytes,
so we add one extra RSD to RSD_EXTENSION
(WARNING: THIS MAY CHANGE IF BUFFER SIZES ARE MODIFIED) */
#define RSD_EXTENSION ((RSD_REQUIRED - RSD_FIXED) + 1)
#define RSD_NBR (RSD_FIXED + RSD_EXTENSION)
#define FORE200E_DEV(d) ((struct fore200e*)((d)->dev_data))
#define FORE200E_VCC(d) ((struct fore200e_vcc*)((d)->dev_data))
/* bitfields endian games */
#if defined(__LITTLE_ENDIAN_BITFIELD)
#define BITFIELD2(b1, b2) b1; b2;
#define BITFIELD3(b1, b2, b3) b1; b2; b3;
#define BITFIELD4(b1, b2, b3, b4) b1; b2; b3; b4;
#define BITFIELD5(b1, b2, b3, b4, b5) b1; b2; b3; b4; b5;
#define BITFIELD6(b1, b2, b3, b4, b5, b6) b1; b2; b3; b4; b5; b6;
#elif defined(__BIG_ENDIAN_BITFIELD)
#define BITFIELD2(b1, b2) b2; b1;
#define BITFIELD3(b1, b2, b3) b3; b2; b1;
#define BITFIELD4(b1, b2, b3, b4) b4; b3; b2; b1;
#define BITFIELD5(b1, b2, b3, b4, b5) b5; b4; b3; b2; b1;
#define BITFIELD6(b1, b2, b3, b4, b5, b6) b6; b5; b4; b3; b2; b1;
#else
#error unknown bitfield endianess
#endif
/* ATM cell header (minus HEC byte) */
typedef struct atm_header {
BITFIELD5(
u32 clp : 1, /* cell loss priority */
u32 plt : 3, /* payload type */
u32 vci : 16, /* virtual channel identifier */
u32 vpi : 8, /* virtual path identifier */
u32 gfc : 4 /* generic flow control */
)
} atm_header_t;
/* ATM adaptation layer id */
typedef enum fore200e_aal {
FORE200E_AAL0 = 0,
FORE200E_AAL34 = 4,
FORE200E_AAL5 = 5,
} fore200e_aal_t;
/* transmit PDU descriptor specification */
typedef struct tpd_spec {
BITFIELD4(
u32 length : 16, /* total PDU length */
u32 nseg : 8, /* number of transmit segments */
enum fore200e_aal aal : 4, /* adaptation layer */
u32 intr : 4 /* interrupt requested */
)
} tpd_spec_t;
/* transmit PDU rate control */
typedef struct tpd_rate
{
BITFIELD2(
u32 idle_cells : 16, /* number of idle cells to insert */
u32 data_cells : 16 /* number of data cells to transmit */
)
} tpd_rate_t;
/* transmit segment descriptor */
typedef struct tsd {
u32 buffer; /* transmit buffer DMA address */
u32 length; /* number of bytes in buffer */
} tsd_t;
/* transmit PDU descriptor */
typedef struct tpd {
struct atm_header atm_header; /* ATM header minus HEC byte */
struct tpd_spec spec; /* tpd specification */
struct tpd_rate rate; /* tpd rate control */
u32 pad; /* reserved */
struct tsd tsd[ TSD_NBR ]; /* transmit segment descriptors */
} tpd_t;
/* receive segment descriptor */
typedef struct rsd {
u32 handle; /* host supplied receive buffer handle */
u32 length; /* number of bytes in buffer */
} rsd_t;
/* receive PDU descriptor */
typedef struct rpd {
struct atm_header atm_header; /* ATM header minus HEC byte */
u32 nseg; /* number of receive segments */
struct rsd rsd[ RSD_NBR ]; /* receive segment descriptors */
} rpd_t;
/* buffer scheme */
typedef enum buffer_scheme {
BUFFER_SCHEME_ONE,
BUFFER_SCHEME_TWO,
BUFFER_SCHEME_NBR /* always last */
} buffer_scheme_t;
/* buffer magnitude */
typedef enum buffer_magn {
BUFFER_MAGN_SMALL,
BUFFER_MAGN_LARGE,
BUFFER_MAGN_NBR /* always last */
} buffer_magn_t;
/* receive buffer descriptor */
typedef struct rbd {
u32 handle; /* host supplied handle */
u32 buffer_haddr; /* host DMA address of host buffer */
} rbd_t;
/* receive buffer descriptor block */
typedef struct rbd_block {
struct rbd rbd[ RBD_BLK_SIZE ]; /* receive buffer descriptor */
} rbd_block_t;
/* tpd DMA address */
typedef struct tpd_haddr {
BITFIELD3(
u32 size : 4, /* tpd size expressed in 32 byte blocks */
u32 pad : 1, /* reserved */
u32 haddr : 27 /* tpd DMA addr aligned on 32 byte boundary */
)
} tpd_haddr_t;
#define TPD_HADDR_SHIFT 5 /* addr aligned on 32 byte boundary */
/* cp resident transmit queue entry */
typedef struct cp_txq_entry {
struct tpd_haddr tpd_haddr; /* host DMA address of tpd */
u32 status_haddr; /* host DMA address of completion status */
} cp_txq_entry_t;
/* cp resident receive queue entry */
typedef struct cp_rxq_entry {
u32 rpd_haddr; /* host DMA address of rpd */
u32 status_haddr; /* host DMA address of completion status */
} cp_rxq_entry_t;
/* cp resident buffer supply queue entry */
typedef struct cp_bsq_entry {
u32 rbd_block_haddr; /* host DMA address of rbd block */
u32 status_haddr; /* host DMA address of completion status */
} cp_bsq_entry_t;
/* completion status */
typedef volatile enum status {
STATUS_PENDING = (1<<0), /* initial status (written by host) */
STATUS_COMPLETE = (1<<1), /* completion status (written by cp) */
STATUS_FREE = (1<<2), /* initial status (written by host) */
STATUS_ERROR = (1<<3) /* completion status (written by cp) */
} status_t;
/* cp operation code */
typedef enum opcode {
OPCODE_INITIALIZE = 1, /* initialize board */
OPCODE_ACTIVATE_VCIN, /* activate incoming VCI */
OPCODE_ACTIVATE_VCOUT, /* activate outgoing VCI */
OPCODE_DEACTIVATE_VCIN, /* deactivate incoming VCI */
OPCODE_DEACTIVATE_VCOUT, /* deactivate incoing VCI */
OPCODE_GET_STATS, /* get board statistics */
OPCODE_SET_OC3, /* set OC-3 registers */
OPCODE_GET_OC3, /* get OC-3 registers */
OPCODE_RESET_STATS, /* reset board statistics */
OPCODE_GET_PROM, /* get expansion PROM data (PCI specific) */
OPCODE_SET_VPI_BITS, /* set x bits of those decoded by the
firmware to be low order bits from
the VPI field of the ATM cell header */
OPCODE_REQUEST_INTR = (1<<7) /* request interrupt */
} opcode_t;
/* virtual path / virtual channel identifiers */
typedef struct vpvc {
BITFIELD3(
u32 vci : 16, /* virtual channel identifier */
u32 vpi : 8, /* virtual path identifier */
u32 pad : 8 /* reserved */
)
} vpvc_t;
/* activate VC command opcode */
typedef struct activate_opcode {
BITFIELD4(
enum opcode opcode : 8, /* cp opcode */
enum fore200e_aal aal : 8, /* adaptation layer */
enum buffer_scheme scheme : 8, /* buffer scheme */
u32 pad : 8 /* reserved */
)
} activate_opcode_t;
/* activate VC command block */
typedef struct activate_block {
struct activate_opcode opcode; /* activate VC command opcode */
struct vpvc vpvc; /* VPI/VCI */
u32 mtu; /* for AAL0 only */
} activate_block_t;
/* deactivate VC command opcode */
typedef struct deactivate_opcode {
BITFIELD2(
enum opcode opcode : 8, /* cp opcode */
u32 pad : 24 /* reserved */
)
} deactivate_opcode_t;
/* deactivate VC command block */
typedef struct deactivate_block {
struct deactivate_opcode opcode; /* deactivate VC command opcode */
struct vpvc vpvc; /* VPI/VCI */
} deactivate_block_t;
/* OC-3 registers */
typedef struct oc3_regs {
u32 reg[ 128 ]; /* see the PMC Sierra PC5346 S/UNI-155-Lite
Saturn User Network Interface documentation
for a description of the OC-3 chip registers */
} oc3_regs_t;
/* set/get OC-3 regs command opcode */
typedef struct oc3_opcode {
BITFIELD4(
enum opcode opcode : 8, /* cp opcode */
u32 reg : 8, /* register index */
u32 value : 8, /* register value */
u32 mask : 8 /* register mask that specifies which
bits of the register value field
are significant */
)
} oc3_opcode_t;
/* set/get OC-3 regs command block */
typedef struct oc3_block {
struct oc3_opcode opcode; /* set/get OC-3 regs command opcode */
u32 regs_haddr; /* host DMA address of OC-3 regs buffer */
} oc3_block_t;
/* physical encoding statistics */
typedef struct stats_phy {
__be32 crc_header_errors; /* cells received with bad header CRC */
__be32 framing_errors; /* cells received with bad framing */
__be32 pad[ 2 ]; /* i960 padding */
} stats_phy_t;
/* OC-3 statistics */
typedef struct stats_oc3 {
__be32 section_bip8_errors; /* section 8 bit interleaved parity */
__be32 path_bip8_errors; /* path 8 bit interleaved parity */
__be32 line_bip24_errors; /* line 24 bit interleaved parity */
__be32 line_febe_errors; /* line far end block errors */
__be32 path_febe_errors; /* path far end block errors */
__be32 corr_hcs_errors; /* correctable header check sequence */
__be32 ucorr_hcs_errors; /* uncorrectable header check sequence */
__be32 pad[ 1 ]; /* i960 padding */
} stats_oc3_t;
/* ATM statistics */
typedef struct stats_atm {
__be32 cells_transmitted; /* cells transmitted */
__be32 cells_received; /* cells received */
__be32 vpi_bad_range; /* cell drops: VPI out of range */
__be32 vpi_no_conn; /* cell drops: no connection for VPI */
__be32 vci_bad_range; /* cell drops: VCI out of range */
__be32 vci_no_conn; /* cell drops: no connection for VCI */
__be32 pad[ 2 ]; /* i960 padding */
} stats_atm_t;
/* AAL0 statistics */
typedef struct stats_aal0 {
__be32 cells_transmitted; /* cells transmitted */
__be32 cells_received; /* cells received */
__be32 cells_dropped; /* cells dropped */
__be32 pad[ 1 ]; /* i960 padding */
} stats_aal0_t;
/* AAL3/4 statistics */
typedef struct stats_aal34 {
__be32 cells_transmitted; /* cells transmitted from segmented PDUs */
__be32 cells_received; /* cells reassembled into PDUs */
__be32 cells_crc_errors; /* payload CRC error count */
__be32 cells_protocol_errors; /* SAR or CS layer protocol errors */
__be32 cells_dropped; /* cells dropped: partial reassembly */
__be32 cspdus_transmitted; /* CS PDUs transmitted */
__be32 cspdus_received; /* CS PDUs received */
__be32 cspdus_protocol_errors; /* CS layer protocol errors */
__be32 cspdus_dropped; /* reassembled PDUs drop'd (in cells) */
__be32 pad[ 3 ]; /* i960 padding */
} stats_aal34_t;
/* AAL5 statistics */
typedef struct stats_aal5 {
__be32 cells_transmitted; /* cells transmitted from segmented SDUs */
__be32 cells_received; /* cells reassembled into SDUs */
__be32 cells_dropped; /* reassembled PDUs dropped (in cells) */
__be32 congestion_experienced; /* CRC error and length wrong */
__be32 cspdus_transmitted; /* CS PDUs transmitted */
__be32 cspdus_received; /* CS PDUs received */
__be32 cspdus_crc_errors; /* CS PDUs CRC errors */
__be32 cspdus_protocol_errors; /* CS layer protocol errors */
__be32 cspdus_dropped; /* reassembled PDUs dropped */
__be32 pad[ 3 ]; /* i960 padding */
} stats_aal5_t;
/* auxiliary statistics */
typedef struct stats_aux {
__be32 small_b1_failed; /* receive BD allocation failures */
__be32 large_b1_failed; /* receive BD allocation failures */
__be32 small_b2_failed; /* receive BD allocation failures */
__be32 large_b2_failed; /* receive BD allocation failures */
__be32 rpd_alloc_failed; /* receive PDU allocation failures */
__be32 receive_carrier; /* no carrier = 0, carrier = 1 */
__be32 pad[ 2 ]; /* i960 padding */
} stats_aux_t;
/* whole statistics buffer */
typedef struct stats {
struct stats_phy phy; /* physical encoding statistics */
struct stats_oc3 oc3; /* OC-3 statistics */
struct stats_atm atm; /* ATM statistics */
struct stats_aal0 aal0; /* AAL0 statistics */
struct stats_aal34 aal34; /* AAL3/4 statistics */
struct stats_aal5 aal5; /* AAL5 statistics */
struct stats_aux aux; /* auxiliary statistics */
} stats_t;
/* get statistics command opcode */
typedef struct stats_opcode {
BITFIELD2(
enum opcode opcode : 8, /* cp opcode */
u32 pad : 24 /* reserved */
)
} stats_opcode_t;
/* get statistics command block */
typedef struct stats_block {
struct stats_opcode opcode; /* get statistics command opcode */
u32 stats_haddr; /* host DMA address of stats buffer */
} stats_block_t;
/* expansion PROM data (PCI specific) */
typedef struct prom_data {
u32 hw_revision; /* hardware revision */
u32 serial_number; /* board serial number */
u8 mac_addr[ 8 ]; /* board MAC address */
} prom_data_t;
/* get expansion PROM data command opcode */
typedef struct prom_opcode {
BITFIELD2(
enum opcode opcode : 8, /* cp opcode */
u32 pad : 24 /* reserved */
)
} prom_opcode_t;
/* get expansion PROM data command block */
typedef struct prom_block {
struct prom_opcode opcode; /* get PROM data command opcode */
u32 prom_haddr; /* host DMA address of PROM buffer */
} prom_block_t;
/* cp command */
typedef union cmd {
enum opcode opcode; /* operation code */
struct activate_block activate_block; /* activate VC */
struct deactivate_block deactivate_block; /* deactivate VC */
struct stats_block stats_block; /* get statistics */
struct prom_block prom_block; /* get expansion PROM data */
struct oc3_block oc3_block; /* get/set OC-3 registers */
u32 pad[ 4 ]; /* i960 padding */
} cmd_t;
/* cp resident command queue */
typedef struct cp_cmdq_entry {
union cmd cmd; /* command */
u32 status_haddr; /* host DMA address of completion status */
u32 pad[ 3 ]; /* i960 padding */
} cp_cmdq_entry_t;
/* host resident transmit queue entry */
typedef struct host_txq_entry {
struct cp_txq_entry __iomem *cp_entry; /* addr of cp resident tx queue entry */
enum status* status; /* addr of host resident status */
struct tpd* tpd; /* addr of transmit PDU descriptor */
u32 tpd_dma; /* DMA address of tpd */
struct sk_buff* skb; /* related skb */
void* data; /* copy of misaligned data */
unsigned long incarn; /* vc_map incarnation when submitted for tx */
struct fore200e_vc_map* vc_map;
} host_txq_entry_t;
/* host resident receive queue entry */
typedef struct host_rxq_entry {
struct cp_rxq_entry __iomem *cp_entry; /* addr of cp resident rx queue entry */
enum status* status; /* addr of host resident status */
struct rpd* rpd; /* addr of receive PDU descriptor */
u32 rpd_dma; /* DMA address of rpd */
} host_rxq_entry_t;
/* host resident buffer supply queue entry */
typedef struct host_bsq_entry {
struct cp_bsq_entry __iomem *cp_entry; /* addr of cp resident buffer supply queue entry */
enum status* status; /* addr of host resident status */
struct rbd_block* rbd_block; /* addr of receive buffer descriptor block */
u32 rbd_block_dma; /* DMA address od rdb */
} host_bsq_entry_t;
/* host resident command queue entry */
typedef struct host_cmdq_entry {
struct cp_cmdq_entry __iomem *cp_entry; /* addr of cp resident cmd queue entry */
enum status *status; /* addr of host resident status */
} host_cmdq_entry_t;
/* chunk of memory */
typedef struct chunk {
void* alloc_addr; /* base address of allocated chunk */
void* align_addr; /* base address of aligned chunk */
dma_addr_t dma_addr; /* DMA address of aligned chunk */
int direction; /* direction of DMA mapping */
u32 alloc_size; /* length of allocated chunk */
u32 align_size; /* length of aligned chunk */
} chunk_t;
#define dma_size align_size /* DMA useable size */
/* host resident receive buffer */
typedef struct buffer {
struct buffer* next; /* next receive buffer */
enum buffer_scheme scheme; /* buffer scheme */
enum buffer_magn magn; /* buffer magnitude */
struct chunk data; /* data buffer */
#ifdef FORE200E_BSQ_DEBUG
unsigned long index; /* buffer # in queue */
int supplied; /* 'buffer supplied' flag */
#endif
} buffer_t;
#if (BITS_PER_LONG == 32)
#define FORE200E_BUF2HDL(buffer) ((u32)(buffer))
#define FORE200E_HDL2BUF(handle) ((struct buffer*)(handle))
#else /* deal with 64 bit pointers */
#define FORE200E_BUF2HDL(buffer) ((u32)((u64)(buffer)))
#define FORE200E_HDL2BUF(handle) ((struct buffer*)(((u64)(handle)) | PAGE_OFFSET))
#endif
/* host resident command queue */
typedef struct host_cmdq {
struct host_cmdq_entry host_entry[ QUEUE_SIZE_CMD ]; /* host resident cmd queue entries */
int head; /* head of cmd queue */
struct chunk status; /* array of completion status */
} host_cmdq_t;
/* host resident transmit queue */
typedef struct host_txq {
struct host_txq_entry host_entry[ QUEUE_SIZE_TX ]; /* host resident tx queue entries */
int head; /* head of tx queue */
int tail; /* tail of tx queue */
struct chunk tpd; /* array of tpds */
struct chunk status; /* arry of completion status */
int txing; /* number of pending PDUs in tx queue */
} host_txq_t;
/* host resident receive queue */
typedef struct host_rxq {
struct host_rxq_entry host_entry[ QUEUE_SIZE_RX ]; /* host resident rx queue entries */
int head; /* head of rx queue */
struct chunk rpd; /* array of rpds */
struct chunk status; /* array of completion status */
} host_rxq_t;
/* host resident buffer supply queues */
typedef struct host_bsq {
struct host_bsq_entry host_entry[ QUEUE_SIZE_BS ]; /* host resident buffer supply queue entries */
int head; /* head of buffer supply queue */
struct chunk rbd_block; /* array of rbds */
struct chunk status; /* array of completion status */
struct buffer* buffer; /* array of rx buffers */
struct buffer* freebuf; /* list of free rx buffers */
volatile int freebuf_count; /* count of free rx buffers */
} host_bsq_t;
/* header of the firmware image */
typedef struct fw_header {
__le32 magic; /* magic number */
__le32 version; /* firmware version id */
__le32 load_offset; /* fw load offset in board memory */
__le32 start_offset; /* fw execution start address in board memory */
} fw_header_t;
#define FW_HEADER_MAGIC 0x65726f66 /* 'fore' */
/* receive buffer supply queues scheme specification */
typedef struct bs_spec {
u32 queue_length; /* queue capacity */
u32 buffer_size; /* host buffer size */
u32 pool_size; /* number of rbds */
u32 supply_blksize; /* num of rbds in I/O block (multiple
of 4 between 4 and 124 inclusive) */
} bs_spec_t;
/* initialization command block (one-time command, not in cmd queue) */
typedef struct init_block {
enum opcode opcode; /* initialize command */
enum status status; /* related status word */
u32 receive_threshold; /* not used */
u32 num_connect; /* ATM connections */
u32 cmd_queue_len; /* length of command queue */
u32 tx_queue_len; /* length of transmit queue */
u32 rx_queue_len; /* length of receive queue */
u32 rsd_extension; /* number of extra 32 byte blocks */
u32 tsd_extension; /* number of extra 32 byte blocks */
u32 conless_vpvc; /* not used */
u32 pad[ 2 ]; /* force quad alignment */
struct bs_spec bs_spec[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ]; /* buffer supply queues spec */
} init_block_t;
typedef enum media_type {
MEDIA_TYPE_CAT5_UTP = 0x06, /* unshielded twisted pair */
MEDIA_TYPE_MM_OC3_ST = 0x16, /* multimode fiber ST */
MEDIA_TYPE_MM_OC3_SC = 0x26, /* multimode fiber SC */
MEDIA_TYPE_SM_OC3_ST = 0x36, /* single-mode fiber ST */
MEDIA_TYPE_SM_OC3_SC = 0x46 /* single-mode fiber SC */
} media_type_t;
#define FORE200E_MEDIA_INDEX(media_type) ((media_type)>>4)
/* cp resident queues */
typedef struct cp_queues {
u32 cp_cmdq; /* command queue */
u32 cp_txq; /* transmit queue */
u32 cp_rxq; /* receive queue */
u32 cp_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ]; /* buffer supply queues */
u32 imask; /* 1 enables cp to host interrupts */
u32 istat; /* 1 for interrupt posted */
u32 heap_base; /* offset form beginning of ram */
u32 heap_size; /* space available for queues */
u32 hlogger; /* non zero for host logging */
u32 heartbeat; /* cp heartbeat */
u32 fw_release; /* firmware version */
u32 mon960_release; /* i960 monitor version */
u32 tq_plen; /* transmit throughput measurements */
/* make sure the init block remains on a quad word boundary */
struct init_block init; /* one time cmd, not in cmd queue */
enum media_type media_type; /* media type id */
u32 oc3_revision; /* OC-3 revision number */
} cp_queues_t;
/* boot status */
typedef enum boot_status {
BSTAT_COLD_START = (u32) 0xc01dc01d, /* cold start */
BSTAT_SELFTEST_OK = (u32) 0x02201958, /* self-test ok */
BSTAT_SELFTEST_FAIL = (u32) 0xadbadbad, /* self-test failed */
BSTAT_CP_RUNNING = (u32) 0xce11feed, /* cp is running */
BSTAT_MON_TOO_BIG = (u32) 0x10aded00 /* i960 monitor is too big */
} boot_status_t;
/* software UART */
typedef struct soft_uart {
u32 send; /* write register */
u32 recv; /* read register */
} soft_uart_t;
#define FORE200E_CP_MONITOR_UART_FREE 0x00000000
#define FORE200E_CP_MONITOR_UART_AVAIL 0x01000000
/* i960 monitor */
typedef struct cp_monitor {
struct soft_uart soft_uart; /* software UART */
enum boot_status bstat; /* boot status */
u32 app_base; /* application base offset */
u32 mon_version; /* i960 monitor version */
} cp_monitor_t;
/* device state */
typedef enum fore200e_state {
FORE200E_STATE_BLANK, /* initial state */
FORE200E_STATE_REGISTER, /* device registered */
FORE200E_STATE_CONFIGURE, /* bus interface configured */
FORE200E_STATE_MAP, /* board space mapped in host memory */
FORE200E_STATE_RESET, /* board resetted */
FORE200E_STATE_START_FW, /* firmware started */
FORE200E_STATE_INITIALIZE, /* initialize command successful */
FORE200E_STATE_INIT_CMDQ, /* command queue initialized */
FORE200E_STATE_INIT_TXQ, /* transmit queue initialized */
FORE200E_STATE_INIT_RXQ, /* receive queue initialized */
FORE200E_STATE_INIT_BSQ, /* buffer supply queue initialized */
FORE200E_STATE_ALLOC_BUF, /* receive buffers allocated */
FORE200E_STATE_IRQ, /* host interrupt requested */
FORE200E_STATE_COMPLETE /* initialization completed */
} fore200e_state;
/* PCA-200E registers */
typedef struct fore200e_pca_regs {
volatile u32 __iomem * hcr; /* address of host control register */
volatile u32 __iomem * imr; /* address of host interrupt mask register */
volatile u32 __iomem * psr; /* address of PCI specific register */
} fore200e_pca_regs_t;
/* SBA-200E registers */
typedef struct fore200e_sba_regs {
u32 __iomem *hcr; /* address of host control register */
u32 __iomem *bsr; /* address of burst transfer size register */
u32 __iomem *isr; /* address of interrupt level selection register */
} fore200e_sba_regs_t;
/* model-specific registers */
typedef union fore200e_regs {
struct fore200e_pca_regs pca; /* PCA-200E registers */
struct fore200e_sba_regs sba; /* SBA-200E registers */
} fore200e_regs;
struct fore200e;
/* bus-dependent data */
typedef struct fore200e_bus {
char* model_name; /* board model name */
char* proc_name; /* board name under /proc/atm */
int descr_alignment; /* tpd/rpd/rbd DMA alignment requirement */
int buffer_alignment; /* rx buffers DMA alignment requirement */
int status_alignment; /* status words DMA alignment requirement */
u32 (*read)(volatile u32 __iomem *);
void (*write)(u32, volatile u32 __iomem *);
u32 (*dma_map)(struct fore200e*, void*, int, int);
void (*dma_unmap)(struct fore200e*, u32, int, int);
void (*dma_sync_for_cpu)(struct fore200e*, u32, int, int);
void (*dma_sync_for_device)(struct fore200e*, u32, int, int);
int (*dma_chunk_alloc)(struct fore200e*, struct chunk*, int, int, int);
void (*dma_chunk_free)(struct fore200e*, struct chunk*);
int (*configure)(struct fore200e*);
int (*map)(struct fore200e*);
void (*reset)(struct fore200e*);
int (*prom_read)(struct fore200e*, struct prom_data*);
void (*unmap)(struct fore200e*);
void (*irq_enable)(struct fore200e*);
int (*irq_check)(struct fore200e*);
void (*irq_ack)(struct fore200e*);
int (*proc_read)(struct fore200e*, char*);
} fore200e_bus_t;
/* vc mapping */
typedef struct fore200e_vc_map {
struct atm_vcc* vcc; /* vcc entry */
unsigned long incarn; /* vcc incarnation number */
} fore200e_vc_map_t;
#define FORE200E_VC_MAP(fore200e, vpi, vci) \
(& (fore200e)->vc_map[ ((vpi) << FORE200E_VCI_BITS) | (vci) ])
/* per-device data */
typedef struct fore200e {
struct list_head entry; /* next device */
const struct fore200e_bus* bus; /* bus-dependent code and data */
union fore200e_regs regs; /* bus-dependent registers */
struct atm_dev* atm_dev; /* ATM device */
enum fore200e_state state; /* device state */
char name[16]; /* device name */
void* bus_dev; /* bus-specific kernel data */
int irq; /* irq number */
unsigned long phys_base; /* physical base address */
void __iomem * virt_base; /* virtual base address */
unsigned char esi[ ESI_LEN ]; /* end system identifier */
struct cp_monitor __iomem * cp_monitor; /* i960 monitor address */
struct cp_queues __iomem * cp_queues; /* cp resident queues */
struct host_cmdq host_cmdq; /* host resident cmd queue */
struct host_txq host_txq; /* host resident tx queue */
struct host_rxq host_rxq; /* host resident rx queue */
/* host resident buffer supply queues */
struct host_bsq host_bsq[ BUFFER_SCHEME_NBR ][ BUFFER_MAGN_NBR ];
u32 available_cell_rate; /* remaining pseudo-CBR bw on link */
int loop_mode; /* S/UNI loopback mode */
struct stats* stats; /* last snapshot of the stats */
struct mutex rate_mtx; /* protects rate reservation ops */
spinlock_t q_lock; /* protects queue ops */
#ifdef FORE200E_USE_TASKLET
struct tasklet_struct tx_tasklet; /* performs tx interrupt work */
struct tasklet_struct rx_tasklet; /* performs rx interrupt work */
#endif
unsigned long tx_sat; /* tx queue saturation count */
unsigned long incarn_count;
struct fore200e_vc_map vc_map[ NBR_CONNECT ]; /* vc mapping */
} fore200e_t;
/* per-vcc data */
typedef struct fore200e_vcc {
enum buffer_scheme scheme; /* rx buffer scheme */
struct tpd_rate rate; /* tx rate control data */
int rx_min_pdu; /* size of smallest PDU received */
int rx_max_pdu; /* size of largest PDU received */
int tx_min_pdu; /* size of smallest PDU transmitted */
int tx_max_pdu; /* size of largest PDU transmitted */
unsigned long tx_pdu; /* nbr of tx pdus */
unsigned long rx_pdu; /* nbr of rx pdus */
} fore200e_vcc_t;
/* 200E-series common memory layout */
#define FORE200E_CP_MONITOR_OFFSET 0x00000400 /* i960 monitor interface */
#define FORE200E_CP_QUEUES_OFFSET 0x00004d40 /* cp resident queues */
/* PCA-200E memory layout */
#define PCA200E_IOSPACE_LENGTH 0x00200000
#define PCA200E_HCR_OFFSET 0x00100000 /* board control register */
#define PCA200E_IMR_OFFSET 0x00100004 /* host IRQ mask register */
#define PCA200E_PSR_OFFSET 0x00100008 /* PCI specific register */
/* PCA-200E host control register */
#define PCA200E_HCR_RESET (1<<0) /* read / write */
#define PCA200E_HCR_HOLD_LOCK (1<<1) /* read / write */
#define PCA200E_HCR_I960FAIL (1<<2) /* read */
#define PCA200E_HCR_INTRB (1<<2) /* write */
#define PCA200E_HCR_HOLD_ACK (1<<3) /* read */
#define PCA200E_HCR_INTRA (1<<3) /* write */
#define PCA200E_HCR_OUTFULL (1<<4) /* read */
#define PCA200E_HCR_CLRINTR (1<<4) /* write */
#define PCA200E_HCR_ESPHOLD (1<<5) /* read */
#define PCA200E_HCR_INFULL (1<<6) /* read */
#define PCA200E_HCR_TESTMODE (1<<7) /* read */
/* PCA-200E PCI bus interface regs (offsets in PCI config space) */
#define PCA200E_PCI_LATENCY 0x40 /* maximum slave latenty */
#define PCA200E_PCI_MASTER_CTRL 0x41 /* master control */
#define PCA200E_PCI_THRESHOLD 0x42 /* burst / continuous req threshold */
/* PBI master control register */
#define PCA200E_CTRL_DIS_CACHE_RD (1<<0) /* disable cache-line reads */
#define PCA200E_CTRL_DIS_WRT_INVAL (1<<1) /* disable writes and invalidates */
#define PCA200E_CTRL_2_CACHE_WRT_INVAL (1<<2) /* require 2 cache-lines for writes and invalidates */
#define PCA200E_CTRL_IGN_LAT_TIMER (1<<3) /* ignore the latency timer */
#define PCA200E_CTRL_ENA_CONT_REQ_MODE (1<<4) /* enable continuous request mode */
#define PCA200E_CTRL_LARGE_PCI_BURSTS (1<<5) /* force large PCI bus bursts */
#define PCA200E_CTRL_CONVERT_ENDIAN (1<<6) /* convert endianess of slave RAM accesses */
#define SBA200E_PROM_NAME "FORE,sba-200e" /* device name in openprom tree */
/* size of SBA-200E registers */
#define SBA200E_HCR_LENGTH 4
#define SBA200E_BSR_LENGTH 4
#define SBA200E_ISR_LENGTH 4
#define SBA200E_RAM_LENGTH 0x40000
/* SBA-200E SBUS burst transfer size register */
#define SBA200E_BSR_BURST4 0x04
#define SBA200E_BSR_BURST8 0x08
#define SBA200E_BSR_BURST16 0x10
/* SBA-200E host control register */
#define SBA200E_HCR_RESET (1<<0) /* read / write (sticky) */
#define SBA200E_HCR_HOLD_LOCK (1<<1) /* read / write (sticky) */
#define SBA200E_HCR_I960FAIL (1<<2) /* read */
#define SBA200E_HCR_I960SETINTR (1<<2) /* write */
#define SBA200E_HCR_OUTFULL (1<<3) /* read */
#define SBA200E_HCR_INTR_CLR (1<<3) /* write */
#define SBA200E_HCR_INTR_ENA (1<<4) /* read / write (sticky) */
#define SBA200E_HCR_ESPHOLD (1<<5) /* read */
#define SBA200E_HCR_INFULL (1<<6) /* read */
#define SBA200E_HCR_TESTMODE (1<<7) /* read */
#define SBA200E_HCR_INTR_REQ (1<<8) /* read */
#define SBA200E_HCR_STICKY (SBA200E_HCR_RESET | SBA200E_HCR_HOLD_LOCK | SBA200E_HCR_INTR_ENA)
#endif /* __KERNEL__ */
#endif /* _FORE200E_H */

2866
drivers/atm/he.c Normal file

File diff suppressed because it is too large Load diff

845
drivers/atm/he.h Normal file
View file

@ -0,0 +1,845 @@
/*
he.h
ForeRunnerHE ATM Adapter driver for ATM on Linux
Copyright (C) 1999-2001 Naval Research Laboratory
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
he.h
ForeRunnerHE ATM Adapter driver for ATM on Linux
Copyright (C) 1999-2000 Naval Research Laboratory
Permission to use, copy, modify and distribute this software and its
documentation is hereby granted, provided that both the copyright
notice and this permission notice appear in all copies of the software,
derivative works or modified versions, and any portions thereof, and
that both notices appear in supporting documentation.
NRL ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION AND
DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
RESULTING FROM THE USE OF THIS SOFTWARE.
*/
#ifndef _HE_H_
#define _HE_H_
#define DEV_LABEL "he"
#define CONFIG_DEFAULT_VCIBITS 12
#define CONFIG_DEFAULT_VPIBITS 0
#define CONFIG_IRQ_SIZE 128
#define CONFIG_IRQ_THRESH (CONFIG_IRQ_SIZE/2)
#define CONFIG_TPDRQ_SIZE 512
#define TPDRQ_MASK(x) (((unsigned long)(x))&((CONFIG_TPDRQ_SIZE<<3)-1))
#define CONFIG_RBRQ_SIZE 512
#define CONFIG_RBRQ_THRESH 400
#define RBRQ_MASK(x) (((unsigned long)(x))&((CONFIG_RBRQ_SIZE<<3)-1))
#define CONFIG_TBRQ_SIZE 512
#define CONFIG_TBRQ_THRESH 400
#define TBRQ_MASK(x) (((unsigned long)(x))&((CONFIG_TBRQ_SIZE<<2)-1))
#define CONFIG_RBPL_SIZE 512
#define CONFIG_RBPL_THRESH 64
#define CONFIG_RBPL_BUFSIZE 4096
#define RBPL_MASK(x) (((unsigned long)(x))&((CONFIG_RBPL_SIZE<<3)-1))
/* 5.1.3 initialize connection memory */
#define CONFIG_RSRA 0x00000
#define CONFIG_RCMLBM 0x08000
#define CONFIG_RCMABR 0x0d800
#define CONFIG_RSRB 0x0e000
#define CONFIG_TSRA 0x00000
#define CONFIG_TSRB 0x08000
#define CONFIG_TSRC 0x0c000
#define CONFIG_TSRD 0x0e000
#define CONFIG_TMABR 0x0f000
#define CONFIG_TPDBA 0x10000
#define HE_MAXCIDBITS 12
/* 2.9.3.3 interrupt encodings */
struct he_irq {
volatile u32 isw;
};
#define IRQ_ALIGNMENT 0x1000
#define NEXT_ENTRY(base, tail, mask) \
(((unsigned long)base)|(((unsigned long)(tail+1))&mask))
#define ITYPE_INVALID 0xffffffff
#define ITYPE_TBRQ_THRESH (0<<3)
#define ITYPE_TPD_COMPLETE (1<<3)
#define ITYPE_RBPS_THRESH (2<<3)
#define ITYPE_RBPL_THRESH (3<<3)
#define ITYPE_RBRQ_THRESH (4<<3)
#define ITYPE_RBRQ_TIMER (5<<3)
#define ITYPE_PHY (6<<3)
#define ITYPE_OTHER 0x80
#define ITYPE_PARITY 0x81
#define ITYPE_ABORT 0x82
#define ITYPE_GROUP(x) (x & 0x7)
#define ITYPE_TYPE(x) (x & 0xf8)
#define HE_NUM_GROUPS 8
/* 2.1.4 transmit packet descriptor */
struct he_tpd {
/* read by the adapter */
volatile u32 status;
volatile u32 reserved;
#define TPD_MAXIOV 3
struct {
u32 addr, len;
} iovec[TPD_MAXIOV];
#define address0 iovec[0].addr
#define length0 iovec[0].len
/* linux-atm extensions */
struct sk_buff *skb;
struct atm_vcc *vcc;
struct list_head entry;
};
#define TPD_ALIGNMENT 64
#define TPD_LEN_MASK 0xffff
#define TPD_ADDR_SHIFT 6
#define TPD_MASK 0xffffffc0
#define TPD_ADDR(x) ((x) & TPD_MASK)
#define TPD_INDEX(x) (TPD_ADDR(x) >> TPD_ADDR_SHIFT)
/* table 2.3 transmit buffer return elements */
struct he_tbrq {
volatile u32 tbre;
};
#define TBRQ_ALIGNMENT CONFIG_TBRQ_SIZE
#define TBRQ_TPD(tbrq) ((tbrq)->tbre & 0xffffffc0)
#define TBRQ_EOS(tbrq) ((tbrq)->tbre & (1<<3))
#define TBRQ_MULTIPLE(tbrq) ((tbrq)->tbre & (1))
/* table 2.21 receive buffer return queue element field organization */
struct he_rbrq {
volatile u32 addr;
volatile u32 cidlen;
};
#define RBRQ_ALIGNMENT CONFIG_RBRQ_SIZE
#define RBRQ_ADDR(rbrq) ((rbrq)->addr & 0xffffffc0)
#define RBRQ_CRC_ERR(rbrq) ((rbrq)->addr & (1<<5))
#define RBRQ_LEN_ERR(rbrq) ((rbrq)->addr & (1<<4))
#define RBRQ_END_PDU(rbrq) ((rbrq)->addr & (1<<3))
#define RBRQ_AAL5_PROT(rbrq) ((rbrq)->addr & (1<<2))
#define RBRQ_CON_CLOSED(rbrq) ((rbrq)->addr & (1<<1))
#define RBRQ_HBUF_ERR(rbrq) ((rbrq)->addr & 1)
#define RBRQ_CID(rbrq) (((rbrq)->cidlen >> 16) & 0x1fff)
#define RBRQ_BUFLEN(rbrq) ((rbrq)->cidlen & 0xffff)
/* figure 2.3 transmit packet descriptor ready queue */
struct he_tpdrq {
volatile u32 tpd;
volatile u32 cid;
};
#define TPDRQ_ALIGNMENT CONFIG_TPDRQ_SIZE
/* table 2.30 host status page detail */
#define HSP_ALIGNMENT 0x400 /* must align on 1k boundary */
struct he_hsp {
struct he_hsp_entry {
volatile u32 tbrq_tail;
volatile u32 reserved1[15];
volatile u32 rbrq_tail;
volatile u32 reserved2[15];
} group[HE_NUM_GROUPS];
};
/*
* figure 2.9 receive buffer pools
*
* since a virtual address might be more than 32 bits, we store an index
* in the virt member of he_rbp. NOTE: the lower six bits in the rbrq
* addr member are used for buffer status further limiting us to 26 bits.
*/
struct he_rbp {
volatile u32 phys;
volatile u32 idx; /* virt */
};
#define RBP_IDX_OFFSET 6
/*
* the he dma engine will try to hold an extra 16 buffers in its local
* caches. and add a couple buffers for safety.
*/
#define RBPL_TABLE_SIZE (CONFIG_RBPL_SIZE + 16 + 2)
struct he_buff {
struct list_head entry;
dma_addr_t mapping;
unsigned long len;
u8 data[];
};
#ifdef notyet
struct he_group {
u32 rpbl_size, rpbl_qsize;
struct he_rpb_entry *rbpl_ba;
};
#endif
#define HE_LOOKUP_VCC(dev, cid) ((dev)->he_vcc_table[(cid)].vcc)
struct he_vcc_table
{
struct atm_vcc *vcc;
};
struct he_cs_stper
{
long pcr;
int inuse;
};
#define HE_NUM_CS_STPER 16
struct he_dev {
unsigned int number;
unsigned int irq;
void __iomem *membase;
char prod_id[30];
char mac_addr[6];
int media;
unsigned int vcibits, vpibits;
unsigned int cells_per_row;
unsigned int bytes_per_row;
unsigned int cells_per_lbuf;
unsigned int r0_numrows, r0_startrow, r0_numbuffs;
unsigned int r1_numrows, r1_startrow, r1_numbuffs;
unsigned int tx_numrows, tx_startrow, tx_numbuffs;
unsigned int buffer_limit;
struct he_vcc_table *he_vcc_table;
#ifdef notyet
struct he_group group[HE_NUM_GROUPS];
#endif
struct he_cs_stper cs_stper[HE_NUM_CS_STPER];
unsigned total_bw;
dma_addr_t irq_phys;
struct he_irq *irq_base, *irq_head, *irq_tail;
volatile unsigned *irq_tailoffset;
int irq_peak;
struct tasklet_struct tasklet;
struct pci_pool *tpd_pool;
struct list_head outstanding_tpds;
dma_addr_t tpdrq_phys;
struct he_tpdrq *tpdrq_base, *tpdrq_tail, *tpdrq_head;
spinlock_t global_lock; /* 8.1.5 pci transaction ordering
error problem */
dma_addr_t rbrq_phys;
struct he_rbrq *rbrq_base, *rbrq_head;
int rbrq_peak;
struct he_buff **rbpl_virt;
unsigned long *rbpl_table;
unsigned long rbpl_hint;
struct pci_pool *rbpl_pool;
dma_addr_t rbpl_phys;
struct he_rbp *rbpl_base, *rbpl_tail;
struct list_head rbpl_outstanding;
int rbpl_peak;
dma_addr_t tbrq_phys;
struct he_tbrq *tbrq_base, *tbrq_head;
int tbrq_peak;
dma_addr_t hsp_phys;
struct he_hsp *hsp;
struct pci_dev *pci_dev;
struct atm_dev *atm_dev;
struct he_dev *next;
};
#define HE_MAXIOV 20
struct he_vcc
{
struct list_head buffers;
int pdu_len;
int rc_index;
wait_queue_head_t rx_waitq;
wait_queue_head_t tx_waitq;
};
#define HE_VCC(vcc) ((struct he_vcc *)(vcc->dev_data))
#define PCI_VENDOR_ID_FORE 0x1127
#define PCI_DEVICE_ID_FORE_HE 0x400
#define GEN_CNTL_0 0x40
#define INT_PROC_ENBL (1<<25)
#define SLAVE_ENDIAN_MODE (1<<16)
#define MRL_ENB (1<<5)
#define MRM_ENB (1<<4)
#define INIT_ENB (1<<2)
#define IGNORE_TIMEOUT (1<<1)
#define ENBL_64 (1<<0)
#define MIN_PCI_LATENCY 32 /* errata 8.1.3 */
#define HE_DEV(dev) ((struct he_dev *) (dev)->dev_data)
#define he_is622(dev) ((dev)->media & 0x1)
#define he_isMM(dev) ((dev)->media & 0x20)
#define HE_REGMAP_SIZE 0x100000
#define RESET_CNTL 0x80000
#define BOARD_RST_STATUS (1<<6)
#define HOST_CNTL 0x80004
#define PCI_BUS_SIZE64 (1<<27)
#define DESC_RD_STATIC_64 (1<<26)
#define DATA_RD_STATIC_64 (1<<25)
#define DATA_WR_STATIC_64 (1<<24)
#define ID_CS (1<<12)
#define ID_WREN (1<<11)
#define ID_DOUT (1<<10)
#define ID_DOFFSET 10
#define ID_DIN (1<<9)
#define ID_CLOCK (1<<8)
#define QUICK_RD_RETRY (1<<7)
#define QUICK_WR_RETRY (1<<6)
#define OUTFF_ENB (1<<5)
#define CMDFF_ENB (1<<4)
#define PERR_INT_ENB (1<<2)
#define IGNORE_INTR (1<<0)
#define LB_SWAP 0x80008
#define SWAP_RNUM_MAX(x) (x<<27)
#define DATA_WR_SWAP (1<<20)
#define DESC_RD_SWAP (1<<19)
#define DATA_RD_SWAP (1<<18)
#define INTR_SWAP (1<<17)
#define DESC_WR_SWAP (1<<16)
#define SDRAM_INIT (1<<15)
#define BIG_ENDIAN_HOST (1<<14)
#define XFER_SIZE (1<<7)
#define LB_MEM_ADDR 0x8000c
#define LB_MEM_DATA 0x80010
#define LB_MEM_ACCESS 0x80014
#define LB_MEM_HNDSHK (1<<30)
#define LM_MEM_WRITE (0x7)
#define LM_MEM_READ (0x3)
#define SDRAM_CTL 0x80018
#define LB_64_ENB (1<<3)
#define LB_TWR (1<<2)
#define LB_TRP (1<<1)
#define LB_TRAS (1<<0)
#define INT_FIFO 0x8001c
#define INT_MASK_D (1<<15)
#define INT_MASK_C (1<<14)
#define INT_MASK_B (1<<13)
#define INT_MASK_A (1<<12)
#define INT_CLEAR_D (1<<11)
#define INT_CLEAR_C (1<<10)
#define INT_CLEAR_B (1<<9)
#define INT_CLEAR_A (1<<8)
#define ABORT_ADDR 0x80020
#define IRQ0_BASE 0x80080
#define IRQ_BASE(x) (x<<12)
#define IRQ_MASK ((CONFIG_IRQ_SIZE<<2)-1) /* was 0x3ff */
#define IRQ_TAIL(x) (((unsigned long)(x)) & IRQ_MASK)
#define IRQ0_HEAD 0x80084
#define IRQ_SIZE(x) (x<<22)
#define IRQ_THRESH(x) (x<<12)
#define IRQ_HEAD(x) (x<<2)
/* #define IRQ_PENDING (1) conflict with linux/irq.h */
#define IRQ0_CNTL 0x80088
#define IRQ_ADDRSEL(x) (x<<2)
#define IRQ_INT_A (0<<2)
#define IRQ_INT_B (1<<2)
#define IRQ_INT_C (2<<2)
#define IRQ_INT_D (3<<2)
#define IRQ_TYPE_ADDR 0x1
#define IRQ_TYPE_LINE 0x0
#define IRQ0_DATA 0x8008c
#define IRQ1_BASE 0x80090
#define IRQ1_HEAD 0x80094
#define IRQ1_CNTL 0x80098
#define IRQ1_DATA 0x8009c
#define IRQ2_BASE 0x800a0
#define IRQ2_HEAD 0x800a4
#define IRQ2_CNTL 0x800a8
#define IRQ2_DATA 0x800ac
#define IRQ3_BASE 0x800b0
#define IRQ3_HEAD 0x800b4
#define IRQ3_CNTL 0x800b8
#define IRQ3_DATA 0x800bc
#define GRP_10_MAP 0x800c0
#define GRP_32_MAP 0x800c4
#define GRP_54_MAP 0x800c8
#define GRP_76_MAP 0x800cc
#define G0_RBPS_S 0x80400
#define G0_RBPS_T 0x80404
#define RBP_TAIL(x) ((x)<<3)
#define RBP_MASK(x) ((x)|0x1fff)
#define G0_RBPS_QI 0x80408
#define RBP_QSIZE(x) ((x)<<14)
#define RBP_INT_ENB (1<<13)
#define RBP_THRESH(x) (x)
#define G0_RBPS_BS 0x8040c
#define G0_RBPL_S 0x80410
#define G0_RBPL_T 0x80414
#define G0_RBPL_QI 0x80418
#define G0_RBPL_BS 0x8041c
#define G1_RBPS_S 0x80420
#define G1_RBPS_T 0x80424
#define G1_RBPS_QI 0x80428
#define G1_RBPS_BS 0x8042c
#define G1_RBPL_S 0x80430
#define G1_RBPL_T 0x80434
#define G1_RBPL_QI 0x80438
#define G1_RBPL_BS 0x8043c
#define G2_RBPS_S 0x80440
#define G2_RBPS_T 0x80444
#define G2_RBPS_QI 0x80448
#define G2_RBPS_BS 0x8044c
#define G2_RBPL_S 0x80450
#define G2_RBPL_T 0x80454
#define G2_RBPL_QI 0x80458
#define G2_RBPL_BS 0x8045c
#define G3_RBPS_S 0x80460
#define G3_RBPS_T 0x80464
#define G3_RBPS_QI 0x80468
#define G3_RBPS_BS 0x8046c
#define G3_RBPL_S 0x80470
#define G3_RBPL_T 0x80474
#define G3_RBPL_QI 0x80478
#define G3_RBPL_BS 0x8047c
#define G4_RBPS_S 0x80480
#define G4_RBPS_T 0x80484
#define G4_RBPS_QI 0x80488
#define G4_RBPS_BS 0x8048c
#define G4_RBPL_S 0x80490
#define G4_RBPL_T 0x80494
#define G4_RBPL_QI 0x80498
#define G4_RBPL_BS 0x8049c
#define G5_RBPS_S 0x804a0
#define G5_RBPS_T 0x804a4
#define G5_RBPS_QI 0x804a8
#define G5_RBPS_BS 0x804ac
#define G5_RBPL_S 0x804b0
#define G5_RBPL_T 0x804b4
#define G5_RBPL_QI 0x804b8
#define G5_RBPL_BS 0x804bc
#define G6_RBPS_S 0x804c0
#define G6_RBPS_T 0x804c4
#define G6_RBPS_QI 0x804c8
#define G6_RBPS_BS 0x804cc
#define G6_RBPL_S 0x804d0
#define G6_RBPL_T 0x804d4
#define G6_RBPL_QI 0x804d8
#define G6_RBPL_BS 0x804dc
#define G7_RBPS_S 0x804e0
#define G7_RBPS_T 0x804e4
#define G7_RBPS_QI 0x804e8
#define G7_RBPS_BS 0x804ec
#define G7_RBPL_S 0x804f0
#define G7_RBPL_T 0x804f4
#define G7_RBPL_QI 0x804f8
#define G7_RBPL_BS 0x804fc
#define G0_RBRQ_ST 0x80500
#define G0_RBRQ_H 0x80504
#define G0_RBRQ_Q 0x80508
#define RBRQ_THRESH(x) ((x)<<13)
#define RBRQ_SIZE(x) (x)
#define G0_RBRQ_I 0x8050c
#define RBRQ_TIME(x) ((x)<<8)
#define RBRQ_COUNT(x) (x)
/* fill in 1 ... 7 later */
#define G0_TBRQ_B_T 0x80600
#define G0_TBRQ_H 0x80604
#define G0_TBRQ_S 0x80608
#define G0_TBRQ_THRESH 0x8060c
#define TBRQ_THRESH(x) (x)
/* fill in 1 ... 7 later */
#define RH_CONFIG 0x805c0
#define PHY_INT_ENB (1<<10)
#define OAM_GID(x) (x<<7)
#define PTMR_PRE(x) (x)
#define G0_INMQ_S 0x80580
#define G0_INMQ_L 0x80584
#define G1_INMQ_S 0x80588
#define G1_INMQ_L 0x8058c
#define G2_INMQ_S 0x80590
#define G2_INMQ_L 0x80594
#define G3_INMQ_S 0x80598
#define G3_INMQ_L 0x8059c
#define G4_INMQ_S 0x805a0
#define G4_INMQ_L 0x805a4
#define G5_INMQ_S 0x805a8
#define G5_INMQ_L 0x805ac
#define G6_INMQ_S 0x805b0
#define G6_INMQ_L 0x805b4
#define G7_INMQ_S 0x805b8
#define G7_INMQ_L 0x805bc
#define TPDRQ_B_H 0x80680
#define TPDRQ_T 0x80684
#define TPDRQ_S 0x80688
#define UBUFF_BA 0x8068c
#define RLBF0_H 0x806c0
#define RLBF0_T 0x806c4
#define RLBF1_H 0x806c8
#define RLBF1_T 0x806cc
#define RLBC_H 0x806d0
#define RLBC_T 0x806d4
#define RLBC_H2 0x806d8
#define TLBF_H 0x806e0
#define TLBF_T 0x806e4
#define RLBF0_C 0x806e8
#define RLBF1_C 0x806ec
#define RXTHRSH 0x806f0
#define LITHRSH 0x806f4
#define LBARB 0x80700
#define SLICE_X(x) (x<<28)
#define ARB_RNUM_MAX(x) (x<<23)
#define TH_PRTY(x) (x<<21)
#define RH_PRTY(x) (x<<19)
#define TL_PRTY(x) (x<<17)
#define RL_PRTY(x) (x<<15)
#define BUS_MULTI(x) (x<<8)
#define NET_PREF(x) (x)
#define SDRAMCON 0x80704
#define BANK_ON (1<<14)
#define WIDE_DATA (1<<13)
#define TWR_WAIT (1<<12)
#define TRP_WAIT (1<<11)
#define TRAS_WAIT (1<<10)
#define REF_RATE(x) (x)
#define LBSTAT 0x80708
#define RCC_STAT 0x8070c
#define RCC_BUSY (1)
#define TCMCONFIG 0x80740
#define TM_DESL2 (1<<10)
#define TM_BANK_WAIT(x) (x<<6)
#define TM_ADD_BANK4(x) (x<<4)
#define TM_PAR_CHECK(x) (x<<3)
#define TM_RW_WAIT(x) (x<<2)
#define TM_SRAM_TYPE(x) (x)
#define TSRB_BA 0x80744
#define TSRC_BA 0x80748
#define TMABR_BA 0x8074c
#define TPD_BA 0x80750
#define TSRD_BA 0x80758
#define TX_CONFIG 0x80760
#define DRF_THRESH(x) (x<<22)
#define TX_UT_MODE(x) (x<<21)
#define TX_VCI_MASK(x) (x<<17)
#define LBFREE_CNT(x) (x)
#define TXAAL5_PROTO 0x80764
#define CPCS_UU(x) (x<<8)
#define CPI(x) (x)
#define RCMCONFIG 0x80780
#define RM_DESL2(x) (x<<10)
#define RM_BANK_WAIT(x) (x<<6)
#define RM_ADD_BANK(x) (x<<4)
#define RM_PAR_CHECK(x) (x<<3)
#define RM_RW_WAIT(x) (x<<2)
#define RM_SRAM_TYPE(x) (x)
#define RCMRSRB_BA 0x80784
#define RCMLBM_BA 0x80788
#define RCMABR_BA 0x8078c
#define RC_CONFIG 0x807c0
#define UT_RD_DELAY(x) (x<<11)
#define WRAP_MODE(x) (x<<10)
#define RC_UT_MODE(x) (x<<9)
#define RX_ENABLE (1<<8)
#define RX_VALVP(x) (x<<4)
#define RX_VALVC(x) (x)
#define MCC 0x807c4
#define OEC 0x807c8
#define DCC 0x807cc
#define CEC 0x807d0
#define HSP_BA 0x807f0
#define LB_CONFIG 0x807f4
#define LB_SIZE(x) (x)
#define CON_DAT 0x807f8
#define CON_CTL 0x807fc
#define CON_CTL_MBOX (2<<30)
#define CON_CTL_TCM (1<<30)
#define CON_CTL_RCM (0<<30)
#define CON_CTL_WRITE (1<<29)
#define CON_CTL_READ (0<<29)
#define CON_CTL_BUSY (1<<28)
#define CON_BYTE_DISABLE_3 (1<<22) /* 24..31 */
#define CON_BYTE_DISABLE_2 (1<<21) /* 16..23 */
#define CON_BYTE_DISABLE_1 (1<<20) /* 8..15 */
#define CON_BYTE_DISABLE_0 (1<<19) /* 0..7 */
#define CON_CTL_ADDR(x) (x)
#define FRAMER 0x80800 /* to 0x80bfc */
/* 3.3 network controller (internal) mailbox registers */
#define CS_STPER0 0x0
/* ... */
#define CS_STPER31 0x01f
#define CS_STTIM0 0x020
/* ... */
#define CS_STTIM31 0x03f
#define CS_TGRLD0 0x040
/* ... */
#define CS_TGRLD15 0x04f
#define CS_ERTHR0 0x050
#define CS_ERTHR1 0x051
#define CS_ERTHR2 0x052
#define CS_ERTHR3 0x053
#define CS_ERTHR4 0x054
#define CS_ERCTL0 0x055
#define TX_ENABLE (1<<28)
#define ER_ENABLE (1<<27)
#define CS_ERCTL1 0x056
#define CS_ERCTL2 0x057
#define CS_ERSTAT0 0x058
#define CS_ERSTAT1 0x059
#define CS_RTCCT 0x060
#define CS_RTFWC 0x061
#define CS_RTFWR 0x062
#define CS_RTFTC 0x063
#define CS_RTATR 0x064
#define CS_TFBSET 0x070
#define CS_TFBADD 0x071
#define CS_TFBSUB 0x072
#define CS_WCRMAX 0x073
#define CS_WCRMIN 0x074
#define CS_WCRINC 0x075
#define CS_WCRDEC 0x076
#define CS_WCRCEIL 0x077
#define CS_BWDCNT 0x078
#define CS_OTPPER 0x080
#define CS_OTWPER 0x081
#define CS_OTTLIM 0x082
#define CS_OTTCNT 0x083
#define CS_HGRRT0 0x090
/* ... */
#define CS_HGRRT7 0x097
#define CS_ORPTRS 0x0a0
#define RXCON_CLOSE 0x100
#define RCM_MEM_SIZE 0x10000 /* 1M of 32-bit registers */
#define TCM_MEM_SIZE 0x20000 /* 2M of 32-bit registers */
/* 2.5 transmit connection memory registers */
#define TSR0_CONN_STATE(x) ((x>>28) & 0x7)
#define TSR0_USE_WMIN (1<<23)
#define TSR0_GROUP(x) ((x & 0x7)<<18)
#define TSR0_ABR (2<<16)
#define TSR0_UBR (1<<16)
#define TSR0_CBR (0<<16)
#define TSR0_PROT (1<<15)
#define TSR0_AAL0_SDU (2<<12)
#define TSR0_AAL0 (1<<12)
#define TSR0_AAL5 (0<<12)
#define TSR0_HALT_ER (1<<11)
#define TSR0_MARK_CI (1<<10)
#define TSR0_MARK_ER (1<<9)
#define TSR0_UPDATE_GER (1<<8)
#define TSR0_RC_INDEX(x) (x & 0x1F)
#define TSR1_PCR(x) ((x & 0x7FFF)<<16)
#define TSR1_MCR(x) (x & 0x7FFF)
#define TSR2_ACR(x) ((x & 0x7FFF)<<16)
#define TSR3_NRM_CNT(x) ((x & 0xFF)<<24)
#define TSR3_CRM_CNT(x) (x & 0xFFFF)
#define TSR4_FLUSH_CONN (1<<31)
#define TSR4_SESSION_ENDED (1<<30)
#define TSR4_CRC10 (1<<28)
#define TSR4_NULL_CRC10 (1<<27)
#define TSR4_PROT (1<<26)
#define TSR4_AAL0_SDU (2<<23)
#define TSR4_AAL0 (1<<23)
#define TSR4_AAL5 (0<<23)
#define TSR9_OPEN_CONN (1<<20)
#define TSR11_ICR(x) ((x & 0x7FFF)<<16)
#define TSR11_TRM(x) ((x & 0x7)<<13)
#define TSR11_NRM(x) ((x & 0x7)<<10)
#define TSR11_ADTF(x) (x & 0x3FF)
#define TSR13_RDF(x) ((x & 0xF)<<23)
#define TSR13_RIF(x) ((x & 0xF)<<19)
#define TSR13_CDF(x) ((x & 0x7)<<16)
#define TSR13_CRM(x) (x & 0xFFFF)
#define TSR14_DELETE (1<<31)
#define TSR14_ABR_CLOSE (1<<16)
/* 2.7.1 per connection receieve state registers */
#define RSR0_START_PDU (1<<10)
#define RSR0_OPEN_CONN (1<<6)
#define RSR0_CLOSE_CONN (0<<6)
#define RSR0_PPD_ENABLE (1<<5)
#define RSR0_EPD_ENABLE (1<<4)
#define RSR0_TCP_CKSUM (1<<3)
#define RSR0_AAL5 (0)
#define RSR0_AAL0 (1)
#define RSR0_AAL0_SDU (2)
#define RSR0_RAWCELL (3)
#define RSR0_RAWCELL_CRC10 (4)
#define RSR1_AQI_ENABLE (1<<20)
#define RSR1_RBPL_ONLY (1<<19)
#define RSR1_GROUP(x) ((x)<<16)
#define RSR4_AQI_ENABLE (1<<30)
#define RSR4_GROUP(x) ((x)<<27)
#define RSR4_RBPL_ONLY (1<<26)
/* 2.1.4 transmit packet descriptor */
#define TPD_USERCELL 0x0
#define TPD_SEGMENT_OAMF5 0x4
#define TPD_END2END_OAMF5 0x5
#define TPD_RMCELL 0x6
#define TPD_CELLTYPE(x) (x<<3)
#define TPD_EOS (1<<2)
#define TPD_CLP (1<<1)
#define TPD_INT (1<<0)
#define TPD_LST (1<<31)
/* table 4.3 serial eeprom information */
#define PROD_ID 0x08 /* char[] */
#define PROD_ID_LEN 30
#define HW_REV 0x26 /* char[] */
#define M_SN 0x3a /* integer */
#define MEDIA 0x3e /* integer */
#define HE155MM 0x26
#define HE622MM 0x27
#define HE155SM 0x46
#define HE622SM 0x47
#define MAC_ADDR 0x42 /* char[] */
#define CS_LOW 0x0
#define CS_HIGH ID_CS /* HOST_CNTL_ID_PROM_SEL */
#define CLK_LOW 0x0
#define CLK_HIGH ID_CLOCK /* HOST_CNTL_ID_PROM_CLOCK */
#define SI_HIGH ID_DIN /* HOST_CNTL_ID_PROM_DATA_IN */
#define EEPROM_DELAY 400 /* microseconds */
#endif /* _HE_H_ */

2938
drivers/atm/horizon.c Normal file

File diff suppressed because it is too large Load diff

507
drivers/atm/horizon.h Normal file
View file

@ -0,0 +1,507 @@
/*
Madge Horizon ATM Adapter driver.
Copyright (C) 1995-1999 Madge Networks Ltd.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
The GNU GPL is contained in /usr/doc/copyright/GPL on a Debian
system and in the file COPYING in the Linux kernel source.
*/
/*
IMPORTANT NOTE: Madge Networks no longer makes the adapters
supported by this driver and makes no commitment to maintain it.
*/
/* too many macros - change to inline functions */
#ifndef DRIVER_ATM_HORIZON_H
#define DRIVER_ATM_HORIZON_H
#ifdef CONFIG_ATM_HORIZON_DEBUG
#define DEBUG_HORIZON
#endif
#define DEV_LABEL "hrz"
#ifndef PCI_VENDOR_ID_MADGE
#define PCI_VENDOR_ID_MADGE 0x10B6
#endif
#ifndef PCI_DEVICE_ID_MADGE_HORIZON
#define PCI_DEVICE_ID_MADGE_HORIZON 0x1000
#endif
// diagnostic output
#define PRINTK(severity,format,args...) \
printk(severity DEV_LABEL ": " format "\n" , ## args)
#ifdef DEBUG_HORIZON
#define DBG_ERR 0x0001
#define DBG_WARN 0x0002
#define DBG_INFO 0x0004
#define DBG_VCC 0x0008
#define DBG_QOS 0x0010
#define DBG_TX 0x0020
#define DBG_RX 0x0040
#define DBG_SKB 0x0080
#define DBG_IRQ 0x0100
#define DBG_FLOW 0x0200
#define DBG_BUS 0x0400
#define DBG_REGS 0x0800
#define DBG_DATA 0x1000
#define DBG_MASK 0x1fff
/* the ## prevents the annoying double expansion of the macro arguments */
/* KERN_INFO is used since KERN_DEBUG often does not make it to the console */
#define PRINTDB(bits,format,args...) \
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format , ## args) : 1 )
#define PRINTDM(bits,format,args...) \
( (debug & (bits)) ? printk (format , ## args) : 1 )
#define PRINTDE(bits,format,args...) \
( (debug & (bits)) ? printk (format "\n" , ## args) : 1 )
#define PRINTD(bits,format,args...) \
( (debug & (bits)) ? printk (KERN_INFO DEV_LABEL ": " format "\n" , ## args) : 1 )
#else
#define PRINTD(bits,format,args...)
#define PRINTDB(bits,format,args...)
#define PRINTDM(bits,format,args...)
#define PRINTDE(bits,format,args...)
#endif
#define PRINTDD(sec,fmt,args...)
#define PRINTDDB(sec,fmt,args...)
#define PRINTDDM(sec,fmt,args...)
#define PRINTDDE(sec,fmt,args...)
// fixed constants
#define SPARE_BUFFER_POOL_SIZE MAX_VCS
#define HRZ_MAX_VPI 4
#define MIN_PCI_LATENCY 48 // 24 IS TOO SMALL
/* Horizon specific bits */
/* Register offsets */
#define HRZ_IO_EXTENT 0x80
#define DATA_PORT_OFF 0x00
#define TX_CHANNEL_PORT_OFF 0x04
#define TX_DESCRIPTOR_PORT_OFF 0x08
#define MEMORY_PORT_OFF 0x0C
#define MEM_WR_ADDR_REG_OFF 0x14
#define MEM_RD_ADDR_REG_OFF 0x18
#define CONTROL_0_REG 0x1C
#define INT_SOURCE_REG_OFF 0x20
#define INT_ENABLE_REG_OFF 0x24
#define MASTER_RX_ADDR_REG_OFF 0x28
#define MASTER_RX_COUNT_REG_OFF 0x2C
#define MASTER_TX_ADDR_REG_OFF 0x30
#define MASTER_TX_COUNT_REG_OFF 0x34
#define TX_DESCRIPTOR_REG_OFF 0x38
#define TX_CHANNEL_CONFIG_COMMAND_OFF 0x40
#define TX_CHANNEL_CONFIG_DATA_OFF 0x44
#define TX_FREE_BUFFER_COUNT_OFF 0x48
#define RX_FREE_BUFFER_COUNT_OFF 0x4C
#define TX_CONFIG_OFF 0x50
#define TX_STATUS_OFF 0x54
#define RX_CONFIG_OFF 0x58
#define RX_LINE_CONFIG_OFF 0x5C
#define RX_QUEUE_RD_PTR_OFF 0x60
#define RX_QUEUE_WR_PTR_OFF 0x64
#define MAX_AAL5_CELL_COUNT_OFF 0x68
#define RX_CHANNEL_PORT_OFF 0x6C
#define TX_CELL_COUNT_OFF 0x70
#define RX_CELL_COUNT_OFF 0x74
#define HEC_ERROR_COUNT_OFF 0x78
#define UNASSIGNED_CELL_COUNT_OFF 0x7C
/* Register bit definitions */
/* Control 0 register */
#define SEEPROM_DO 0x00000001
#define SEEPROM_DI 0x00000002
#define SEEPROM_SK 0x00000004
#define SEEPROM_CS 0x00000008
#define DEBUG_BIT_0 0x00000010
#define DEBUG_BIT_1 0x00000020
#define DEBUG_BIT_2 0x00000040
// RESERVED 0x00000080
#define DEBUG_BIT_0_OE 0x00000100
#define DEBUG_BIT_1_OE 0x00000200
#define DEBUG_BIT_2_OE 0x00000400
// RESERVED 0x00000800
#define DEBUG_BIT_0_STATE 0x00001000
#define DEBUG_BIT_1_STATE 0x00002000
#define DEBUG_BIT_2_STATE 0x00004000
// RESERVED 0x00008000
#define GENERAL_BIT_0 0x00010000
#define GENERAL_BIT_1 0x00020000
#define GENERAL_BIT_2 0x00040000
#define GENERAL_BIT_3 0x00080000
#define RESET_HORIZON 0x00100000
#define RESET_ATM 0x00200000
#define RESET_RX 0x00400000
#define RESET_TX 0x00800000
#define RESET_HOST 0x01000000
// RESERVED 0x02000000
#define TARGET_RETRY_DISABLE 0x04000000
#define ATM_LAYER_SELECT 0x08000000
#define ATM_LAYER_STATUS 0x10000000
// RESERVED 0xE0000000
/* Interrupt source and enable registers */
#define RX_DATA_AV 0x00000001
#define RX_DISABLED 0x00000002
#define TIMING_MARKER 0x00000004
#define FORCED 0x00000008
#define RX_BUS_MASTER_COMPLETE 0x00000010
#define TX_BUS_MASTER_COMPLETE 0x00000020
#define ABR_TX_CELL_COUNT_INT 0x00000040
#define DEBUG_INT 0x00000080
// RESERVED 0xFFFFFF00
/* PIO and Bus Mastering */
#define MAX_PIO_COUNT 0x000000ff // 255 - make tunable?
// 8188 is a hard limit for bus mastering
#define MAX_TRANSFER_COUNT 0x00001ffc // 8188
#define MASTER_TX_AUTO_APPEND_DESC 0x80000000
/* TX channel config command port */
#define PCR_TIMER_ACCESS 0x0000
#define SCR_TIMER_ACCESS 0x0001
#define BUCKET_CAPACITY_ACCESS 0x0002
#define BUCKET_FULLNESS_ACCESS 0x0003
#define RATE_TYPE_ACCESS 0x0004
// UNUSED 0x00F8
#define TX_CHANNEL_CONFIG_MULT 0x0100
// UNUSED 0xF800
#define BUCKET_MAX_SIZE 0x003f
/* TX channel config data port */
#define CLOCK_SELECT_SHIFT 4
#define CLOCK_DISABLE 0x00ff
#define IDLE_RATE_TYPE 0x0
#define ABR_RATE_TYPE 0x1
#define VBR_RATE_TYPE 0x2
#define CBR_RATE_TYPE 0x3
/* TX config register */
#define DRVR_DRVRBAR_ENABLE 0x0001
#define TXCLK_MUX_SELECT_RCLK 0x0002
#define TRANSMIT_TIMING_MARKER 0x0004
#define LOOPBACK_TIMING_MARKER 0x0008
#define TX_TEST_MODE_16MHz 0x0000
#define TX_TEST_MODE_8MHz 0x0010
#define TX_TEST_MODE_5_33MHz 0x0020
#define TX_TEST_MODE_4MHz 0x0030
#define TX_TEST_MODE_3_2MHz 0x0040
#define TX_TEST_MODE_2_66MHz 0x0050
#define TX_TEST_MODE_2_29MHz 0x0060
#define TX_NORMAL_OPERATION 0x0070
#define ABR_ROUND_ROBIN 0x0080
/* TX status register */
#define IDLE_CHANNELS_MASK 0x00FF
#define ABR_CELL_COUNT_REACHED_MULT 0x0100
#define ABR_CELL_COUNT_REACHED_MASK 0xFF
/* RX config register */
#define NON_USER_CELLS_IN_ONE_CHANNEL 0x0008
#define RX_ENABLE 0x0010
#define IGNORE_UNUSED_VPI_VCI_BITS_SET 0x0000
#define NON_USER_UNUSED_VPI_VCI_BITS_SET 0x0020
#define DISCARD_UNUSED_VPI_VCI_BITS_SET 0x0040
/* RX line config register */
#define SIGNAL_LOSS 0x0001
#define FREQUENCY_DETECT_ERROR 0x0002
#define LOCK_DETECT_ERROR 0x0004
#define SELECT_INTERNAL_LOOPBACK 0x0008
#define LOCK_DETECT_ENABLE 0x0010
#define FREQUENCY_DETECT_ENABLE 0x0020
#define USER_FRAQ 0x0040
#define GXTALOUT_SELECT_DIV4 0x0080
#define GXTALOUT_SELECT_NO_GATING 0x0100
#define TIMING_MARKER_RECEIVED 0x0200
/* RX channel port */
#define RX_CHANNEL_MASK 0x03FF
// UNUSED 0x3C00
#define FLUSH_CHANNEL 0x4000
#define RX_CHANNEL_UPDATE_IN_PROGRESS 0x8000
/* Receive queue entry */
#define RX_Q_ENTRY_LENGTH_MASK 0x0000FFFF
#define RX_Q_ENTRY_CHANNEL_SHIFT 16
#define SIMONS_DODGEY_MARKER 0x08000000
#define RX_CONGESTION_EXPERIENCED 0x10000000
#define RX_CRC_10_OK 0x20000000
#define RX_CRC_32_OK 0x40000000
#define RX_COMPLETE_FRAME 0x80000000
/* Offsets and constants for use with the buffer memory */
/* Buffer pointers and channel types */
#define BUFFER_PTR_MASK 0x0000FFFF
#define RX_INT_THRESHOLD_MULT 0x00010000
#define RX_INT_THRESHOLD_MASK 0x07FF
#define INT_EVERY_N_CELLS 0x08000000
#define CONGESTION_EXPERIENCED 0x10000000
#define FIRST_CELL_OF_AAL5_FRAME 0x20000000
#define CHANNEL_TYPE_AAL5 0x00000000
#define CHANNEL_TYPE_RAW_CELLS 0x40000000
#define CHANNEL_TYPE_AAL3_4 0x80000000
/* Buffer status stuff */
#define BUFF_STATUS_MASK 0x00030000
#define BUFF_STATUS_EMPTY 0x00000000
#define BUFF_STATUS_CELL_AV 0x00010000
#define BUFF_STATUS_LAST_CELL_AV 0x00020000
/* Transmit channel stuff */
/* Receive channel stuff */
#define RX_CHANNEL_DISABLED 0x00000000
#define RX_CHANNEL_IDLE 0x00000001
/* General things */
#define INITIAL_CRC 0xFFFFFFFF
// A Horizon u32, a byte! Really nasty. Horizon pointers are (32 bit)
// word addresses and so standard C pointer operations break (as they
// assume byte addresses); so we pretend that Horizon words (and word
// pointers) are bytes (and byte pointers) for the purposes of having
// a memory map that works.
typedef u8 HDW;
typedef struct cell_buf {
HDW payload[12];
HDW next;
HDW cell_count; // AAL5 rx bufs
HDW res;
union {
HDW partial_crc; // AAL5 rx bufs
HDW cell_header; // RAW bufs
} u;
} cell_buf;
typedef struct tx_ch_desc {
HDW rd_buf_type;
HDW wr_buf_type;
HDW partial_crc;
HDW cell_header;
} tx_ch_desc;
typedef struct rx_ch_desc {
HDW wr_buf_type;
HDW rd_buf_type;
} rx_ch_desc;
typedef struct rx_q_entry {
HDW entry;
} rx_q_entry;
#define TX_CHANS 8
#define RX_CHANS 1024
#define RX_QS 1024
#define MAX_VCS RX_CHANS
/* Horizon buffer memory map */
// TX Channel Descriptors 2
// TX Initial Buffers 8 // TX_CHANS
#define BUFN1_SIZE 118 // (126 - TX_CHANS)
// RX/TX Start/End Buffers 4
#define BUFN2_SIZE 124
// RX Queue Entries 64
#define BUFN3_SIZE 192
// RX Channel Descriptors 128
#define BUFN4_SIZE 1408
// TOTAL cell_buff chunks 2048
// cell_buf bufs[2048];
// HDW dws[32768];
typedef struct MEMMAP {
tx_ch_desc tx_descs[TX_CHANS]; // 8 * 4 = 32 , 0x0020
cell_buf inittxbufs[TX_CHANS]; // these are really
cell_buf bufn1[BUFN1_SIZE]; // part of this pool
cell_buf txfreebufstart;
cell_buf txfreebufend;
cell_buf rxfreebufstart;
cell_buf rxfreebufend; // 8+118+1+1+1+1+124 = 254
cell_buf bufn2[BUFN2_SIZE]; // 16 * 254 = 4064 , 0x1000
rx_q_entry rx_q_entries[RX_QS]; // 1 * 1024 = 1024 , 0x1400
cell_buf bufn3[BUFN3_SIZE]; // 16 * 192 = 3072 , 0x2000
rx_ch_desc rx_descs[MAX_VCS]; // 2 * 1024 = 2048 , 0x2800
cell_buf bufn4[BUFN4_SIZE]; // 16 * 1408 = 22528 , 0x8000
} MEMMAP;
#define memmap ((MEMMAP *)0)
/* end horizon specific bits */
typedef enum {
aal0,
aal34,
aal5
} hrz_aal;
typedef enum {
tx_busy,
rx_busy,
ultra
} hrz_flags;
// a single struct pointed to by atm_vcc->dev_data
typedef struct {
unsigned int tx_rate;
unsigned int rx_rate;
u16 channel;
u16 tx_xbr_bits;
u16 tx_pcr_bits;
#if 0
u16 tx_scr_bits;
u16 tx_bucket_bits;
#endif
hrz_aal aal;
} hrz_vcc;
struct hrz_dev {
u32 iobase;
u32 * membase;
struct sk_buff * rx_skb; // skb being RXed
unsigned int rx_bytes; // bytes remaining to RX within region
void * rx_addr; // addr to send bytes to (for PIO)
unsigned int rx_channel; // channel that the skb is going out on
struct sk_buff * tx_skb; // skb being TXed
unsigned int tx_bytes; // bytes remaining to TX within region
void * tx_addr; // addr to send bytes from (for PIO)
struct iovec * tx_iovec; // remaining regions
unsigned int tx_regions; // number of remaining regions
spinlock_t mem_lock;
wait_queue_head_t tx_queue;
u8 irq;
unsigned long flags;
u8 tx_last;
u8 tx_idle;
rx_q_entry * rx_q_reset;
rx_q_entry * rx_q_entry;
rx_q_entry * rx_q_wrap;
struct atm_dev * atm_dev;
u32 last_vc;
int noof_spare_buffers;
u16 spare_buffers[SPARE_BUFFER_POOL_SIZE];
u16 tx_channel_record[TX_CHANS];
// this is what we follow when we get incoming data
u32 txer[MAX_VCS/32];
struct atm_vcc * rxer[MAX_VCS];
// cell rate allocation
spinlock_t rate_lock;
unsigned int rx_avail;
unsigned int tx_avail;
// dev stats
unsigned long tx_cell_count;
unsigned long rx_cell_count;
unsigned long hec_error_count;
unsigned long unassigned_cell_count;
struct pci_dev * pci_dev;
struct timer_list housekeeping;
};
typedef struct hrz_dev hrz_dev;
/* macros for use later */
#define BUF_PTR(cbptr) ((cbptr) - (cell_buf *) 0)
#define INTERESTING_INTERRUPTS \
(RX_DATA_AV | RX_DISABLED | TX_BUS_MASTER_COMPLETE | RX_BUS_MASTER_COMPLETE)
// 190 cells by default (192 TX buffers - 2 elbow room, see docs)
#define TX_AAL5_LIMIT (190*ATM_CELL_PAYLOAD-ATM_AAL5_TRAILER) // 9112
// Have enough RX buffers (unless we allow other buffer splits)
#define RX_AAL5_LIMIT ATM_MAX_AAL5_PDU
/* multi-statement macro protector */
#define DW(x) do{ x } while(0)
#define HRZ_DEV(atm_dev) ((hrz_dev *) (atm_dev)->dev_data)
#define HRZ_VCC(atm_vcc) ((hrz_vcc *) (atm_vcc)->dev_data)
/* Turn the LEDs on and off */
// The LEDs bits are upside down in that setting the bit in the debug
// register will turn the appropriate LED off.
#define YELLOW_LED DEBUG_BIT_0
#define GREEN_LED DEBUG_BIT_1
#define YELLOW_LED_OE DEBUG_BIT_0_OE
#define GREEN_LED_OE DEBUG_BIT_1_OE
#define GREEN_LED_OFF(dev) \
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) | GREEN_LED)
#define GREEN_LED_ON(dev) \
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) &~ GREEN_LED)
#define YELLOW_LED_OFF(dev) \
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) | YELLOW_LED)
#define YELLOW_LED_ON(dev) \
wr_regl (dev, CONTROL_0_REG, rd_regl (dev, CONTROL_0_REG) &~ YELLOW_LED)
typedef enum {
round_up,
round_down,
round_nearest
} rounding;
#endif /* DRIVER_ATM_HORIZON_H */

378
drivers/atm/idt77105.c Normal file
View file

@ -0,0 +1,378 @@
/* drivers/atm/idt77105.c - IDT77105 (PHY) driver */
/* Written 1999 by Greg Banks, NEC Australia <gnb@linuxfan.com>. Based on suni.c */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/atm_idt77105.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include "idt77105.h"
#undef GENERAL_DEBUG
#ifdef GENERAL_DEBUG
#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
#else
#define DPRINTK(format,args...)
#endif
struct idt77105_priv {
struct idt77105_stats stats; /* link diagnostics */
struct atm_dev *dev; /* device back-pointer */
struct idt77105_priv *next;
int loop_mode;
unsigned char old_mcr; /* storage of MCR reg while signal lost */
};
static DEFINE_SPINLOCK(idt77105_priv_lock);
#define PRIV(dev) ((struct idt77105_priv *) dev->phy_data)
#define PUT(val,reg) dev->ops->phy_put(dev,val,IDT77105_##reg)
#define GET(reg) dev->ops->phy_get(dev,IDT77105_##reg)
static void idt77105_stats_timer_func(unsigned long);
static void idt77105_restart_timer_func(unsigned long);
static DEFINE_TIMER(stats_timer, idt77105_stats_timer_func, 0, 0);
static DEFINE_TIMER(restart_timer, idt77105_restart_timer_func, 0, 0);
static int start_timer = 1;
static struct idt77105_priv *idt77105_all = NULL;
/*
* Retrieve the value of one of the IDT77105's counters.
* `counter' is one of the IDT77105_CTRSEL_* constants.
*/
static u16 get_counter(struct atm_dev *dev, int counter)
{
u16 val;
/* write the counter bit into PHY register 6 */
PUT(counter, CTRSEL);
/* read the low 8 bits from register 4 */
val = GET(CTRLO);
/* read the high 8 bits from register 5 */
val |= GET(CTRHI)<<8;
return val;
}
/*
* Timer function called every second to gather statistics
* from the 77105. This is done because the h/w registers
* will overflow if not read at least once per second. The
* kernel's stats are much higher precision. Also, having
* a separate copy of the stats allows implementation of
* an ioctl which gathers the stats *without* zero'ing them.
*/
static void idt77105_stats_timer_func(unsigned long dummy)
{
struct idt77105_priv *walk;
struct atm_dev *dev;
struct idt77105_stats *stats;
DPRINTK("IDT77105 gathering statistics\n");
for (walk = idt77105_all; walk; walk = walk->next) {
dev = walk->dev;
stats = &walk->stats;
stats->symbol_errors += get_counter(dev, IDT77105_CTRSEL_SEC);
stats->tx_cells += get_counter(dev, IDT77105_CTRSEL_TCC);
stats->rx_cells += get_counter(dev, IDT77105_CTRSEL_RCC);
stats->rx_hec_errors += get_counter(dev, IDT77105_CTRSEL_RHEC);
}
if (!start_timer) mod_timer(&stats_timer,jiffies+IDT77105_STATS_TIMER_PERIOD);
}
/*
* A separate timer func which handles restarting PHY chips which
* have had the cable re-inserted after being pulled out. This is
* done by polling the Good Signal Bit in the Interrupt Status
* register every 5 seconds. The other technique (checking Good
* Signal Bit in the interrupt handler) cannot be used because PHY
* interrupts need to be disabled when the cable is pulled out
* to avoid lots of spurious cell error interrupts.
*/
static void idt77105_restart_timer_func(unsigned long dummy)
{
struct idt77105_priv *walk;
struct atm_dev *dev;
unsigned char istat;
DPRINTK("IDT77105 checking for cable re-insertion\n");
for (walk = idt77105_all; walk; walk = walk->next) {
dev = walk->dev;
if (dev->signal != ATM_PHY_SIG_LOST)
continue;
istat = GET(ISTAT); /* side effect: clears all interrupt status bits */
if (istat & IDT77105_ISTAT_GOODSIG) {
/* Found signal again */
atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND);
printk(KERN_NOTICE "%s(itf %d): signal detected again\n",
dev->type,dev->number);
/* flush the receive FIFO */
PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG);
/* re-enable interrupts */
PUT( walk->old_mcr ,MCR);
}
}
if (!start_timer) mod_timer(&restart_timer,jiffies+IDT77105_RESTART_TIMER_PERIOD);
}
static int fetch_stats(struct atm_dev *dev,struct idt77105_stats __user *arg,int zero)
{
unsigned long flags;
struct idt77105_stats stats;
spin_lock_irqsave(&idt77105_priv_lock, flags);
memcpy(&stats, &PRIV(dev)->stats, sizeof(struct idt77105_stats));
if (zero)
memset(&PRIV(dev)->stats, 0, sizeof(struct idt77105_stats));
spin_unlock_irqrestore(&idt77105_priv_lock, flags);
if (arg == NULL)
return 0;
return copy_to_user(arg, &stats,
sizeof(struct idt77105_stats)) ? -EFAULT : 0;
}
static int set_loopback(struct atm_dev *dev,int mode)
{
int diag;
diag = GET(DIAG) & ~IDT77105_DIAG_LCMASK;
switch (mode) {
case ATM_LM_NONE:
break;
case ATM_LM_LOC_ATM:
diag |= IDT77105_DIAG_LC_PHY_LOOPBACK;
break;
case ATM_LM_RMT_ATM:
diag |= IDT77105_DIAG_LC_LINE_LOOPBACK;
break;
default:
return -EINVAL;
}
PUT(diag,DIAG);
printk(KERN_NOTICE "%s(%d) Loopback mode is: %s\n", dev->type,
dev->number,
(mode == ATM_LM_NONE ? "NONE" :
(mode == ATM_LM_LOC_ATM ? "DIAG (local)" :
(mode == IDT77105_DIAG_LC_LINE_LOOPBACK ? "LOOP (remote)" :
"unknown")))
);
PRIV(dev)->loop_mode = mode;
return 0;
}
static int idt77105_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
printk(KERN_NOTICE "%s(%d) idt77105_ioctl() called\n",dev->type,dev->number);
switch (cmd) {
case IDT77105_GETSTATZ:
if (!capable(CAP_NET_ADMIN)) return -EPERM;
/* fall through */
case IDT77105_GETSTAT:
return fetch_stats(dev, arg, cmd == IDT77105_GETSTATZ);
case ATM_SETLOOP:
return set_loopback(dev,(int)(unsigned long) arg);
case ATM_GETLOOP:
return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-EFAULT : 0;
case ATM_QUERYLOOP:
return put_user(ATM_LM_LOC_ATM | ATM_LM_RMT_ATM,
(int __user *) arg) ? -EFAULT : 0;
default:
return -ENOIOCTLCMD;
}
}
static void idt77105_int(struct atm_dev *dev)
{
unsigned char istat;
istat = GET(ISTAT); /* side effect: clears all interrupt status bits */
DPRINTK("IDT77105 generated an interrupt, istat=%02x\n", (unsigned)istat);
if (istat & IDT77105_ISTAT_RSCC) {
/* Rx Signal Condition Change - line went up or down */
if (istat & IDT77105_ISTAT_GOODSIG) { /* signal detected again */
/* This should not happen (restart timer does it) but JIC */
atm_dev_signal_change(dev, ATM_PHY_SIG_FOUND);
} else { /* signal lost */
/*
* Disable interrupts and stop all transmission and
* reception - the restart timer will restore these.
*/
PRIV(dev)->old_mcr = GET(MCR);
PUT(
(PRIV(dev)->old_mcr|
IDT77105_MCR_DREC|
IDT77105_MCR_DRIC|
IDT77105_MCR_HALTTX
) & ~IDT77105_MCR_EIP, MCR);
atm_dev_signal_change(dev, ATM_PHY_SIG_LOST);
printk(KERN_NOTICE "%s(itf %d): signal lost\n",
dev->type,dev->number);
}
}
if (istat & IDT77105_ISTAT_RFO) {
/* Rx FIFO Overrun -- perform a FIFO flush */
PUT( GET(DIAG) | IDT77105_DIAG_RFLUSH, DIAG);
printk(KERN_NOTICE "%s(itf %d): receive FIFO overrun\n",
dev->type,dev->number);
}
#ifdef GENERAL_DEBUG
if (istat & (IDT77105_ISTAT_HECERR | IDT77105_ISTAT_SCR |
IDT77105_ISTAT_RSE)) {
/* normally don't care - just report in stats */
printk(KERN_NOTICE "%s(itf %d): received cell with error\n",
dev->type,dev->number);
}
#endif
}
static int idt77105_start(struct atm_dev *dev)
{
unsigned long flags;
if (!(dev->dev_data = kmalloc(sizeof(struct idt77105_priv),GFP_KERNEL)))
return -ENOMEM;
PRIV(dev)->dev = dev;
spin_lock_irqsave(&idt77105_priv_lock, flags);
PRIV(dev)->next = idt77105_all;
idt77105_all = PRIV(dev);
spin_unlock_irqrestore(&idt77105_priv_lock, flags);
memset(&PRIV(dev)->stats,0,sizeof(struct idt77105_stats));
/* initialise dev->signal from Good Signal Bit */
atm_dev_signal_change(dev,
GET(ISTAT) & IDT77105_ISTAT_GOODSIG ?
ATM_PHY_SIG_FOUND : ATM_PHY_SIG_LOST);
if (dev->signal == ATM_PHY_SIG_LOST)
printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type,
dev->number);
/* initialise loop mode from hardware */
switch ( GET(DIAG) & IDT77105_DIAG_LCMASK ) {
case IDT77105_DIAG_LC_NORMAL:
PRIV(dev)->loop_mode = ATM_LM_NONE;
break;
case IDT77105_DIAG_LC_PHY_LOOPBACK:
PRIV(dev)->loop_mode = ATM_LM_LOC_ATM;
break;
case IDT77105_DIAG_LC_LINE_LOOPBACK:
PRIV(dev)->loop_mode = ATM_LM_RMT_ATM;
break;
}
/* enable interrupts, e.g. on loss of signal */
PRIV(dev)->old_mcr = GET(MCR);
if (dev->signal == ATM_PHY_SIG_FOUND) {
PRIV(dev)->old_mcr |= IDT77105_MCR_EIP;
PUT(PRIV(dev)->old_mcr, MCR);
}
idt77105_stats_timer_func(0); /* clear 77105 counters */
(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
spin_lock_irqsave(&idt77105_priv_lock, flags);
if (start_timer) {
start_timer = 0;
init_timer(&stats_timer);
stats_timer.expires = jiffies+IDT77105_STATS_TIMER_PERIOD;
stats_timer.function = idt77105_stats_timer_func;
add_timer(&stats_timer);
init_timer(&restart_timer);
restart_timer.expires = jiffies+IDT77105_RESTART_TIMER_PERIOD;
restart_timer.function = idt77105_restart_timer_func;
add_timer(&restart_timer);
}
spin_unlock_irqrestore(&idt77105_priv_lock, flags);
return 0;
}
static int idt77105_stop(struct atm_dev *dev)
{
struct idt77105_priv *walk, *prev;
DPRINTK("%s(itf %d): stopping IDT77105\n",dev->type,dev->number);
/* disable interrupts */
PUT( GET(MCR) & ~IDT77105_MCR_EIP, MCR );
/* detach private struct from atm_dev & free */
for (prev = NULL, walk = idt77105_all ;
walk != NULL;
prev = walk, walk = walk->next) {
if (walk->dev == dev) {
if (prev != NULL)
prev->next = walk->next;
else
idt77105_all = walk->next;
dev->phy = NULL;
dev->dev_data = NULL;
kfree(walk);
break;
}
}
return 0;
}
static const struct atmphy_ops idt77105_ops = {
.start = idt77105_start,
.ioctl = idt77105_ioctl,
.interrupt = idt77105_int,
.stop = idt77105_stop,
};
int idt77105_init(struct atm_dev *dev)
{
dev->phy = &idt77105_ops;
return 0;
}
EXPORT_SYMBOL(idt77105_init);
static void __exit idt77105_exit(void)
{
/* turn off timers */
del_timer_sync(&stats_timer);
del_timer_sync(&restart_timer);
}
module_exit(idt77105_exit);
MODULE_LICENSE("GPL");

91
drivers/atm/idt77105.h Normal file
View file

@ -0,0 +1,91 @@
/* drivers/atm/idt77105.h - IDT77105 (PHY) declarations */
/* Written 1999 by Greg Banks, NEC Australia <gnb@linuxfan.com>. Based on suni.h */
#ifndef DRIVER_ATM_IDT77105_H
#define DRIVER_ATM_IDT77105_H
#include <linux/atmdev.h>
#include <linux/atmioc.h>
/* IDT77105 registers */
#define IDT77105_MCR 0x0 /* Master Control Register */
#define IDT77105_ISTAT 0x1 /* Interrupt Status */
#define IDT77105_DIAG 0x2 /* Diagnostic Control */
#define IDT77105_LEDHEC 0x3 /* LED Driver & HEC Status/Control */
#define IDT77105_CTRLO 0x4 /* Low Byte Counter Register */
#define IDT77105_CTRHI 0x5 /* High Byte Counter Register */
#define IDT77105_CTRSEL 0x6 /* Counter Register Read Select */
/* IDT77105 register values */
/* MCR */
#define IDT77105_MCR_UPLO 0x80 /* R/W, User Prog'le Output Latch */
#define IDT77105_MCR_DREC 0x40 /* R/W, Discard Receive Error Cells */
#define IDT77105_MCR_ECEIO 0x20 /* R/W, Enable Cell Error Interrupts
* Only */
#define IDT77105_MCR_TDPC 0x10 /* R/W, Transmit Data Parity Check */
#define IDT77105_MCR_DRIC 0x08 /* R/W, Discard Received Idle Cells */
#define IDT77105_MCR_HALTTX 0x04 /* R/W, Halt Tx */
#define IDT77105_MCR_UMODE 0x02 /* R/W, Utopia (cell/byte) Mode */
#define IDT77105_MCR_EIP 0x01 /* R/W, Enable Interrupt Pin */
/* ISTAT */
#define IDT77105_ISTAT_GOODSIG 0x40 /* R, Good Signal Bit */
#define IDT77105_ISTAT_HECERR 0x20 /* sticky, HEC Error*/
#define IDT77105_ISTAT_SCR 0x10 /* sticky, Short Cell Received */
#define IDT77105_ISTAT_TPE 0x08 /* sticky, Transmit Parity Error */
#define IDT77105_ISTAT_RSCC 0x04 /* sticky, Rx Signal Condition Change */
#define IDT77105_ISTAT_RSE 0x02 /* sticky, Rx Symbol Error */
#define IDT77105_ISTAT_RFO 0x01 /* sticky, Rx FIFO Overrun */
/* DIAG */
#define IDT77105_DIAG_FTD 0x80 /* R/W, Force TxClav deassert */
#define IDT77105_DIAG_ROS 0x40 /* R/W, RxClav operation select */
#define IDT77105_DIAG_MPCS 0x20 /* R/W, Multi-PHY config'n select */
#define IDT77105_DIAG_RFLUSH 0x10 /* R/W, clear receive FIFO */
#define IDT77105_DIAG_ITPE 0x08 /* R/W, Insert Tx payload error */
#define IDT77105_DIAG_ITHE 0x04 /* R/W, Insert Tx HEC error */
#define IDT77105_DIAG_UMODE 0x02 /* R/W, Utopia (cell/byte) Mode */
#define IDT77105_DIAG_LCMASK 0x03 /* R/W, Loopback Control */
#define IDT77105_DIAG_LC_NORMAL 0x00 /* Receive from network */
#define IDT77105_DIAG_LC_PHY_LOOPBACK 0x02
#define IDT77105_DIAG_LC_LINE_LOOPBACK 0x03
/* LEDHEC */
#define IDT77105_LEDHEC_DRHC 0x40 /* R/W, Disable Rx HEC check */
#define IDT77105_LEDHEC_DTHC 0x20 /* R/W, Disable Tx HEC calculation */
#define IDT77105_LEDHEC_RPWMASK 0x18 /* R/W, RxRef pulse width select */
#define IDT77105_LEDHEC_TFS 0x04 /* R, Tx FIFO Status (1=empty) */
#define IDT77105_LEDHEC_TLS 0x02 /* R, Tx LED Status (1=lit) */
#define IDT77105_LEDHEC_RLS 0x01 /* R, Rx LED Status (1=lit) */
#define IDT77105_LEDHEC_RPW_1 0x00 /* RxRef active for 1 RxClk cycle */
#define IDT77105_LEDHEC_RPW_2 0x08 /* RxRef active for 2 RxClk cycle */
#define IDT77105_LEDHEC_RPW_4 0x10 /* RxRef active for 4 RxClk cycle */
#define IDT77105_LEDHEC_RPW_8 0x18 /* RxRef active for 8 RxClk cycle */
/* CTRSEL */
#define IDT77105_CTRSEL_SEC 0x08 /* W, Symbol Error Counter */
#define IDT77105_CTRSEL_TCC 0x04 /* W, Tx Cell Counter */
#define IDT77105_CTRSEL_RCC 0x02 /* W, Rx Cell Counter */
#define IDT77105_CTRSEL_RHEC 0x01 /* W, Rx HEC Error Counter */
#ifdef __KERNEL__
int idt77105_init(struct atm_dev *dev);
#endif
/*
* Tunable parameters
*/
/* Time between samples of the hardware cell counters. Should be <= 1 sec */
#define IDT77105_STATS_TIMER_PERIOD (HZ)
/* Time between checks to see if the signal has been found again */
#define IDT77105_RESTART_TIMER_PERIOD (5 * HZ)
#endif

3797
drivers/atm/idt77252.c Normal file

File diff suppressed because it is too large Load diff

813
drivers/atm/idt77252.h Normal file
View file

@ -0,0 +1,813 @@
/*******************************************************************
*
* Copyright (c) 2000 ATecoM GmbH
*
* The author may be reached at ecd@atecom.com.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.
*
*******************************************************************/
#ifndef _IDT77252_H
#define _IDT77252_H 1
#include <linux/ptrace.h>
#include <linux/skbuff.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
/*****************************************************************************/
/* */
/* Makros */
/* */
/*****************************************************************************/
#define VPCI2VC(card, vpi, vci) \
(((vpi) << card->vcibits) | ((vci) & card->vcimask))
/*****************************************************************************/
/* */
/* DEBUGGING definitions */
/* */
/*****************************************************************************/
#define DBG_RAW_CELL 0x00000400
#define DBG_TINY 0x00000200
#define DBG_GENERAL 0x00000100
#define DBG_XGENERAL 0x00000080
#define DBG_INIT 0x00000040
#define DBG_DEINIT 0x00000020
#define DBG_INTERRUPT 0x00000010
#define DBG_OPEN_CONN 0x00000008
#define DBG_CLOSE_CONN 0x00000004
#define DBG_RX_DATA 0x00000002
#define DBG_TX_DATA 0x00000001
#ifdef CONFIG_ATM_IDT77252_DEBUG
#define CPRINTK(args...) do { if (debug & DBG_CLOSE_CONN) printk(args); } while(0)
#define OPRINTK(args...) do { if (debug & DBG_OPEN_CONN) printk(args); } while(0)
#define IPRINTK(args...) do { if (debug & DBG_INIT) printk(args); } while(0)
#define INTPRINTK(args...) do { if (debug & DBG_INTERRUPT) printk(args); } while(0)
#define DIPRINTK(args...) do { if (debug & DBG_DEINIT) printk(args); } while(0)
#define TXPRINTK(args...) do { if (debug & DBG_TX_DATA) printk(args); } while(0)
#define RXPRINTK(args...) do { if (debug & DBG_RX_DATA) printk(args); } while(0)
#define XPRINTK(args...) do { if (debug & DBG_XGENERAL) printk(args); } while(0)
#define DPRINTK(args...) do { if (debug & DBG_GENERAL) printk(args); } while(0)
#define NPRINTK(args...) do { if (debug & DBG_TINY) printk(args); } while(0)
#define RPRINTK(args...) do { if (debug & DBG_RAW_CELL) printk(args); } while(0)
#else
#define CPRINTK(args...) do { } while(0)
#define OPRINTK(args...) do { } while(0)
#define IPRINTK(args...) do { } while(0)
#define INTPRINTK(args...) do { } while(0)
#define DIPRINTK(args...) do { } while(0)
#define TXPRINTK(args...) do { } while(0)
#define RXPRINTK(args...) do { } while(0)
#define XPRINTK(args...) do { } while(0)
#define DPRINTK(args...) do { } while(0)
#define NPRINTK(args...) do { } while(0)
#define RPRINTK(args...) do { } while(0)
#endif
#define SCHED_UBR0 0
#define SCHED_UBR 1
#define SCHED_VBR 2
#define SCHED_ABR 3
#define SCHED_CBR 4
#define SCQFULL_TIMEOUT HZ
/*****************************************************************************/
/* */
/* Free Buffer Queue Layout */
/* */
/*****************************************************************************/
#define SAR_FB_SIZE_0 (2048 - 256)
#define SAR_FB_SIZE_1 (4096 - 256)
#define SAR_FB_SIZE_2 (8192 - 256)
#define SAR_FB_SIZE_3 (16384 - 256)
#define SAR_FBQ0_LOW 4
#define SAR_FBQ0_HIGH 8
#define SAR_FBQ1_LOW 2
#define SAR_FBQ1_HIGH 4
#define SAR_FBQ2_LOW 1
#define SAR_FBQ2_HIGH 2
#define SAR_FBQ3_LOW 1
#define SAR_FBQ3_HIGH 2
#if 0
#define SAR_TST_RESERVED 44 /* Num TST reserved for UBR/ABR/VBR */
#else
#define SAR_TST_RESERVED 0 /* Num TST reserved for UBR/ABR/VBR */
#endif
#define TCT_CBR 0x00000000
#define TCT_UBR 0x00000000
#define TCT_VBR 0x40000000
#define TCT_ABR 0x80000000
#define TCT_TYPE 0xc0000000
#define TCT_RR 0x20000000
#define TCT_LMCR 0x08000000
#define TCT_SCD_MASK 0x0007ffff
#define TCT_TSIF 0x00004000
#define TCT_HALT 0x80000000
#define TCT_IDLE 0x40000000
#define TCT_FLAG_UBR 0x80000000
/*****************************************************************************/
/* */
/* Structure describing an IDT77252 */
/* */
/*****************************************************************************/
struct scqe
{
u32 word_1;
u32 word_2;
u32 word_3;
u32 word_4;
};
#define SCQ_ENTRIES 64
#define SCQ_SIZE (SCQ_ENTRIES * sizeof(struct scqe))
#define SCQ_MASK (SCQ_SIZE - 1)
struct scq_info
{
struct scqe *base;
struct scqe *next;
struct scqe *last;
dma_addr_t paddr;
spinlock_t lock;
atomic_t used;
unsigned long trans_start;
unsigned long scd;
spinlock_t skblock;
struct sk_buff_head transmit;
struct sk_buff_head pending;
};
struct rx_pool {
struct sk_buff_head queue;
unsigned int len;
};
struct aal1 {
unsigned int total;
unsigned int count;
struct sk_buff *data;
unsigned char sequence;
};
struct rate_estimator {
struct timer_list timer;
unsigned int interval;
unsigned int ewma_log;
u64 cells;
u64 last_cells;
long avcps;
u32 cps;
u32 maxcps;
};
struct vc_map {
unsigned int index;
unsigned long flags;
#define VCF_TX 0
#define VCF_RX 1
#define VCF_IDLE 2
#define VCF_RSV 3
unsigned int class;
u8 init_er;
u8 lacr;
u8 max_er;
unsigned int ntste;
spinlock_t lock;
struct atm_vcc *tx_vcc;
struct atm_vcc *rx_vcc;
struct idt77252_dev *card;
struct scq_info *scq; /* To keep track of the SCQ */
struct rate_estimator *estimator;
int scd_index;
union {
struct rx_pool rx_pool;
struct aal1 aal1;
} rcv;
};
/*****************************************************************************/
/* */
/* RCTE - Receive Connection Table Entry */
/* */
/*****************************************************************************/
struct rct_entry
{
u32 word_1;
u32 buffer_handle;
u32 dma_address;
u32 aal5_crc32;
};
/*****************************************************************************/
/* */
/* RSQ - Receive Status Queue */
/* */
/*****************************************************************************/
#define SAR_RSQE_VALID 0x80000000
#define SAR_RSQE_IDLE 0x40000000
#define SAR_RSQE_BUF_MASK 0x00030000
#define SAR_RSQE_BUF_ASGN 0x00008000
#define SAR_RSQE_NZGFC 0x00004000
#define SAR_RSQE_EPDU 0x00002000
#define SAR_RSQE_BUF_CONT 0x00001000
#define SAR_RSQE_EFCIE 0x00000800
#define SAR_RSQE_CLP 0x00000400
#define SAR_RSQE_CRC 0x00000200
#define SAR_RSQE_CELLCNT 0x000001FF
#define RSQSIZE 8192
#define RSQ_NUM_ENTRIES (RSQSIZE / 16)
#define RSQ_ALIGNMENT 8192
struct rsq_entry {
u32 word_1;
u32 word_2;
u32 word_3;
u32 word_4;
};
struct rsq_info {
struct rsq_entry *base;
struct rsq_entry *next;
struct rsq_entry *last;
dma_addr_t paddr;
};
/*****************************************************************************/
/* */
/* TSQ - Transmit Status Queue */
/* */
/*****************************************************************************/
#define SAR_TSQE_INVALID 0x80000000
#define SAR_TSQE_TIMESTAMP 0x00FFFFFF
#define SAR_TSQE_TYPE 0x60000000
#define SAR_TSQE_TYPE_TIMER 0x00000000
#define SAR_TSQE_TYPE_TSR 0x20000000
#define SAR_TSQE_TYPE_IDLE 0x40000000
#define SAR_TSQE_TYPE_TBD_COMP 0x60000000
#define SAR_TSQE_TAG(stat) (((stat) >> 24) & 0x1f)
#define TSQSIZE 8192
#define TSQ_NUM_ENTRIES 1024
#define TSQ_ALIGNMENT 8192
struct tsq_entry
{
u32 word_1;
u32 word_2;
};
struct tsq_info
{
struct tsq_entry *base;
struct tsq_entry *next;
struct tsq_entry *last;
dma_addr_t paddr;
};
struct tst_info
{
struct vc_map *vc;
u32 tste;
};
#define TSTE_MASK 0x601fffff
#define TSTE_OPC_MASK 0x60000000
#define TSTE_OPC_NULL 0x00000000
#define TSTE_OPC_CBR 0x20000000
#define TSTE_OPC_VAR 0x40000000
#define TSTE_OPC_JMP 0x60000000
#define TSTE_PUSH_IDLE 0x01000000
#define TSTE_PUSH_ACTIVE 0x02000000
#define TST_SWITCH_DONE 0
#define TST_SWITCH_PENDING 1
#define TST_SWITCH_WAIT 2
#define FBQ_SHIFT 9
#define FBQ_SIZE (1 << FBQ_SHIFT)
#define FBQ_MASK (FBQ_SIZE - 1)
struct sb_pool
{
unsigned int index;
struct sk_buff *skb[FBQ_SIZE];
};
#define POOL_HANDLE(queue, index) (((queue + 1) << 16) | (index))
#define POOL_QUEUE(handle) (((handle) >> 16) - 1)
#define POOL_INDEX(handle) ((handle) & 0xffff)
struct idt77252_dev
{
struct tsq_info tsq; /* Transmit Status Queue */
struct rsq_info rsq; /* Receive Status Queue */
struct pci_dev *pcidev; /* PCI handle (desriptor) */
struct atm_dev *atmdev; /* ATM device desriptor */
void __iomem *membase; /* SAR's memory base address */
unsigned long srambase; /* SAR's sram base address */
void __iomem *fbq[4]; /* FBQ fill addresses */
struct mutex mutex;
spinlock_t cmd_lock; /* for r/w utility/sram */
unsigned long softstat;
unsigned long flags; /* see blow */
struct work_struct tqueue;
unsigned long tct_base; /* TCT base address in SRAM */
unsigned long rct_base; /* RCT base address in SRAM */
unsigned long rt_base; /* Rate Table base in SRAM */
unsigned long scd_base; /* SCD base address in SRAM */
unsigned long tst[2]; /* TST base address in SRAM */
unsigned long abrst_base; /* ABRST base address in SRAM */
unsigned long fifo_base; /* RX FIFO base in SRAM */
unsigned long irqstat[16];
unsigned int sramsize; /* SAR's sram size */
unsigned int tct_size; /* total TCT entries */
unsigned int rct_size; /* total RCT entries */
unsigned int scd_size; /* length of SCD */
unsigned int tst_size; /* total TST entries */
unsigned int tst_free; /* free TSTEs in TST */
unsigned int abrst_size; /* size of ABRST in words */
unsigned int fifo_size; /* size of RX FIFO in words */
unsigned int vpibits; /* Bits used for VPI index */
unsigned int vcibits; /* Bits used for VCI index */
unsigned int vcimask; /* Mask for VCI index */
unsigned int utopia_pcr; /* Utopia Itf's Cell Rate */
unsigned int link_pcr; /* PHY's Peek Cell Rate */
struct vc_map **vcs; /* Open Connections */
struct vc_map **scd2vc; /* SCD to Connection map */
struct tst_info *soft_tst; /* TST to Connection map */
unsigned int tst_index; /* Current TST in use */
struct timer_list tst_timer;
spinlock_t tst_lock;
unsigned long tst_state;
struct sb_pool sbpool[4]; /* Pool of RX skbuffs */
struct sk_buff *raw_cell_head; /* Pointer to raw cell queue */
u32 *raw_cell_hnd; /* Pointer to RCQ handle */
dma_addr_t raw_cell_paddr;
int index; /* SAR's ID */
int revision; /* chip revision */
char name[16]; /* Device name */
struct idt77252_dev *next;
};
/* definition for flag field above */
#define IDT77252_BIT_INIT 1
#define IDT77252_BIT_INTERRUPT 2
#define ATM_CELL_PAYLOAD 48
#define FREEBUF_ALIGNMENT 16
/*****************************************************************************/
/* */
/* Makros */
/* */
/*****************************************************************************/
#define ALIGN_ADDRESS(addr, alignment) \
((((u32)(addr)) + (((u32)(alignment))-1)) & ~(((u32)(alignment)) - 1))
/*****************************************************************************/
/* */
/* ABR SAR Network operation Register */
/* */
/*****************************************************************************/
#define SAR_REG_DR0 (card->membase + 0x00)
#define SAR_REG_DR1 (card->membase + 0x04)
#define SAR_REG_DR2 (card->membase + 0x08)
#define SAR_REG_DR3 (card->membase + 0x0C)
#define SAR_REG_CMD (card->membase + 0x10)
#define SAR_REG_CFG (card->membase + 0x14)
#define SAR_REG_STAT (card->membase + 0x18)
#define SAR_REG_RSQB (card->membase + 0x1C)
#define SAR_REG_RSQT (card->membase + 0x20)
#define SAR_REG_RSQH (card->membase + 0x24)
#define SAR_REG_CDC (card->membase + 0x28)
#define SAR_REG_VPEC (card->membase + 0x2C)
#define SAR_REG_ICC (card->membase + 0x30)
#define SAR_REG_RAWCT (card->membase + 0x34)
#define SAR_REG_TMR (card->membase + 0x38)
#define SAR_REG_TSTB (card->membase + 0x3C)
#define SAR_REG_TSQB (card->membase + 0x40)
#define SAR_REG_TSQT (card->membase + 0x44)
#define SAR_REG_TSQH (card->membase + 0x48)
#define SAR_REG_GP (card->membase + 0x4C)
#define SAR_REG_VPM (card->membase + 0x50)
#define SAR_REG_RXFD (card->membase + 0x54)
#define SAR_REG_RXFT (card->membase + 0x58)
#define SAR_REG_RXFH (card->membase + 0x5C)
#define SAR_REG_RAWHND (card->membase + 0x60)
#define SAR_REG_RXSTAT (card->membase + 0x64)
#define SAR_REG_ABRSTD (card->membase + 0x68)
#define SAR_REG_ABRRQ (card->membase + 0x6C)
#define SAR_REG_VBRRQ (card->membase + 0x70)
#define SAR_REG_RTBL (card->membase + 0x74)
#define SAR_REG_MDFCT (card->membase + 0x78)
#define SAR_REG_TXSTAT (card->membase + 0x7C)
#define SAR_REG_TCMDQ (card->membase + 0x80)
#define SAR_REG_IRCP (card->membase + 0x84)
#define SAR_REG_FBQP0 (card->membase + 0x88)
#define SAR_REG_FBQP1 (card->membase + 0x8C)
#define SAR_REG_FBQP2 (card->membase + 0x90)
#define SAR_REG_FBQP3 (card->membase + 0x94)
#define SAR_REG_FBQS0 (card->membase + 0x98)
#define SAR_REG_FBQS1 (card->membase + 0x9C)
#define SAR_REG_FBQS2 (card->membase + 0xA0)
#define SAR_REG_FBQS3 (card->membase + 0xA4)
#define SAR_REG_FBQWP0 (card->membase + 0xA8)
#define SAR_REG_FBQWP1 (card->membase + 0xAC)
#define SAR_REG_FBQWP2 (card->membase + 0xB0)
#define SAR_REG_FBQWP3 (card->membase + 0xB4)
#define SAR_REG_NOW (card->membase + 0xB8)
/*****************************************************************************/
/* */
/* Commands */
/* */
/*****************************************************************************/
#define SAR_CMD_NO_OPERATION 0x00000000
#define SAR_CMD_OPENCLOSE_CONNECTION 0x20000000
#define SAR_CMD_WRITE_SRAM 0x40000000
#define SAR_CMD_READ_SRAM 0x50000000
#define SAR_CMD_READ_UTILITY 0x80000000
#define SAR_CMD_WRITE_UTILITY 0x90000000
#define SAR_CMD_OPEN_CONNECTION (SAR_CMD_OPENCLOSE_CONNECTION | 0x00080000)
#define SAR_CMD_CLOSE_CONNECTION SAR_CMD_OPENCLOSE_CONNECTION
/*****************************************************************************/
/* */
/* Configuration Register bits */
/* */
/*****************************************************************************/
#define SAR_CFG_SWRST 0x80000000 /* Software reset */
#define SAR_CFG_LOOP 0x40000000 /* Internal Loopback */
#define SAR_CFG_RXPTH 0x20000000 /* Receive Path Enable */
#define SAR_CFG_IDLE_CLP 0x10000000 /* SAR set CLP Bits of Null Cells */
#define SAR_CFG_TX_FIFO_SIZE_1 0x04000000 /* TX FIFO Size = 1 cell */
#define SAR_CFG_TX_FIFO_SIZE_2 0x08000000 /* TX FIFO Size = 2 cells */
#define SAR_CFG_TX_FIFO_SIZE_4 0x0C000000 /* TX FIFO Size = 4 cells */
#define SAR_CFG_TX_FIFO_SIZE_9 0x00000000 /* TX FIFO Size = 9 cells (full) */
#define SAR_CFG_NO_IDLE 0x02000000 /* SAR sends no Null Cells */
#define SAR_CFG_RSVD1 0x01000000 /* Reserved */
#define SAR_CFG_RXSTQ_SIZE_2k 0x00000000 /* RX Stat Queue Size = 2048 byte */
#define SAR_CFG_RXSTQ_SIZE_4k 0x00400000 /* RX Stat Queue Size = 4096 byte */
#define SAR_CFG_RXSTQ_SIZE_8k 0x00800000 /* RX Stat Queue Size = 8192 byte */
#define SAR_CFG_RXSTQ_SIZE_R 0x00C00000 /* RX Stat Queue Size = reserved */
#define SAR_CFG_ICAPT 0x00200000 /* accept Invalid Cells */
#define SAR_CFG_IGGFC 0x00100000 /* Ignore GFC */
#define SAR_CFG_VPVCS_0 0x00000000 /* VPI/VCI Select bit range */
#define SAR_CFG_VPVCS_1 0x00040000 /* VPI/VCI Select bit range */
#define SAR_CFG_VPVCS_2 0x00080000 /* VPI/VCI Select bit range */
#define SAR_CFG_VPVCS_8 0x000C0000 /* VPI/VCI Select bit range */
#define SAR_CFG_CNTBL_1k 0x00000000 /* Connection Table Size */
#define SAR_CFG_CNTBL_4k 0x00010000 /* Connection Table Size */
#define SAR_CFG_CNTBL_16k 0x00020000 /* Connection Table Size */
#define SAR_CFG_CNTBL_512 0x00030000 /* Connection Table Size */
#define SAR_CFG_VPECA 0x00008000 /* VPI/VCI Error Cell Accept */
#define SAR_CFG_RXINT_NOINT 0x00000000 /* No Interrupt on PDU received */
#define SAR_CFG_RXINT_NODELAY 0x00001000 /* Interrupt without delay to host*/
#define SAR_CFG_RXINT_256US 0x00002000 /* Interrupt with delay 256 usec */
#define SAR_CFG_RXINT_505US 0x00003000 /* Interrupt with delay 505 usec */
#define SAR_CFG_RXINT_742US 0x00004000 /* Interrupt with delay 742 usec */
#define SAR_CFG_RAWIE 0x00000800 /* Raw Cell Queue Interrupt Enable*/
#define SAR_CFG_RQFIE 0x00000400 /* RSQ Almost Full Int Enable */
#define SAR_CFG_RSVD2 0x00000200 /* Reserved */
#define SAR_CFG_CACHE 0x00000100 /* DMA on Cache Line Boundary */
#define SAR_CFG_TMOIE 0x00000080 /* Timer Roll Over Int Enable */
#define SAR_CFG_FBIE 0x00000040 /* Free Buffer Queue Int Enable */
#define SAR_CFG_TXEN 0x00000020 /* Transmit Operation Enable */
#define SAR_CFG_TXINT 0x00000010 /* Transmit status Int Enable */
#define SAR_CFG_TXUIE 0x00000008 /* Transmit underrun Int Enable */
#define SAR_CFG_UMODE 0x00000004 /* Utopia Mode Select */
#define SAR_CFG_TXSFI 0x00000002 /* Transmit status Full Int Enable*/
#define SAR_CFG_PHYIE 0x00000001 /* PHY Interrupt Enable */
#define SAR_CFG_TX_FIFO_SIZE_MASK 0x0C000000 /* TX FIFO Size Mask */
#define SAR_CFG_RXSTQSIZE_MASK 0x00C00000
#define SAR_CFG_CNTBL_MASK 0x00030000
#define SAR_CFG_RXINT_MASK 0x00007000
/*****************************************************************************/
/* */
/* Status Register bits */
/* */
/*****************************************************************************/
#define SAR_STAT_FRAC_3 0xF0000000 /* Fraction of Free Buffer Queue 3 */
#define SAR_STAT_FRAC_2 0x0F000000 /* Fraction of Free Buffer Queue 2 */
#define SAR_STAT_FRAC_1 0x00F00000 /* Fraction of Free Buffer Queue 1 */
#define SAR_STAT_FRAC_0 0x000F0000 /* Fraction of Free Buffer Queue 0 */
#define SAR_STAT_TSIF 0x00008000 /* Transmit Status Indicator */
#define SAR_STAT_TXICP 0x00004000 /* Transmit Status Indicator */
#define SAR_STAT_RSVD1 0x00002000 /* Reserved */
#define SAR_STAT_TSQF 0x00001000 /* Transmit Status Queue full */
#define SAR_STAT_TMROF 0x00000800 /* Timer overflow */
#define SAR_STAT_PHYI 0x00000400 /* PHY device Interrupt flag */
#define SAR_STAT_CMDBZ 0x00000200 /* ABR SAR Command Busy Flag */
#define SAR_STAT_FBQ3A 0x00000100 /* Free Buffer Queue 3 Attention */
#define SAR_STAT_FBQ2A 0x00000080 /* Free Buffer Queue 2 Attention */
#define SAR_STAT_RSQF 0x00000040 /* Receive Status Queue full */
#define SAR_STAT_EPDU 0x00000020 /* End Of PDU Flag */
#define SAR_STAT_RAWCF 0x00000010 /* Raw Cell Flag */
#define SAR_STAT_FBQ1A 0x00000008 /* Free Buffer Queue 1 Attention */
#define SAR_STAT_FBQ0A 0x00000004 /* Free Buffer Queue 0 Attention */
#define SAR_STAT_RSQAF 0x00000002 /* Receive Status Queue almost full*/
#define SAR_STAT_RSVD2 0x00000001 /* Reserved */
/*****************************************************************************/
/* */
/* General Purpose Register bits */
/* */
/*****************************************************************************/
#define SAR_GP_TXNCC_MASK 0xff000000 /* Transmit Negative Credit Count */
#define SAR_GP_EEDI 0x00010000 /* EEPROM Data In */
#define SAR_GP_BIGE 0x00008000 /* Big Endian Operation */
#define SAR_GP_RM_NORMAL 0x00000000 /* Normal handling of RM cells */
#define SAR_GP_RM_TO_RCQ 0x00002000 /* put RM cells into Raw Cell Queue */
#define SAR_GP_RM_RSVD 0x00004000 /* Reserved */
#define SAR_GP_RM_INHIBIT 0x00006000 /* Inhibit update of Connection tab */
#define SAR_GP_PHY_RESET 0x00000008 /* PHY Reset */
#define SAR_GP_EESCLK 0x00000004 /* EEPROM SCLK */
#define SAR_GP_EECS 0x00000002 /* EEPROM Chip Select */
#define SAR_GP_EEDO 0x00000001 /* EEPROM Data Out */
/*****************************************************************************/
/* */
/* SAR local SRAM layout for 128k work SRAM */
/* */
/*****************************************************************************/
#define SAR_SRAM_SCD_SIZE 12
#define SAR_SRAM_TCT_SIZE 8
#define SAR_SRAM_RCT_SIZE 4
#define SAR_SRAM_TCT_128_BASE 0x00000
#define SAR_SRAM_TCT_128_TOP 0x01fff
#define SAR_SRAM_RCT_128_BASE 0x02000
#define SAR_SRAM_RCT_128_TOP 0x02fff
#define SAR_SRAM_FB0_128_BASE 0x03000
#define SAR_SRAM_FB0_128_TOP 0x033ff
#define SAR_SRAM_FB1_128_BASE 0x03400
#define SAR_SRAM_FB1_128_TOP 0x037ff
#define SAR_SRAM_FB2_128_BASE 0x03800
#define SAR_SRAM_FB2_128_TOP 0x03bff
#define SAR_SRAM_FB3_128_BASE 0x03c00
#define SAR_SRAM_FB3_128_TOP 0x03fff
#define SAR_SRAM_SCD_128_BASE 0x04000
#define SAR_SRAM_SCD_128_TOP 0x07fff
#define SAR_SRAM_TST1_128_BASE 0x08000
#define SAR_SRAM_TST1_128_TOP 0x0bfff
#define SAR_SRAM_TST2_128_BASE 0x0c000
#define SAR_SRAM_TST2_128_TOP 0x0ffff
#define SAR_SRAM_ABRSTD_128_BASE 0x10000
#define SAR_SRAM_ABRSTD_128_TOP 0x13fff
#define SAR_SRAM_RT_128_BASE 0x14000
#define SAR_SRAM_RT_128_TOP 0x15fff
#define SAR_SRAM_FIFO_128_BASE 0x18000
#define SAR_SRAM_FIFO_128_TOP 0x1ffff
/*****************************************************************************/
/* */
/* SAR local SRAM layout for 32k work SRAM */
/* */
/*****************************************************************************/
#define SAR_SRAM_TCT_32_BASE 0x00000
#define SAR_SRAM_TCT_32_TOP 0x00fff
#define SAR_SRAM_RCT_32_BASE 0x01000
#define SAR_SRAM_RCT_32_TOP 0x017ff
#define SAR_SRAM_FB0_32_BASE 0x01800
#define SAR_SRAM_FB0_32_TOP 0x01bff
#define SAR_SRAM_FB1_32_BASE 0x01c00
#define SAR_SRAM_FB1_32_TOP 0x01fff
#define SAR_SRAM_FB2_32_BASE 0x02000
#define SAR_SRAM_FB2_32_TOP 0x023ff
#define SAR_SRAM_FB3_32_BASE 0x02400
#define SAR_SRAM_FB3_32_TOP 0x027ff
#define SAR_SRAM_SCD_32_BASE 0x02800
#define SAR_SRAM_SCD_32_TOP 0x03fff
#define SAR_SRAM_TST1_32_BASE 0x04000
#define SAR_SRAM_TST1_32_TOP 0x04fff
#define SAR_SRAM_TST2_32_BASE 0x05000
#define SAR_SRAM_TST2_32_TOP 0x05fff
#define SAR_SRAM_ABRSTD_32_BASE 0x06000
#define SAR_SRAM_ABRSTD_32_TOP 0x067ff
#define SAR_SRAM_RT_32_BASE 0x06800
#define SAR_SRAM_RT_32_TOP 0x06fff
#define SAR_SRAM_FIFO_32_BASE 0x07000
#define SAR_SRAM_FIFO_32_TOP 0x07fff
/*****************************************************************************/
/* */
/* TSR - Transmit Status Request */
/* */
/*****************************************************************************/
#define SAR_TSR_TYPE_TSR 0x80000000
#define SAR_TSR_TYPE_TBD 0x00000000
#define SAR_TSR_TSIF 0x20000000
#define SAR_TSR_TAG_MASK 0x01F00000
/*****************************************************************************/
/* */
/* TBD - Transmit Buffer Descriptor */
/* */
/*****************************************************************************/
#define SAR_TBD_EPDU 0x40000000
#define SAR_TBD_TSIF 0x20000000
#define SAR_TBD_OAM 0x10000000
#define SAR_TBD_AAL0 0x00000000
#define SAR_TBD_AAL34 0x04000000
#define SAR_TBD_AAL5 0x08000000
#define SAR_TBD_GTSI 0x02000000
#define SAR_TBD_TAG_MASK 0x01F00000
#define SAR_TBD_VPI_MASK 0x0FF00000
#define SAR_TBD_VCI_MASK 0x000FFFF0
#define SAR_TBD_VC_MASK (SAR_TBD_VPI_MASK | SAR_TBD_VCI_MASK)
#define SAR_TBD_VPI_SHIFT 20
#define SAR_TBD_VCI_SHIFT 4
/*****************************************************************************/
/* */
/* RXFD - Receive FIFO Descriptor */
/* */
/*****************************************************************************/
#define SAR_RXFD_SIZE_MASK 0x0F000000
#define SAR_RXFD_SIZE_512 0x00000000 /* 512 words */
#define SAR_RXFD_SIZE_1K 0x01000000 /* 1k words */
#define SAR_RXFD_SIZE_2K 0x02000000 /* 2k words */
#define SAR_RXFD_SIZE_4K 0x03000000 /* 4k words */
#define SAR_RXFD_SIZE_8K 0x04000000 /* 8k words */
#define SAR_RXFD_SIZE_16K 0x05000000 /* 16k words */
#define SAR_RXFD_SIZE_32K 0x06000000 /* 32k words */
#define SAR_RXFD_SIZE_64K 0x07000000 /* 64k words */
#define SAR_RXFD_SIZE_128K 0x08000000 /* 128k words */
#define SAR_RXFD_SIZE_256K 0x09000000 /* 256k words */
#define SAR_RXFD_ADDR_MASK 0x001ffc00
/*****************************************************************************/
/* */
/* ABRSTD - ABR + VBR Schedule Tables */
/* */
/*****************************************************************************/
#define SAR_ABRSTD_SIZE_MASK 0x07000000
#define SAR_ABRSTD_SIZE_512 0x00000000 /* 512 words */
#define SAR_ABRSTD_SIZE_1K 0x01000000 /* 1k words */
#define SAR_ABRSTD_SIZE_2K 0x02000000 /* 2k words */
#define SAR_ABRSTD_SIZE_4K 0x03000000 /* 4k words */
#define SAR_ABRSTD_SIZE_8K 0x04000000 /* 8k words */
#define SAR_ABRSTD_SIZE_16K 0x05000000 /* 16k words */
#define SAR_ABRSTD_ADDR_MASK 0x001ffc00
/*****************************************************************************/
/* */
/* RCTE - Receive Connection Table Entry */
/* */
/*****************************************************************************/
#define SAR_RCTE_IL_MASK 0xE0000000 /* inactivity limit */
#define SAR_RCTE_IC_MASK 0x1C000000 /* inactivity count */
#define SAR_RCTE_RSVD 0x02000000 /* reserved */
#define SAR_RCTE_LCD 0x01000000 /* last cell data */
#define SAR_RCTE_CI_VC 0x00800000 /* EFCI in previous cell of VC */
#define SAR_RCTE_FBP_01 0x00000000 /* 1. cell->FBQ0, others->FBQ1 */
#define SAR_RCTE_FBP_1 0x00200000 /* use FBQ 1 for all cells */
#define SAR_RCTE_FBP_2 0x00400000 /* use FBQ 2 for all cells */
#define SAR_RCTE_FBP_3 0x00600000 /* use FBQ 3 for all cells */
#define SAR_RCTE_NZ_GFC 0x00100000 /* non zero GFC in all cell of VC */
#define SAR_RCTE_CONNECTOPEN 0x00080000 /* VC is open */
#define SAR_RCTE_AAL_MASK 0x00070000 /* mask for AAL type field s.b. */
#define SAR_RCTE_RAWCELLINTEN 0x00008000 /* raw cell interrupt enable */
#define SAR_RCTE_RXCONCELLADDR 0x00004000 /* RX constant cell address */
#define SAR_RCTE_BUFFSTAT_MASK 0x00003000 /* buffer status */
#define SAR_RCTE_EFCI 0x00000800 /* EFCI Congestion flag */
#define SAR_RCTE_CLP 0x00000400 /* Cell Loss Priority flag */
#define SAR_RCTE_CRC 0x00000200 /* Received CRC Error */
#define SAR_RCTE_CELLCNT_MASK 0x000001FF /* cell Count */
#define SAR_RCTE_AAL0 0x00000000 /* AAL types for ALL field */
#define SAR_RCTE_AAL34 0x00010000
#define SAR_RCTE_AAL5 0x00020000
#define SAR_RCTE_RCQ 0x00030000
#define SAR_RCTE_OAM 0x00040000
#define TCMDQ_START 0x01000000
#define TCMDQ_LACR 0x02000000
#define TCMDQ_START_LACR 0x03000000
#define TCMDQ_INIT_ER 0x04000000
#define TCMDQ_HALT 0x05000000
struct idt77252_skb_prv {
struct scqe tbd; /* Transmit Buffer Descriptor */
dma_addr_t paddr; /* DMA handle */
u32 pool; /* sb_pool handle */
};
#define IDT77252_PRV_TBD(skb) \
(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->tbd)
#define IDT77252_PRV_PADDR(skb) \
(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->paddr)
#define IDT77252_PRV_POOL(skb) \
(((struct idt77252_skb_prv *)(ATM_SKB(skb)+1))->pool)
/*****************************************************************************/
/* */
/* PCI related items */
/* */
/*****************************************************************************/
#ifndef PCI_VENDOR_ID_IDT
#define PCI_VENDOR_ID_IDT 0x111D
#endif /* PCI_VENDOR_ID_IDT */
#ifndef PCI_DEVICE_ID_IDT_IDT77252
#define PCI_DEVICE_ID_IDT_IDT77252 0x0003
#endif /* PCI_DEVICE_ID_IDT_IDT772052 */
#endif /* !(_IDT77252_H) */

View file

@ -0,0 +1,780 @@
/* Do not edit, automatically generated by `./genrtbl'.
*
* Cell Line Rate: 353207.55 (155520000 bps)
*/
static unsigned int log_to_rate[] =
{
/* 000 */ 0x8d022e27, /* cps = 10.02, nrm = 3, interval = 35264.00 */
/* 001 */ 0x8d362e11, /* cps = 10.42, nrm = 3, interval = 33856.00 */
/* 002 */ 0x8d6e2bf8, /* cps = 10.86, nrm = 3, interval = 32512.00 */
/* 003 */ 0x8da82bcf, /* cps = 11.31, nrm = 3, interval = 31200.00 */
/* 004 */ 0x8de42ba8, /* cps = 11.78, nrm = 3, interval = 29952.00 */
/* 005 */ 0x8e242b82, /* cps = 12.28, nrm = 3, interval = 28736.00 */
/* 006 */ 0x8e662b5e, /* cps = 12.80, nrm = 3, interval = 27584.00 */
/* 007 */ 0x8eaa2b3c, /* cps = 13.33, nrm = 3, interval = 26496.00 */
/* 008 */ 0x8ef22b1a, /* cps = 13.89, nrm = 3, interval = 25408.00 */
/* 009 */ 0x8f3e2afa, /* cps = 14.48, nrm = 3, interval = 24384.00 */
/* 010 */ 0x8f8a2adc, /* cps = 15.08, nrm = 3, interval = 23424.00 */
/* 011 */ 0x8fdc2abe, /* cps = 15.72, nrm = 3, interval = 22464.00 */
/* 012 */ 0x90182aa2, /* cps = 16.38, nrm = 3, interval = 21568.00 */
/* 013 */ 0x90422a87, /* cps = 17.03, nrm = 3, interval = 20704.00 */
/* 014 */ 0x90702a6d, /* cps = 17.75, nrm = 3, interval = 19872.00 */
/* 015 */ 0x90a02a54, /* cps = 18.50, nrm = 3, interval = 19072.00 */
/* 016 */ 0x90d22a3c, /* cps = 19.28, nrm = 3, interval = 18304.00 */
/* 017 */ 0x91062a25, /* cps = 20.09, nrm = 3, interval = 17568.00 */
/* 018 */ 0x913c2a0f, /* cps = 20.94, nrm = 3, interval = 16864.00 */
/* 019 */ 0x917427f3, /* cps = 21.81, nrm = 3, interval = 16176.00 */
/* 020 */ 0x91b027ca, /* cps = 22.75, nrm = 3, interval = 15520.00 */
/* 021 */ 0x91ec27a3, /* cps = 23.69, nrm = 3, interval = 14896.00 */
/* 022 */ 0x922c277e, /* cps = 24.69, nrm = 3, interval = 14304.00 */
/* 023 */ 0x926e275a, /* cps = 25.72, nrm = 3, interval = 13728.00 */
/* 024 */ 0x92b42737, /* cps = 26.81, nrm = 3, interval = 13168.00 */
/* 025 */ 0x92fc2716, /* cps = 27.94, nrm = 3, interval = 12640.00 */
/* 026 */ 0x934626f6, /* cps = 29.09, nrm = 3, interval = 12128.00 */
/* 027 */ 0x939426d8, /* cps = 30.31, nrm = 3, interval = 11648.00 */
/* 028 */ 0x93e426bb, /* cps = 31.56, nrm = 3, interval = 11184.00 */
/* 029 */ 0x941e269e, /* cps = 32.94, nrm = 3, interval = 10720.00 */
/* 030 */ 0x944a2683, /* cps = 34.31, nrm = 3, interval = 10288.00 */
/* 031 */ 0x9476266a, /* cps = 35.69, nrm = 3, interval = 9888.00 */
/* 032 */ 0x94a62651, /* cps = 37.19, nrm = 3, interval = 9488.00 */
/* 033 */ 0x94d82639, /* cps = 38.75, nrm = 3, interval = 9104.00 */
/* 034 */ 0x950c6622, /* cps = 40.38, nrm = 4, interval = 8736.00 */
/* 035 */ 0x9544660c, /* cps = 42.12, nrm = 4, interval = 8384.00 */
/* 036 */ 0x957c63ee, /* cps = 43.88, nrm = 4, interval = 8048.00 */
/* 037 */ 0x95b663c6, /* cps = 45.69, nrm = 4, interval = 7728.00 */
/* 038 */ 0x95f4639f, /* cps = 47.62, nrm = 4, interval = 7416.00 */
/* 039 */ 0x96346379, /* cps = 49.62, nrm = 4, interval = 7112.00 */
/* 040 */ 0x96766356, /* cps = 51.69, nrm = 4, interval = 6832.00 */
/* 041 */ 0x96bc6333, /* cps = 53.88, nrm = 4, interval = 6552.00 */
/* 042 */ 0x97046312, /* cps = 56.12, nrm = 4, interval = 6288.00 */
/* 043 */ 0x974e62f3, /* cps = 58.44, nrm = 4, interval = 6040.00 */
/* 044 */ 0x979e62d4, /* cps = 60.94, nrm = 4, interval = 5792.00 */
/* 045 */ 0x97f062b7, /* cps = 63.50, nrm = 4, interval = 5560.00 */
/* 046 */ 0x9822629b, /* cps = 66.12, nrm = 4, interval = 5336.00 */
/* 047 */ 0x984e6280, /* cps = 68.88, nrm = 4, interval = 5120.00 */
/* 048 */ 0x987e6266, /* cps = 71.88, nrm = 4, interval = 4912.00 */
/* 049 */ 0x98ac624e, /* cps = 74.75, nrm = 4, interval = 4720.00 */
/* 050 */ 0x98e06236, /* cps = 78.00, nrm = 4, interval = 4528.00 */
/* 051 */ 0x9914a21f, /* cps = 81.25, nrm = 8, interval = 4344.00 */
/* 052 */ 0x994aa209, /* cps = 84.62, nrm = 8, interval = 4168.00 */
/* 053 */ 0x99829fe9, /* cps = 88.12, nrm = 8, interval = 4004.00 */
/* 054 */ 0x99be9fc1, /* cps = 91.88, nrm = 8, interval = 3844.00 */
/* 055 */ 0x99fc9f9a, /* cps = 95.75, nrm = 8, interval = 3688.00 */
/* 056 */ 0x9a3c9f75, /* cps = 99.75, nrm = 8, interval = 3540.00 */
/* 057 */ 0x9a809f51, /* cps = 104.00, nrm = 8, interval = 3396.00 */
/* 058 */ 0x9ac49f2f, /* cps = 108.25, nrm = 8, interval = 3260.00 */
/* 059 */ 0x9b0e9f0e, /* cps = 112.88, nrm = 8, interval = 3128.00 */
/* 060 */ 0x9b589eef, /* cps = 117.50, nrm = 8, interval = 3004.00 */
/* 061 */ 0x9ba69ed1, /* cps = 122.38, nrm = 8, interval = 2884.00 */
/* 062 */ 0x9bf89eb4, /* cps = 127.50, nrm = 8, interval = 2768.00 */
/* 063 */ 0x9c269e98, /* cps = 132.75, nrm = 8, interval = 2656.00 */
/* 064 */ 0x9c549e7d, /* cps = 138.50, nrm = 8, interval = 2548.00 */
/* 065 */ 0x9c849e63, /* cps = 144.50, nrm = 8, interval = 2444.00 */
/* 066 */ 0x9cb29e4b, /* cps = 150.25, nrm = 8, interval = 2348.00 */
/* 067 */ 0x9ce69e33, /* cps = 156.75, nrm = 8, interval = 2252.00 */
/* 068 */ 0x9d1cde1c, /* cps = 163.50, nrm = 16, interval = 2160.00 */
/* 069 */ 0x9d50de07, /* cps = 170.00, nrm = 16, interval = 2076.00 */
/* 070 */ 0x9d8adbe4, /* cps = 177.25, nrm = 16, interval = 1992.00 */
/* 071 */ 0x9dc4dbbc, /* cps = 184.50, nrm = 16, interval = 1912.00 */
/* 072 */ 0x9e02db96, /* cps = 192.25, nrm = 16, interval = 1836.00 */
/* 073 */ 0x9e42db71, /* cps = 200.25, nrm = 16, interval = 1762.00 */
/* 074 */ 0x9e86db4d, /* cps = 208.75, nrm = 16, interval = 1690.00 */
/* 075 */ 0x9ecedb2b, /* cps = 217.75, nrm = 16, interval = 1622.00 */
/* 076 */ 0x9f16db0a, /* cps = 226.75, nrm = 16, interval = 1556.00 */
/* 077 */ 0x9f62daeb, /* cps = 236.25, nrm = 16, interval = 1494.00 */
/* 078 */ 0x9fb2dacd, /* cps = 246.25, nrm = 16, interval = 1434.00 */
/* 079 */ 0xa002dab0, /* cps = 256.50, nrm = 16, interval = 1376.00 */
/* 080 */ 0xa02eda94, /* cps = 267.50, nrm = 16, interval = 1320.00 */
/* 081 */ 0xa05ada7a, /* cps = 278.50, nrm = 16, interval = 1268.00 */
/* 082 */ 0xa088da60, /* cps = 290.00, nrm = 16, interval = 1216.00 */
/* 083 */ 0xa0b8da48, /* cps = 302.00, nrm = 16, interval = 1168.00 */
/* 084 */ 0xa0ecda30, /* cps = 315.00, nrm = 16, interval = 1120.00 */
/* 085 */ 0xa1211a1a, /* cps = 328.00, nrm = 32, interval = 1076.00 */
/* 086 */ 0xa1591a04, /* cps = 342.00, nrm = 32, interval = 1032.00 */
/* 087 */ 0xa19117df, /* cps = 356.00, nrm = 32, interval = 991.00 */
/* 088 */ 0xa1cd17b7, /* cps = 371.00, nrm = 32, interval = 951.00 */
/* 089 */ 0xa20b1791, /* cps = 386.50, nrm = 32, interval = 913.00 */
/* 090 */ 0xa24d176c, /* cps = 403.00, nrm = 32, interval = 876.00 */
/* 091 */ 0xa28f1749, /* cps = 419.50, nrm = 32, interval = 841.00 */
/* 092 */ 0xa2d71727, /* cps = 437.50, nrm = 32, interval = 807.00 */
/* 093 */ 0xa31f1707, /* cps = 455.50, nrm = 32, interval = 775.00 */
/* 094 */ 0xa36d16e7, /* cps = 475.00, nrm = 32, interval = 743.00 */
/* 095 */ 0xa3bd16c9, /* cps = 495.00, nrm = 32, interval = 713.00 */
/* 096 */ 0xa40716ad, /* cps = 515.00, nrm = 32, interval = 685.00 */
/* 097 */ 0xa4331691, /* cps = 537.00, nrm = 32, interval = 657.00 */
/* 098 */ 0xa45f1677, /* cps = 559.00, nrm = 32, interval = 631.00 */
/* 099 */ 0xa48f165d, /* cps = 583.00, nrm = 32, interval = 605.00 */
/* 100 */ 0xa4bf1645, /* cps = 607.00, nrm = 32, interval = 581.00 */
/* 101 */ 0xa4f1162e, /* cps = 632.00, nrm = 32, interval = 558.00 */
/* 102 */ 0xa5291617, /* cps = 660.00, nrm = 32, interval = 535.00 */
/* 103 */ 0xa55f1602, /* cps = 687.00, nrm = 32, interval = 514.00 */
/* 104 */ 0xa59913da, /* cps = 716.00, nrm = 32, interval = 493.00 */
/* 105 */ 0xa5d513b2, /* cps = 746.00, nrm = 32, interval = 473.00 */
/* 106 */ 0xa613138c, /* cps = 777.00, nrm = 32, interval = 454.00 */
/* 107 */ 0xa6551368, /* cps = 810.00, nrm = 32, interval = 436.00 */
/* 108 */ 0xa6971345, /* cps = 843.00, nrm = 32, interval = 418.50 */
/* 109 */ 0xa6df1323, /* cps = 879.00, nrm = 32, interval = 401.50 */
/* 110 */ 0xa7291303, /* cps = 916.00, nrm = 32, interval = 385.50 */
/* 111 */ 0xa77512e4, /* cps = 954.00, nrm = 32, interval = 370.00 */
/* 112 */ 0xa7c512c6, /* cps = 994.00, nrm = 32, interval = 355.00 */
/* 113 */ 0xa80d12a9, /* cps = 1036.00, nrm = 32, interval = 340.50 */
/* 114 */ 0xa839128e, /* cps = 1080.00, nrm = 32, interval = 327.00 */
/* 115 */ 0xa8651274, /* cps = 1124.00, nrm = 32, interval = 314.00 */
/* 116 */ 0xa895125a, /* cps = 1172.00, nrm = 32, interval = 301.00 */
/* 117 */ 0xa8c71242, /* cps = 1222.00, nrm = 32, interval = 289.00 */
/* 118 */ 0xa8f9122b, /* cps = 1272.00, nrm = 32, interval = 277.50 */
/* 119 */ 0xa92f1214, /* cps = 1326.00, nrm = 32, interval = 266.00 */
/* 120 */ 0xa9670ffe, /* cps = 1382.00, nrm = 32, interval = 255.50 */
/* 121 */ 0xa9a10fd5, /* cps = 1440.00, nrm = 32, interval = 245.25 */
/* 122 */ 0xa9db0fae, /* cps = 1498.00, nrm = 32, interval = 235.50 */
/* 123 */ 0xaa1b0f88, /* cps = 1562.00, nrm = 32, interval = 226.00 */
/* 124 */ 0xaa5d0f63, /* cps = 1628.00, nrm = 32, interval = 216.75 */
/* 125 */ 0xaaa10f41, /* cps = 1696.00, nrm = 32, interval = 208.25 */
/* 126 */ 0xaae90f1f, /* cps = 1768.00, nrm = 32, interval = 199.75 */
/* 127 */ 0xab330eff, /* cps = 1842.00, nrm = 32, interval = 191.75 */
/* 128 */ 0xab7f0ee0, /* cps = 1918.00, nrm = 32, interval = 184.00 */
/* 129 */ 0xabd10ec2, /* cps = 2000.00, nrm = 32, interval = 176.50 */
/* 130 */ 0xac110ea6, /* cps = 2080.00, nrm = 32, interval = 169.50 */
/* 131 */ 0xac3d0e8b, /* cps = 2168.00, nrm = 32, interval = 162.75 */
/* 132 */ 0xac6d0e70, /* cps = 2264.00, nrm = 32, interval = 156.00 */
/* 133 */ 0xac9b0e57, /* cps = 2356.00, nrm = 32, interval = 149.75 */
/* 134 */ 0xaccd0e3f, /* cps = 2456.00, nrm = 32, interval = 143.75 */
/* 135 */ 0xacff0e28, /* cps = 2556.00, nrm = 32, interval = 138.00 */
/* 136 */ 0xad350e12, /* cps = 2664.00, nrm = 32, interval = 132.50 */
/* 137 */ 0xad6d0bf9, /* cps = 2776.00, nrm = 32, interval = 127.12 */
/* 138 */ 0xada70bd0, /* cps = 2892.00, nrm = 32, interval = 122.00 */
/* 139 */ 0xade30ba9, /* cps = 3012.00, nrm = 32, interval = 117.12 */
/* 140 */ 0xae230b83, /* cps = 3140.00, nrm = 32, interval = 112.38 */
/* 141 */ 0xae650b5f, /* cps = 3272.00, nrm = 32, interval = 107.88 */
/* 142 */ 0xaeab0b3c, /* cps = 3412.00, nrm = 32, interval = 103.50 */
/* 143 */ 0xaef10b1b, /* cps = 3552.00, nrm = 32, interval = 99.38 */
/* 144 */ 0xaf3b0afb, /* cps = 3700.00, nrm = 32, interval = 95.38 */
/* 145 */ 0xaf8b0adc, /* cps = 3860.00, nrm = 32, interval = 91.50 */
/* 146 */ 0xafd90abf, /* cps = 4016.00, nrm = 32, interval = 87.88 */
/* 147 */ 0xb0170aa3, /* cps = 4184.00, nrm = 32, interval = 84.38 */
/* 148 */ 0xb0430a87, /* cps = 4360.00, nrm = 32, interval = 80.88 */
/* 149 */ 0xb0710a6d, /* cps = 4544.00, nrm = 32, interval = 77.62 */
/* 150 */ 0xb0a10a54, /* cps = 4736.00, nrm = 32, interval = 74.50 */
/* 151 */ 0xb0d30a3c, /* cps = 4936.00, nrm = 32, interval = 71.50 */
/* 152 */ 0xb1070a25, /* cps = 5144.00, nrm = 32, interval = 68.62 */
/* 153 */ 0xb13d0a0f, /* cps = 5360.00, nrm = 32, interval = 65.88 */
/* 154 */ 0xb17507f4, /* cps = 5584.00, nrm = 32, interval = 63.25 */
/* 155 */ 0xb1af07cb, /* cps = 5816.00, nrm = 32, interval = 60.69 */
/* 156 */ 0xb1eb07a4, /* cps = 6056.00, nrm = 32, interval = 58.25 */
/* 157 */ 0xb22b077f, /* cps = 6312.00, nrm = 32, interval = 55.94 */
/* 158 */ 0xb26d075b, /* cps = 6576.00, nrm = 32, interval = 53.69 */
/* 159 */ 0xb2b30738, /* cps = 6856.00, nrm = 32, interval = 51.50 */
/* 160 */ 0xb2fb0717, /* cps = 7144.00, nrm = 32, interval = 49.44 */
/* 161 */ 0xb34506f7, /* cps = 7440.00, nrm = 32, interval = 47.44 */
/* 162 */ 0xb39306d9, /* cps = 7752.00, nrm = 32, interval = 45.56 */
/* 163 */ 0xb3e506bb, /* cps = 8080.00, nrm = 32, interval = 43.69 */
/* 164 */ 0xb41d069f, /* cps = 8416.00, nrm = 32, interval = 41.94 */
/* 165 */ 0xb4490684, /* cps = 8768.00, nrm = 32, interval = 40.25 */
/* 166 */ 0xb477066a, /* cps = 9136.00, nrm = 32, interval = 38.62 */
/* 167 */ 0xb4a70651, /* cps = 9520.00, nrm = 32, interval = 37.06 */
/* 168 */ 0xb4d90639, /* cps = 9920.00, nrm = 32, interval = 35.56 */
/* 169 */ 0xb50d0622, /* cps = 10336.00, nrm = 32, interval = 34.12 */
/* 170 */ 0xb545060c, /* cps = 10784.00, nrm = 32, interval = 32.75 */
/* 171 */ 0xb57b03ef, /* cps = 11216.00, nrm = 32, interval = 31.47 */
/* 172 */ 0xb5b503c7, /* cps = 11680.00, nrm = 32, interval = 30.22 */
/* 173 */ 0xb5f303a0, /* cps = 12176.00, nrm = 32, interval = 29.00 */
/* 174 */ 0xb633037a, /* cps = 12688.00, nrm = 32, interval = 27.81 */
/* 175 */ 0xb6750357, /* cps = 13216.00, nrm = 32, interval = 26.72 */
/* 176 */ 0xb6bb0334, /* cps = 13776.00, nrm = 32, interval = 25.62 */
/* 177 */ 0xb7030313, /* cps = 14352.00, nrm = 32, interval = 24.59 */
/* 178 */ 0xb74f02f3, /* cps = 14960.00, nrm = 32, interval = 23.59 */
/* 179 */ 0xb79d02d5, /* cps = 15584.00, nrm = 32, interval = 22.66 */
/* 180 */ 0xb7ed02b8, /* cps = 16224.00, nrm = 32, interval = 21.75 */
/* 181 */ 0xb821029c, /* cps = 16896.00, nrm = 32, interval = 20.88 */
/* 182 */ 0xb84f0281, /* cps = 17632.00, nrm = 32, interval = 20.03 */
/* 183 */ 0xb87d0267, /* cps = 18368.00, nrm = 32, interval = 19.22 */
/* 184 */ 0xb8ad024e, /* cps = 19136.00, nrm = 32, interval = 18.44 */
/* 185 */ 0xb8dd0237, /* cps = 19904.00, nrm = 32, interval = 17.72 */
/* 186 */ 0xb9130220, /* cps = 20768.00, nrm = 32, interval = 17.00 */
/* 187 */ 0xb949020a, /* cps = 21632.00, nrm = 32, interval = 16.31 */
/* 188 */ 0xb98301f5, /* cps = 22560.00, nrm = 32, interval = 15.66 */
/* 189 */ 0xb9bd01e1, /* cps = 23488.00, nrm = 32, interval = 15.03 */
/* 190 */ 0xb9fd01cd, /* cps = 24512.00, nrm = 32, interval = 14.41 */
/* 191 */ 0xba3b01bb, /* cps = 25504.00, nrm = 32, interval = 13.84 */
/* 192 */ 0xba7f01a9, /* cps = 26592.00, nrm = 32, interval = 13.28 */
/* 193 */ 0xbac30198, /* cps = 27680.00, nrm = 32, interval = 12.75 */
/* 194 */ 0xbb0f0187, /* cps = 28896.00, nrm = 32, interval = 12.22 */
/* 195 */ 0xbb570178, /* cps = 30048.00, nrm = 32, interval = 11.75 */
/* 196 */ 0xbbab0168, /* cps = 31392.00, nrm = 32, interval = 11.25 */
/* 197 */ 0xbbf9015a, /* cps = 32640.00, nrm = 32, interval = 10.81 */
/* 198 */ 0xbc27014c, /* cps = 33984.00, nrm = 32, interval = 10.38 */
/* 199 */ 0xbc53013f, /* cps = 35392.00, nrm = 32, interval = 9.97 */
/* 200 */ 0xbc830132, /* cps = 36928.00, nrm = 32, interval = 9.56 */
/* 201 */ 0xbcb50125, /* cps = 38528.00, nrm = 32, interval = 9.16 */
/* 202 */ 0xbce5011a, /* cps = 40064.00, nrm = 32, interval = 8.81 */
/* 203 */ 0xbd1d010e, /* cps = 41856.00, nrm = 32, interval = 8.44 */
/* 204 */ 0xbd530103, /* cps = 43584.00, nrm = 32, interval = 8.09 */
/* 205 */ 0xbd8b00f9, /* cps = 45376.00, nrm = 32, interval = 7.78 */
/* 206 */ 0xbdc500ef, /* cps = 47232.00, nrm = 32, interval = 7.47 */
/* 207 */ 0xbe0700e5, /* cps = 49344.00, nrm = 32, interval = 7.16 */
/* 208 */ 0xbe4500dc, /* cps = 51328.00, nrm = 32, interval = 6.88 */
/* 209 */ 0xbe8900d3, /* cps = 53504.00, nrm = 32, interval = 6.59 */
/* 210 */ 0xbecb00cb, /* cps = 55616.00, nrm = 32, interval = 6.34 */
/* 211 */ 0xbf1d00c2, /* cps = 58240.00, nrm = 32, interval = 6.06 */
/* 212 */ 0xbf6100bb, /* cps = 60416.00, nrm = 32, interval = 5.84 */
/* 213 */ 0xbfb500b3, /* cps = 63104.00, nrm = 32, interval = 5.59 */
/* 214 */ 0xc00300ac, /* cps = 65664.00, nrm = 32, interval = 5.38 */
/* 215 */ 0xc02f00a5, /* cps = 68480.00, nrm = 32, interval = 5.16 */
/* 216 */ 0xc05d009e, /* cps = 71424.00, nrm = 32, interval = 4.94 */
/* 217 */ 0xc0890098, /* cps = 74240.00, nrm = 32, interval = 4.75 */
/* 218 */ 0xc0b90092, /* cps = 77312.00, nrm = 32, interval = 4.56 */
/* 219 */ 0xc0ed008c, /* cps = 80640.00, nrm = 32, interval = 4.38 */
/* 220 */ 0xc1250086, /* cps = 84224.00, nrm = 32, interval = 4.19 */
/* 221 */ 0xc1590081, /* cps = 87552.00, nrm = 32, interval = 4.03 */
/* 222 */ 0xc191007c, /* cps = 91136.00, nrm = 32, interval = 3.88 */
/* 223 */ 0xc1cd0077, /* cps = 94976.00, nrm = 32, interval = 3.72 */
/* 224 */ 0xc20d0072, /* cps = 99072.00, nrm = 32, interval = 3.56 */
/* 225 */ 0xc255006d, /* cps = 103680.00, nrm = 32, interval = 3.41 */
/* 226 */ 0xc2910069, /* cps = 107520.00, nrm = 32, interval = 3.28 */
/* 227 */ 0xc2d50065, /* cps = 111872.00, nrm = 32, interval = 3.16 */
/* 228 */ 0xc32f0060, /* cps = 117632.00, nrm = 32, interval = 3.00 */
/* 229 */ 0xc36b005d, /* cps = 121472.00, nrm = 32, interval = 2.91 */
/* 230 */ 0xc3c10059, /* cps = 126976.00, nrm = 32, interval = 2.78 */
/* 231 */ 0xc40f0055, /* cps = 132864.00, nrm = 32, interval = 2.66 */
/* 232 */ 0xc4350052, /* cps = 137728.00, nrm = 32, interval = 2.56 */
/* 233 */ 0xc46d004e, /* cps = 144896.00, nrm = 32, interval = 2.44 */
/* 234 */ 0xc499004b, /* cps = 150528.00, nrm = 32, interval = 2.34 */
/* 235 */ 0xc4cb0048, /* cps = 156928.00, nrm = 32, interval = 2.25 */
/* 236 */ 0xc4ff0045, /* cps = 163584.00, nrm = 32, interval = 2.16 */
/* 237 */ 0xc5250043, /* cps = 168448.00, nrm = 32, interval = 2.09 */
/* 238 */ 0xc5630040, /* cps = 176384.00, nrm = 32, interval = 2.00 */
/* 239 */ 0xc5a7003d, /* cps = 185088.00, nrm = 32, interval = 1.91 */
/* 240 */ 0xc5d9003b, /* cps = 191488.00, nrm = 32, interval = 1.84 */
/* 241 */ 0xc6290038, /* cps = 201728.00, nrm = 32, interval = 1.75 */
/* 242 */ 0xc6630036, /* cps = 209152.00, nrm = 32, interval = 1.69 */
/* 243 */ 0xc6a30034, /* cps = 217344.00, nrm = 32, interval = 1.62 */
/* 244 */ 0xc6e70032, /* cps = 226048.00, nrm = 32, interval = 1.56 */
/* 245 */ 0xc72f0030, /* cps = 235264.00, nrm = 32, interval = 1.50 */
/* 246 */ 0xc77f002e, /* cps = 245504.00, nrm = 32, interval = 1.44 */
/* 247 */ 0xc7d7002c, /* cps = 256768.00, nrm = 32, interval = 1.38 */
/* 248 */ 0xc81b002a, /* cps = 268800.00, nrm = 32, interval = 1.31 */
/* 249 */ 0xc84f0028, /* cps = 282112.00, nrm = 32, interval = 1.25 */
/* 250 */ 0xc86d0027, /* cps = 289792.00, nrm = 32, interval = 1.22 */
/* 251 */ 0xc8a90025, /* cps = 305152.00, nrm = 32, interval = 1.16 */
/* 252 */ 0xc8cb0024, /* cps = 313856.00, nrm = 32, interval = 1.12 */
/* 253 */ 0xc9130022, /* cps = 332288.00, nrm = 32, interval = 1.06 */
/* 254 */ 0xc9390021, /* cps = 342016.00, nrm = 32, interval = 1.03 */
/* 255 */ 0xc9630020, /* cps = 352768.00, nrm = 32, interval = 1.00 */
};
static unsigned char rate_to_log[] =
{
/* 1.00 => 0 */ 0x00, /* => 10.02 */
/* 1.06 => 0 */ 0x00, /* => 10.02 */
/* 1.12 => 0 */ 0x00, /* => 10.02 */
/* 1.19 => 0 */ 0x00, /* => 10.02 */
/* 1.25 => 0 */ 0x00, /* => 10.02 */
/* 1.31 => 0 */ 0x00, /* => 10.02 */
/* 1.38 => 0 */ 0x00, /* => 10.02 */
/* 1.44 => 0 */ 0x00, /* => 10.02 */
/* 1.50 => 0 */ 0x00, /* => 10.02 */
/* 1.56 => 0 */ 0x00, /* => 10.02 */
/* 1.62 => 0 */ 0x00, /* => 10.02 */
/* 1.69 => 0 */ 0x00, /* => 10.02 */
/* 1.75 => 0 */ 0x00, /* => 10.02 */
/* 1.81 => 0 */ 0x00, /* => 10.02 */
/* 1.88 => 0 */ 0x00, /* => 10.02 */
/* 1.94 => 0 */ 0x00, /* => 10.02 */
/* 2.00 => 0 */ 0x00, /* => 10.02 */
/* 2.12 => 0 */ 0x00, /* => 10.02 */
/* 2.25 => 0 */ 0x00, /* => 10.02 */
/* 2.38 => 0 */ 0x00, /* => 10.02 */
/* 2.50 => 0 */ 0x00, /* => 10.02 */
/* 2.62 => 0 */ 0x00, /* => 10.02 */
/* 2.75 => 0 */ 0x00, /* => 10.02 */
/* 2.88 => 0 */ 0x00, /* => 10.02 */
/* 3.00 => 0 */ 0x00, /* => 10.02 */
/* 3.12 => 0 */ 0x00, /* => 10.02 */
/* 3.25 => 0 */ 0x00, /* => 10.02 */
/* 3.38 => 0 */ 0x00, /* => 10.02 */
/* 3.50 => 0 */ 0x00, /* => 10.02 */
/* 3.62 => 0 */ 0x00, /* => 10.02 */
/* 3.75 => 0 */ 0x00, /* => 10.02 */
/* 3.88 => 0 */ 0x00, /* => 10.02 */
/* 4.00 => 0 */ 0x00, /* => 10.02 */
/* 4.25 => 0 */ 0x00, /* => 10.02 */
/* 4.50 => 0 */ 0x00, /* => 10.02 */
/* 4.75 => 0 */ 0x00, /* => 10.02 */
/* 5.00 => 0 */ 0x00, /* => 10.02 */
/* 5.25 => 0 */ 0x00, /* => 10.02 */
/* 5.50 => 0 */ 0x00, /* => 10.02 */
/* 5.75 => 0 */ 0x00, /* => 10.02 */
/* 6.00 => 0 */ 0x00, /* => 10.02 */
/* 6.25 => 0 */ 0x00, /* => 10.02 */
/* 6.50 => 0 */ 0x00, /* => 10.02 */
/* 6.75 => 0 */ 0x00, /* => 10.02 */
/* 7.00 => 0 */ 0x00, /* => 10.02 */
/* 7.25 => 0 */ 0x00, /* => 10.02 */
/* 7.50 => 0 */ 0x00, /* => 10.02 */
/* 7.75 => 0 */ 0x00, /* => 10.02 */
/* 8.00 => 0 */ 0x00, /* => 10.02 */
/* 8.50 => 0 */ 0x00, /* => 10.02 */
/* 9.00 => 0 */ 0x00, /* => 10.02 */
/* 9.50 => 0 */ 0x00, /* => 10.02 */
/* 10.00 => 0 */ 0x00, /* => 10.02 */
/* 10.50 => 1 */ 0x01, /* => 10.42 */
/* 11.00 => 2 */ 0x02, /* => 10.86 */
/* 11.50 => 3 */ 0x03, /* => 11.31 */
/* 12.00 => 4 */ 0x04, /* => 11.78 */
/* 12.50 => 5 */ 0x05, /* => 12.28 */
/* 13.00 => 6 */ 0x06, /* => 12.80 */
/* 13.50 => 7 */ 0x07, /* => 13.33 */
/* 14.00 => 8 */ 0x08, /* => 13.89 */
/* 14.50 => 9 */ 0x09, /* => 14.48 */
/* 15.00 => 9 */ 0x09, /* => 14.48 */
/* 15.50 => 10 */ 0x0a, /* => 15.08 */
/* 16.00 => 11 */ 0x0b, /* => 15.72 */
/* 17.00 => 12 */ 0x0c, /* => 16.38 */
/* 18.00 => 14 */ 0x0e, /* => 17.75 */
/* 19.00 => 15 */ 0x0f, /* => 18.50 */
/* 20.00 => 16 */ 0x10, /* => 19.28 */
/* 21.00 => 18 */ 0x12, /* => 20.94 */
/* 22.00 => 19 */ 0x13, /* => 21.81 */
/* 23.00 => 20 */ 0x14, /* => 22.75 */
/* 24.00 => 21 */ 0x15, /* => 23.69 */
/* 25.00 => 22 */ 0x16, /* => 24.69 */
/* 26.00 => 23 */ 0x17, /* => 25.72 */
/* 27.00 => 24 */ 0x18, /* => 26.81 */
/* 28.00 => 25 */ 0x19, /* => 27.94 */
/* 29.00 => 25 */ 0x19, /* => 27.94 */
/* 30.00 => 26 */ 0x1a, /* => 29.09 */
/* 31.00 => 27 */ 0x1b, /* => 30.31 */
/* 32.00 => 28 */ 0x1c, /* => 31.56 */
/* 34.00 => 29 */ 0x1d, /* => 32.94 */
/* 36.00 => 31 */ 0x1f, /* => 35.69 */
/* 38.00 => 32 */ 0x20, /* => 37.19 */
/* 40.00 => 33 */ 0x21, /* => 38.75 */
/* 42.00 => 34 */ 0x22, /* => 40.38 */
/* 44.00 => 36 */ 0x24, /* => 43.88 */
/* 46.00 => 37 */ 0x25, /* => 45.69 */
/* 48.00 => 38 */ 0x26, /* => 47.62 */
/* 50.00 => 39 */ 0x27, /* => 49.62 */
/* 52.00 => 40 */ 0x28, /* => 51.69 */
/* 54.00 => 41 */ 0x29, /* => 53.88 */
/* 56.00 => 41 */ 0x29, /* => 53.88 */
/* 58.00 => 42 */ 0x2a, /* => 56.12 */
/* 60.00 => 43 */ 0x2b, /* => 58.44 */
/* 62.00 => 44 */ 0x2c, /* => 60.94 */
/* 64.00 => 45 */ 0x2d, /* => 63.50 */
/* 68.00 => 46 */ 0x2e, /* => 66.12 */
/* 72.00 => 48 */ 0x30, /* => 71.88 */
/* 76.00 => 49 */ 0x31, /* => 74.75 */
/* 80.00 => 50 */ 0x32, /* => 78.00 */
/* 84.00 => 51 */ 0x33, /* => 81.25 */
/* 88.00 => 52 */ 0x34, /* => 84.62 */
/* 92.00 => 54 */ 0x36, /* => 91.88 */
/* 96.00 => 55 */ 0x37, /* => 95.75 */
/* 100.00 => 56 */ 0x38, /* => 99.75 */
/* 104.00 => 56 */ 0x38, /* => 99.75 */
/* 108.00 => 57 */ 0x39, /* => 104.00 */
/* 112.00 => 58 */ 0x3a, /* => 108.25 */
/* 116.00 => 59 */ 0x3b, /* => 112.88 */
/* 120.00 => 60 */ 0x3c, /* => 117.50 */
/* 124.00 => 61 */ 0x3d, /* => 122.38 */
/* 128.00 => 62 */ 0x3e, /* => 127.50 */
/* 136.00 => 63 */ 0x3f, /* => 132.75 */
/* 144.00 => 64 */ 0x40, /* => 138.50 */
/* 152.00 => 66 */ 0x42, /* => 150.25 */
/* 160.00 => 67 */ 0x43, /* => 156.75 */
/* 168.00 => 68 */ 0x44, /* => 163.50 */
/* 176.00 => 69 */ 0x45, /* => 170.00 */
/* 184.00 => 70 */ 0x46, /* => 177.25 */
/* 192.00 => 71 */ 0x47, /* => 184.50 */
/* 200.00 => 72 */ 0x48, /* => 192.25 */
/* 208.00 => 73 */ 0x49, /* => 200.25 */
/* 216.00 => 74 */ 0x4a, /* => 208.75 */
/* 224.00 => 75 */ 0x4b, /* => 217.75 */
/* 232.00 => 76 */ 0x4c, /* => 226.75 */
/* 240.00 => 77 */ 0x4d, /* => 236.25 */
/* 248.00 => 78 */ 0x4e, /* => 246.25 */
/* 256.00 => 78 */ 0x4e, /* => 246.25 */
/* 272.00 => 80 */ 0x50, /* => 267.50 */
/* 288.00 => 81 */ 0x51, /* => 278.50 */
/* 304.00 => 83 */ 0x53, /* => 302.00 */
/* 320.00 => 84 */ 0x54, /* => 315.00 */
/* 336.00 => 85 */ 0x55, /* => 328.00 */
/* 352.00 => 86 */ 0x56, /* => 342.00 */
/* 368.00 => 87 */ 0x57, /* => 356.00 */
/* 384.00 => 88 */ 0x58, /* => 371.00 */
/* 400.00 => 89 */ 0x59, /* => 386.50 */
/* 416.00 => 90 */ 0x5a, /* => 403.00 */
/* 432.00 => 91 */ 0x5b, /* => 419.50 */
/* 448.00 => 92 */ 0x5c, /* => 437.50 */
/* 464.00 => 93 */ 0x5d, /* => 455.50 */
/* 480.00 => 94 */ 0x5e, /* => 475.00 */
/* 496.00 => 95 */ 0x5f, /* => 495.00 */
/* 512.00 => 95 */ 0x5f, /* => 495.00 */
/* 544.00 => 97 */ 0x61, /* => 537.00 */
/* 576.00 => 98 */ 0x62, /* => 559.00 */
/* 608.00 => 100 */ 0x64, /* => 607.00 */
/* 640.00 => 101 */ 0x65, /* => 632.00 */
/* 672.00 => 102 */ 0x66, /* => 660.00 */
/* 704.00 => 103 */ 0x67, /* => 687.00 */
/* 736.00 => 104 */ 0x68, /* => 716.00 */
/* 768.00 => 105 */ 0x69, /* => 746.00 */
/* 800.00 => 106 */ 0x6a, /* => 777.00 */
/* 832.00 => 107 */ 0x6b, /* => 810.00 */
/* 864.00 => 108 */ 0x6c, /* => 843.00 */
/* 896.00 => 109 */ 0x6d, /* => 879.00 */
/* 928.00 => 110 */ 0x6e, /* => 916.00 */
/* 960.00 => 111 */ 0x6f, /* => 954.00 */
/* 992.00 => 111 */ 0x6f, /* => 954.00 */
/* 1024.00 => 112 */ 0x70, /* => 994.00 */
/* 1088.00 => 114 */ 0x72, /* => 1080.00 */
/* 1152.00 => 115 */ 0x73, /* => 1124.00 */
/* 1216.00 => 116 */ 0x74, /* => 1172.00 */
/* 1280.00 => 118 */ 0x76, /* => 1272.00 */
/* 1344.00 => 119 */ 0x77, /* => 1326.00 */
/* 1408.00 => 120 */ 0x78, /* => 1382.00 */
/* 1472.00 => 121 */ 0x79, /* => 1440.00 */
/* 1536.00 => 122 */ 0x7a, /* => 1498.00 */
/* 1600.00 => 123 */ 0x7b, /* => 1562.00 */
/* 1664.00 => 124 */ 0x7c, /* => 1628.00 */
/* 1728.00 => 125 */ 0x7d, /* => 1696.00 */
/* 1792.00 => 126 */ 0x7e, /* => 1768.00 */
/* 1856.00 => 127 */ 0x7f, /* => 1842.00 */
/* 1920.00 => 128 */ 0x80, /* => 1918.00 */
/* 1984.00 => 128 */ 0x80, /* => 1918.00 */
/* 2048.00 => 129 */ 0x81, /* => 2000.00 */
/* 2176.00 => 131 */ 0x83, /* => 2168.00 */
/* 2304.00 => 132 */ 0x84, /* => 2264.00 */
/* 2432.00 => 133 */ 0x85, /* => 2356.00 */
/* 2560.00 => 135 */ 0x87, /* => 2556.00 */
/* 2688.00 => 136 */ 0x88, /* => 2664.00 */
/* 2816.00 => 137 */ 0x89, /* => 2776.00 */
/* 2944.00 => 138 */ 0x8a, /* => 2892.00 */
/* 3072.00 => 139 */ 0x8b, /* => 3012.00 */
/* 3200.00 => 140 */ 0x8c, /* => 3140.00 */
/* 3328.00 => 141 */ 0x8d, /* => 3272.00 */
/* 3456.00 => 142 */ 0x8e, /* => 3412.00 */
/* 3584.00 => 143 */ 0x8f, /* => 3552.00 */
/* 3712.00 => 144 */ 0x90, /* => 3700.00 */
/* 3840.00 => 144 */ 0x90, /* => 3700.00 */
/* 3968.00 => 145 */ 0x91, /* => 3860.00 */
/* 4096.00 => 146 */ 0x92, /* => 4016.00 */
/* 4352.00 => 147 */ 0x93, /* => 4184.00 */
/* 4608.00 => 149 */ 0x95, /* => 4544.00 */
/* 4864.00 => 150 */ 0x96, /* => 4736.00 */
/* 5120.00 => 151 */ 0x97, /* => 4936.00 */
/* 5376.00 => 153 */ 0x99, /* => 5360.00 */
/* 5632.00 => 154 */ 0x9a, /* => 5584.00 */
/* 5888.00 => 155 */ 0x9b, /* => 5816.00 */
/* 6144.00 => 156 */ 0x9c, /* => 6056.00 */
/* 6400.00 => 157 */ 0x9d, /* => 6312.00 */
/* 6656.00 => 158 */ 0x9e, /* => 6576.00 */
/* 6912.00 => 159 */ 0x9f, /* => 6856.00 */
/* 7168.00 => 160 */ 0xa0, /* => 7144.00 */
/* 7424.00 => 160 */ 0xa0, /* => 7144.00 */
/* 7680.00 => 161 */ 0xa1, /* => 7440.00 */
/* 7936.00 => 162 */ 0xa2, /* => 7752.00 */
/* 8192.00 => 163 */ 0xa3, /* => 8080.00 */
/* 8704.00 => 164 */ 0xa4, /* => 8416.00 */
/* 9216.00 => 166 */ 0xa6, /* => 9136.00 */
/* 9728.00 => 167 */ 0xa7, /* => 9520.00 */
/* 10240.00 => 168 */ 0xa8, /* => 9920.00 */
/* 10752.00 => 169 */ 0xa9, /* => 10336.00 */
/* 11264.00 => 171 */ 0xab, /* => 11216.00 */
/* 11776.00 => 172 */ 0xac, /* => 11680.00 */
/* 12288.00 => 173 */ 0xad, /* => 12176.00 */
/* 12800.00 => 174 */ 0xae, /* => 12688.00 */
/* 13312.00 => 175 */ 0xaf, /* => 13216.00 */
/* 13824.00 => 176 */ 0xb0, /* => 13776.00 */
/* 14336.00 => 176 */ 0xb0, /* => 13776.00 */
/* 14848.00 => 177 */ 0xb1, /* => 14352.00 */
/* 15360.00 => 178 */ 0xb2, /* => 14960.00 */
/* 15872.00 => 179 */ 0xb3, /* => 15584.00 */
/* 16384.00 => 180 */ 0xb4, /* => 16224.00 */
/* 17408.00 => 181 */ 0xb5, /* => 16896.00 */
/* 18432.00 => 183 */ 0xb7, /* => 18368.00 */
/* 19456.00 => 184 */ 0xb8, /* => 19136.00 */
/* 20480.00 => 185 */ 0xb9, /* => 19904.00 */
/* 21504.00 => 186 */ 0xba, /* => 20768.00 */
/* 22528.00 => 187 */ 0xbb, /* => 21632.00 */
/* 23552.00 => 189 */ 0xbd, /* => 23488.00 */
/* 24576.00 => 190 */ 0xbe, /* => 24512.00 */
/* 25600.00 => 191 */ 0xbf, /* => 25504.00 */
/* 26624.00 => 192 */ 0xc0, /* => 26592.00 */
/* 27648.00 => 192 */ 0xc0, /* => 26592.00 */
/* 28672.00 => 193 */ 0xc1, /* => 27680.00 */
/* 29696.00 => 194 */ 0xc2, /* => 28896.00 */
/* 30720.00 => 195 */ 0xc3, /* => 30048.00 */
/* 31744.00 => 196 */ 0xc4, /* => 31392.00 */
/* 32768.00 => 197 */ 0xc5, /* => 32640.00 */
/* 34816.00 => 198 */ 0xc6, /* => 33984.00 */
/* 36864.00 => 199 */ 0xc7, /* => 35392.00 */
/* 38912.00 => 201 */ 0xc9, /* => 38528.00 */
/* 40960.00 => 202 */ 0xca, /* => 40064.00 */
/* 43008.00 => 203 */ 0xcb, /* => 41856.00 */
/* 45056.00 => 204 */ 0xcc, /* => 43584.00 */
/* 47104.00 => 205 */ 0xcd, /* => 45376.00 */
/* 49152.00 => 206 */ 0xce, /* => 47232.00 */
/* 51200.00 => 207 */ 0xcf, /* => 49344.00 */
/* 53248.00 => 208 */ 0xd0, /* => 51328.00 */
/* 55296.00 => 209 */ 0xd1, /* => 53504.00 */
/* 57344.00 => 210 */ 0xd2, /* => 55616.00 */
/* 59392.00 => 211 */ 0xd3, /* => 58240.00 */
/* 61440.00 => 212 */ 0xd4, /* => 60416.00 */
/* 63488.00 => 213 */ 0xd5, /* => 63104.00 */
/* 65536.00 => 213 */ 0xd5, /* => 63104.00 */
/* 69632.00 => 215 */ 0xd7, /* => 68480.00 */
/* 73728.00 => 216 */ 0xd8, /* => 71424.00 */
/* 77824.00 => 218 */ 0xda, /* => 77312.00 */
/* 81920.00 => 219 */ 0xdb, /* => 80640.00 */
/* 86016.00 => 220 */ 0xdc, /* => 84224.00 */
/* 90112.00 => 221 */ 0xdd, /* => 87552.00 */
/* 94208.00 => 222 */ 0xde, /* => 91136.00 */
/* 98304.00 => 223 */ 0xdf, /* => 94976.00 */
/* 102400.00 => 224 */ 0xe0, /* => 99072.00 */
/* 106496.00 => 225 */ 0xe1, /* => 103680.00 */
/* 110592.00 => 226 */ 0xe2, /* => 107520.00 */
/* 114688.00 => 227 */ 0xe3, /* => 111872.00 */
/* 118784.00 => 228 */ 0xe4, /* => 117632.00 */
/* 122880.00 => 229 */ 0xe5, /* => 121472.00 */
/* 126976.00 => 229 */ 0xe5, /* => 121472.00 */
/* 131072.00 => 230 */ 0xe6, /* => 126976.00 */
/* 139264.00 => 232 */ 0xe8, /* => 137728.00 */
/* 147456.00 => 233 */ 0xe9, /* => 144896.00 */
/* 155648.00 => 234 */ 0xea, /* => 150528.00 */
/* 163840.00 => 236 */ 0xec, /* => 163584.00 */
/* 172032.00 => 237 */ 0xed, /* => 168448.00 */
/* 180224.00 => 238 */ 0xee, /* => 176384.00 */
/* 188416.00 => 239 */ 0xef, /* => 185088.00 */
/* 196608.00 => 240 */ 0xf0, /* => 191488.00 */
/* 204800.00 => 241 */ 0xf1, /* => 201728.00 */
/* 212992.00 => 242 */ 0xf2, /* => 209152.00 */
/* 221184.00 => 243 */ 0xf3, /* => 217344.00 */
/* 229376.00 => 244 */ 0xf4, /* => 226048.00 */
/* 237568.00 => 245 */ 0xf5, /* => 235264.00 */
/* 245760.00 => 246 */ 0xf6, /* => 245504.00 */
/* 253952.00 => 246 */ 0xf6, /* => 245504.00 */
/* 262144.00 => 247 */ 0xf7, /* => 256768.00 */
/* 278528.00 => 248 */ 0xf8, /* => 268800.00 */
/* 294912.00 => 250 */ 0xfa, /* => 289792.00 */
/* 311296.00 => 251 */ 0xfb, /* => 305152.00 */
/* 327680.00 => 252 */ 0xfc, /* => 313856.00 */
/* 344064.00 => 254 */ 0xfe, /* => 342016.00 */
/* 360448.00 => 255 */ 0xff, /* => 352768.00 */
/* 376832.00 => 255 */ 0xff, /* => 352768.00 */
/* 393216.00 => 255 */ 0xff, /* => 352768.00 */
/* 409600.00 => 255 */ 0xff, /* => 352768.00 */
/* 425984.00 => 255 */ 0xff, /* => 352768.00 */
/* 442368.00 => 255 */ 0xff, /* => 352768.00 */
/* 458752.00 => 255 */ 0xff, /* => 352768.00 */
/* 475136.00 => 255 */ 0xff, /* => 352768.00 */
/* 491520.00 => 255 */ 0xff, /* => 352768.00 */
/* 507904.00 => 255 */ 0xff, /* => 352768.00 */
/* 524288.00 => 255 */ 0xff, /* => 352768.00 */
/* 557056.00 => 255 */ 0xff, /* => 352768.00 */
/* 589824.00 => 255 */ 0xff, /* => 352768.00 */
/* 622592.00 => 255 */ 0xff, /* => 352768.00 */
/* 655360.00 => 255 */ 0xff, /* => 352768.00 */
/* 688128.00 => 255 */ 0xff, /* => 352768.00 */
/* 720896.00 => 255 */ 0xff, /* => 352768.00 */
/* 753664.00 => 255 */ 0xff, /* => 352768.00 */
/* 786432.00 => 255 */ 0xff, /* => 352768.00 */
/* 819200.00 => 255 */ 0xff, /* => 352768.00 */
/* 851968.00 => 255 */ 0xff, /* => 352768.00 */
/* 884736.00 => 255 */ 0xff, /* => 352768.00 */
/* 917504.00 => 255 */ 0xff, /* => 352768.00 */
/* 950272.00 => 255 */ 0xff, /* => 352768.00 */
/* 983040.00 => 255 */ 0xff, /* => 352768.00 */
/* 1015808.00 => 255 */ 0xff, /* => 352768.00 */
/* 1048576.00 => 255 */ 0xff, /* => 352768.00 */
/* 1114112.00 => 255 */ 0xff, /* => 352768.00 */
/* 1179648.00 => 255 */ 0xff, /* => 352768.00 */
/* 1245184.00 => 255 */ 0xff, /* => 352768.00 */
/* 1310720.00 => 255 */ 0xff, /* => 352768.00 */
/* 1376256.00 => 255 */ 0xff, /* => 352768.00 */
/* 1441792.00 => 255 */ 0xff, /* => 352768.00 */
/* 1507328.00 => 255 */ 0xff, /* => 352768.00 */
/* 1572864.00 => 255 */ 0xff, /* => 352768.00 */
/* 1638400.00 => 255 */ 0xff, /* => 352768.00 */
/* 1703936.00 => 255 */ 0xff, /* => 352768.00 */
/* 1769472.00 => 255 */ 0xff, /* => 352768.00 */
/* 1835008.00 => 255 */ 0xff, /* => 352768.00 */
/* 1900544.00 => 255 */ 0xff, /* => 352768.00 */
/* 1966080.00 => 255 */ 0xff, /* => 352768.00 */
/* 2031616.00 => 255 */ 0xff, /* => 352768.00 */
/* 2097152.00 => 255 */ 0xff, /* => 352768.00 */
/* 2228224.00 => 255 */ 0xff, /* => 352768.00 */
/* 2359296.00 => 255 */ 0xff, /* => 352768.00 */
/* 2490368.00 => 255 */ 0xff, /* => 352768.00 */
/* 2621440.00 => 255 */ 0xff, /* => 352768.00 */
/* 2752512.00 => 255 */ 0xff, /* => 352768.00 */
/* 2883584.00 => 255 */ 0xff, /* => 352768.00 */
/* 3014656.00 => 255 */ 0xff, /* => 352768.00 */
/* 3145728.00 => 255 */ 0xff, /* => 352768.00 */
/* 3276800.00 => 255 */ 0xff, /* => 352768.00 */
/* 3407872.00 => 255 */ 0xff, /* => 352768.00 */
/* 3538944.00 => 255 */ 0xff, /* => 352768.00 */
/* 3670016.00 => 255 */ 0xff, /* => 352768.00 */
/* 3801088.00 => 255 */ 0xff, /* => 352768.00 */
/* 3932160.00 => 255 */ 0xff, /* => 352768.00 */
/* 4063232.00 => 255 */ 0xff, /* => 352768.00 */
/* 4194304.00 => 255 */ 0xff, /* => 352768.00 */
/* 4456448.00 => 255 */ 0xff, /* => 352768.00 */
/* 4718592.00 => 255 */ 0xff, /* => 352768.00 */
/* 4980736.00 => 255 */ 0xff, /* => 352768.00 */
/* 5242880.00 => 255 */ 0xff, /* => 352768.00 */
/* 5505024.00 => 255 */ 0xff, /* => 352768.00 */
/* 5767168.00 => 255 */ 0xff, /* => 352768.00 */
/* 6029312.00 => 255 */ 0xff, /* => 352768.00 */
/* 6291456.00 => 255 */ 0xff, /* => 352768.00 */
/* 6553600.00 => 255 */ 0xff, /* => 352768.00 */
/* 6815744.00 => 255 */ 0xff, /* => 352768.00 */
/* 7077888.00 => 255 */ 0xff, /* => 352768.00 */
/* 7340032.00 => 255 */ 0xff, /* => 352768.00 */
/* 7602176.00 => 255 */ 0xff, /* => 352768.00 */
/* 7864320.00 => 255 */ 0xff, /* => 352768.00 */
/* 8126464.00 => 255 */ 0xff, /* => 352768.00 */
/* 8388608.00 => 255 */ 0xff, /* => 352768.00 */
/* 8912896.00 => 255 */ 0xff, /* => 352768.00 */
/* 9437184.00 => 255 */ 0xff, /* => 352768.00 */
/* 9961472.00 => 255 */ 0xff, /* => 352768.00 */
/* 10485760.00 => 255 */ 0xff, /* => 352768.00 */
/* 11010048.00 => 255 */ 0xff, /* => 352768.00 */
/* 11534336.00 => 255 */ 0xff, /* => 352768.00 */
/* 12058624.00 => 255 */ 0xff, /* => 352768.00 */
/* 12582912.00 => 255 */ 0xff, /* => 352768.00 */
/* 13107200.00 => 255 */ 0xff, /* => 352768.00 */
/* 13631488.00 => 255 */ 0xff, /* => 352768.00 */
/* 14155776.00 => 255 */ 0xff, /* => 352768.00 */
/* 14680064.00 => 255 */ 0xff, /* => 352768.00 */
/* 15204352.00 => 255 */ 0xff, /* => 352768.00 */
/* 15728640.00 => 255 */ 0xff, /* => 352768.00 */
/* 16252928.00 => 255 */ 0xff, /* => 352768.00 */
/* 16777216.00 => 255 */ 0xff, /* => 352768.00 */
/* 17825792.00 => 255 */ 0xff, /* => 352768.00 */
/* 18874368.00 => 255 */ 0xff, /* => 352768.00 */
/* 19922944.00 => 255 */ 0xff, /* => 352768.00 */
/* 20971520.00 => 255 */ 0xff, /* => 352768.00 */
/* 22020096.00 => 255 */ 0xff, /* => 352768.00 */
/* 23068672.00 => 255 */ 0xff, /* => 352768.00 */
/* 24117248.00 => 255 */ 0xff, /* => 352768.00 */
/* 25165824.00 => 255 */ 0xff, /* => 352768.00 */
/* 26214400.00 => 255 */ 0xff, /* => 352768.00 */
/* 27262976.00 => 255 */ 0xff, /* => 352768.00 */
/* 28311552.00 => 255 */ 0xff, /* => 352768.00 */
/* 29360128.00 => 255 */ 0xff, /* => 352768.00 */
/* 30408704.00 => 255 */ 0xff, /* => 352768.00 */
/* 31457280.00 => 255 */ 0xff, /* => 352768.00 */
/* 32505856.00 => 255 */ 0xff, /* => 352768.00 */
/* 33554432.00 => 255 */ 0xff, /* => 352768.00 */
/* 35651584.00 => 255 */ 0xff, /* => 352768.00 */
/* 37748736.00 => 255 */ 0xff, /* => 352768.00 */
/* 39845888.00 => 255 */ 0xff, /* => 352768.00 */
/* 41943040.00 => 255 */ 0xff, /* => 352768.00 */
/* 44040192.00 => 255 */ 0xff, /* => 352768.00 */
/* 46137344.00 => 255 */ 0xff, /* => 352768.00 */
/* 48234496.00 => 255 */ 0xff, /* => 352768.00 */
/* 50331648.00 => 255 */ 0xff, /* => 352768.00 */
/* 52428800.00 => 255 */ 0xff, /* => 352768.00 */
/* 54525952.00 => 255 */ 0xff, /* => 352768.00 */
/* 56623104.00 => 255 */ 0xff, /* => 352768.00 */
/* 58720256.00 => 255 */ 0xff, /* => 352768.00 */
/* 60817408.00 => 255 */ 0xff, /* => 352768.00 */
/* 62914560.00 => 255 */ 0xff, /* => 352768.00 */
/* 65011712.00 => 255 */ 0xff, /* => 352768.00 */
/* 67108864.00 => 255 */ 0xff, /* => 352768.00 */
/* 71303168.00 => 255 */ 0xff, /* => 352768.00 */
/* 75497472.00 => 255 */ 0xff, /* => 352768.00 */
/* 79691776.00 => 255 */ 0xff, /* => 352768.00 */
/* 83886080.00 => 255 */ 0xff, /* => 352768.00 */
/* 88080384.00 => 255 */ 0xff, /* => 352768.00 */
/* 92274688.00 => 255 */ 0xff, /* => 352768.00 */
/* 96468992.00 => 255 */ 0xff, /* => 352768.00 */
/* 100663296.00 => 255 */ 0xff, /* => 352768.00 */
/* 104857600.00 => 255 */ 0xff, /* => 352768.00 */
/* 109051904.00 => 255 */ 0xff, /* => 352768.00 */
/* 113246208.00 => 255 */ 0xff, /* => 352768.00 */
/* 117440512.00 => 255 */ 0xff, /* => 352768.00 */
/* 121634816.00 => 255 */ 0xff, /* => 352768.00 */
/* 125829120.00 => 255 */ 0xff, /* => 352768.00 */
/* 130023424.00 => 255 */ 0xff, /* => 352768.00 */
/* 134217728.00 => 255 */ 0xff, /* => 352768.00 */
/* 142606336.00 => 255 */ 0xff, /* => 352768.00 */
/* 150994944.00 => 255 */ 0xff, /* => 352768.00 */
/* 159383552.00 => 255 */ 0xff, /* => 352768.00 */
/* 167772160.00 => 255 */ 0xff, /* => 352768.00 */
/* 176160768.00 => 255 */ 0xff, /* => 352768.00 */
/* 184549376.00 => 255 */ 0xff, /* => 352768.00 */
/* 192937984.00 => 255 */ 0xff, /* => 352768.00 */
/* 201326592.00 => 255 */ 0xff, /* => 352768.00 */
/* 209715200.00 => 255 */ 0xff, /* => 352768.00 */
/* 218103808.00 => 255 */ 0xff, /* => 352768.00 */
/* 226492416.00 => 255 */ 0xff, /* => 352768.00 */
/* 234881024.00 => 255 */ 0xff, /* => 352768.00 */
/* 243269632.00 => 255 */ 0xff, /* => 352768.00 */
/* 251658240.00 => 255 */ 0xff, /* => 352768.00 */
/* 260046848.00 => 255 */ 0xff, /* => 352768.00 */
/* 268435456.00 => 255 */ 0xff, /* => 352768.00 */
/* 285212672.00 => 255 */ 0xff, /* => 352768.00 */
/* 301989888.00 => 255 */ 0xff, /* => 352768.00 */
/* 318767104.00 => 255 */ 0xff, /* => 352768.00 */
/* 335544320.00 => 255 */ 0xff, /* => 352768.00 */
/* 352321536.00 => 255 */ 0xff, /* => 352768.00 */
/* 369098752.00 => 255 */ 0xff, /* => 352768.00 */
/* 385875968.00 => 255 */ 0xff, /* => 352768.00 */
/* 402653184.00 => 255 */ 0xff, /* => 352768.00 */
/* 419430400.00 => 255 */ 0xff, /* => 352768.00 */
/* 436207616.00 => 255 */ 0xff, /* => 352768.00 */
/* 452984832.00 => 255 */ 0xff, /* => 352768.00 */
/* 469762048.00 => 255 */ 0xff, /* => 352768.00 */
/* 486539264.00 => 255 */ 0xff, /* => 352768.00 */
/* 503316480.00 => 255 */ 0xff, /* => 352768.00 */
/* 520093696.00 => 255 */ 0xff, /* => 352768.00 */
/* 536870912.00 => 255 */ 0xff, /* => 352768.00 */
/* 570425344.00 => 255 */ 0xff, /* => 352768.00 */
/* 603979776.00 => 255 */ 0xff, /* => 352768.00 */
/* 637534208.00 => 255 */ 0xff, /* => 352768.00 */
/* 671088640.00 => 255 */ 0xff, /* => 352768.00 */
/* 704643072.00 => 255 */ 0xff, /* => 352768.00 */
/* 738197504.00 => 255 */ 0xff, /* => 352768.00 */
/* 771751936.00 => 255 */ 0xff, /* => 352768.00 */
/* 805306368.00 => 255 */ 0xff, /* => 352768.00 */
/* 838860800.00 => 255 */ 0xff, /* => 352768.00 */
/* 872415232.00 => 255 */ 0xff, /* => 352768.00 */
/* 905969664.00 => 255 */ 0xff, /* => 352768.00 */
/* 939524096.00 => 255 */ 0xff, /* => 352768.00 */
/* 973078528.00 => 255 */ 0xff, /* => 352768.00 */
/* 1006632960.00 => 255 */ 0xff, /* => 352768.00 */
/* 1040187392.00 => 255 */ 0xff, /* => 352768.00 */
/* 1073741824.00 => 255 */ 0xff, /* => 352768.00 */
/* 1140850688.00 => 255 */ 0xff, /* => 352768.00 */
/* 1207959552.00 => 255 */ 0xff, /* => 352768.00 */
/* 1275068416.00 => 255 */ 0xff, /* => 352768.00 */
/* 1342177280.00 => 255 */ 0xff, /* => 352768.00 */
/* 1409286144.00 => 255 */ 0xff, /* => 352768.00 */
/* 1476395008.00 => 255 */ 0xff, /* => 352768.00 */
/* 1543503872.00 => 255 */ 0xff, /* => 352768.00 */
/* 1610612736.00 => 255 */ 0xff, /* => 352768.00 */
/* 1677721600.00 => 255 */ 0xff, /* => 352768.00 */
/* 1744830464.00 => 255 */ 0xff, /* => 352768.00 */
/* 1811939328.00 => 255 */ 0xff, /* => 352768.00 */
/* 1879048192.00 => 255 */ 0xff, /* => 352768.00 */
/* 1946157056.00 => 255 */ 0xff, /* => 352768.00 */
/* 2013265920.00 => 255 */ 0xff, /* => 352768.00 */
/* 2080374784.00 => 255 */ 0xff, /* => 352768.00 */
/* 2147483648.00 => 255 */ 0xff, /* => 352768.00 */
/* 2281701376.00 => 255 */ 0xff, /* => 352768.00 */
/* 2415919104.00 => 255 */ 0xff, /* => 352768.00 */
/* 2550136832.00 => 255 */ 0xff, /* => 352768.00 */
/* 2684354560.00 => 255 */ 0xff, /* => 352768.00 */
/* 2818572288.00 => 255 */ 0xff, /* => 352768.00 */
/* 2952790016.00 => 255 */ 0xff, /* => 352768.00 */
/* 3087007744.00 => 255 */ 0xff, /* => 352768.00 */
/* 3221225472.00 => 255 */ 0xff, /* => 352768.00 */
/* 3355443200.00 => 255 */ 0xff, /* => 352768.00 */
/* 3489660928.00 => 255 */ 0xff, /* => 352768.00 */
/* 3623878656.00 => 255 */ 0xff, /* => 352768.00 */
/* 3758096384.00 => 255 */ 0xff, /* => 352768.00 */
/* 3892314112.00 => 255 */ 0xff, /* => 352768.00 */
/* 4026531840.00 => 255 */ 0xff, /* => 352768.00 */
/* 4160749568.00 => 255 */ 0xff, /* => 352768.00 */
};

3296
drivers/atm/iphase.c Normal file

File diff suppressed because it is too large Load diff

1453
drivers/atm/iphase.h Normal file

File diff suppressed because it is too large Load diff

2621
drivers/atm/lanai.c Normal file

File diff suppressed because it is too large Load diff

265
drivers/atm/midway.h Normal file
View file

@ -0,0 +1,265 @@
/* drivers/atm/midway.h - Efficient Networks Midway (SAR) description */
/* Written 1995-1999 by Werner Almesberger, EPFL LRC/ICA */
#ifndef DRIVERS_ATM_MIDWAY_H
#define DRIVERS_ATM_MIDWAY_H
#define NR_VCI 1024 /* number of VCIs */
#define NR_VCI_LD 10 /* log2(NR_VCI) */
#define NR_DMA_RX 512 /* RX DMA queue entries */
#define NR_DMA_TX 512 /* TX DMA queue entries */
#define NR_SERVICE NR_VCI /* service list size */
#define NR_CHAN 8 /* number of TX channels */
#define TS_CLOCK 25000000 /* traffic shaper clock (cell/sec) */
#define MAP_MAX_SIZE 0x00400000 /* memory window for max config */
#define EPROM_SIZE 0x00010000
#define MEM_VALID 0xffc00000 /* mask base address with this */
#define PHY_BASE 0x00020000 /* offset of PHY register are */
#define REG_BASE 0x00040000 /* offset of Midway register area */
#define RAM_BASE 0x00200000 /* offset of RAM area */
#define RAM_INCREMENT 0x00020000 /* probe for RAM every 128kB */
#define MID_VCI_BASE RAM_BASE
#define MID_DMA_RX_BASE (MID_VCI_BASE+NR_VCI*16)
#define MID_DMA_TX_BASE (MID_DMA_RX_BASE+NR_DMA_RX*8)
#define MID_SERVICE_BASE (MID_DMA_TX_BASE+NR_DMA_TX*8)
#define MID_FREE_BASE (MID_SERVICE_BASE+NR_SERVICE*4)
#define MAC_LEN 6 /* atm.h */
#define MID_MIN_BUF_SIZE (1024) /* 1 kB is minimum */
#define MID_MAX_BUF_SIZE (128*1024) /* 128 kB is maximum */
#define RX_DESCR_SIZE 1 /* RX PDU descr is 1 longword */
#define TX_DESCR_SIZE 2 /* TX PDU descr is 2 longwords */
#define AAL5_TRAILER (ATM_AAL5_TRAILER/4) /* AAL5 trailer is 2 longwords */
#define TX_GAP 8 /* TX buffer gap (words) */
/*
* Midway Reset/ID
*
* All values read-only. Writing to this register resets Midway chip.
*/
#define MID_RES_ID_MCON 0x00 /* Midway Reset/ID */
#define MID_ID 0xf0000000 /* Midway version */
#define MID_SHIFT 24
#define MID_MOTHER_ID 0x00000700 /* mother board id */
#define MID_MOTHER_SHIFT 8
#define MID_CON_TI 0x00000080 /* 0: normal ctrl; 1: SABRE */
#define MID_CON_SUNI 0x00000040 /* 0: UTOPIA; 1: SUNI */
#define MID_CON_V6 0x00000020 /* 0: non-pipel UTOPIA (required iff
!CON_SUNI; 1: UTOPIA */
#define DAUGTHER_ID 0x0000001f /* daugther board id */
/*
* Interrupt Status Acknowledge, Interrupt Status & Interrupt Enable
*/
#define MID_ISA 0x01 /* Interrupt Status Acknowledge */
#define MID_IS 0x02 /* Interrupt Status */
#define MID_IE 0x03 /* Interrupt Enable */
#define MID_TX_COMPLETE_7 0x00010000 /* channel N completed a PDU */
#define MID_TX_COMPLETE_6 0x00008000 /* transmission */
#define MID_TX_COMPLETE_5 0x00004000
#define MID_TX_COMPLETE_4 0x00002000
#define MID_TX_COMPLETE_3 0x00001000
#define MID_TX_COMPLETE_2 0x00000800
#define MID_TX_COMPLETE_1 0x00000400
#define MID_TX_COMPLETE_0 0x00000200
#define MID_TX_COMPLETE 0x0001fe00 /* any TX */
#define MID_TX_DMA_OVFL 0x00000100 /* DMA to adapter overflow */
#define MID_TX_IDENT_MISM 0x00000080 /* TX: ident mismatch => halted */
#define MID_DMA_LERR_ACK 0x00000040 /* LERR - SBus ? */
#define MID_DMA_ERR_ACK 0x00000020 /* DMA error */
#define MID_RX_DMA_COMPLETE 0x00000010 /* DMA to host done */
#define MID_TX_DMA_COMPLETE 0x00000008 /* DMA from host done */
#define MID_SERVICE 0x00000004 /* something in service list */
#define MID_SUNI_INT 0x00000002 /* interrupt from SUNI */
#define MID_STAT_OVFL 0x00000001 /* statistics overflow */
/*
* Master Control/Status
*/
#define MID_MC_S 0x04
#define MID_INT_SELECT 0x000001C0 /* Interrupt level (000: off) */
#define MID_INT_SEL_SHIFT 6
#define MID_TX_LOCK_MODE 0x00000020 /* 0: streaming; 1: TX ovfl->lock */
#define MID_DMA_ENABLE 0x00000010 /* R: 0: disable; 1: enable
W: 0: no change; 1: enable */
#define MID_TX_ENABLE 0x00000008 /* R: 0: TX disabled; 1: enabled
W: 0: no change; 1: enable */
#define MID_RX_ENABLE 0x00000004 /* like TX */
#define MID_WAIT_1MS 0x00000002 /* R: 0: timer not running; 1: running
W: 0: no change; 1: no interrupts
for 1 ms */
#define MID_WAIT_500US 0x00000001 /* like WAIT_1MS, but 0.5 ms */
/*
* Statistics
*
* Cleared when reading.
*/
#define MID_STAT 0x05
#define MID_VCI_TRASH 0xFFFF0000 /* trashed cells because of VCI mode */
#define MID_VCI_TRASH_SHIFT 16
#define MID_OVFL_TRASH 0x0000FFFF /* trashed cells because of overflow */
/*
* Address registers
*/
#define MID_SERV_WRITE 0x06 /* free pos in service area (R, 10 bits) */
#define MID_DMA_ADDR 0x07 /* virtual DMA address (R, 32 bits) */
#define MID_DMA_WR_RX 0x08 /* (RW, 9 bits) */
#define MID_DMA_RD_RX 0x09
#define MID_DMA_WR_TX 0x0A
#define MID_DMA_RD_TX 0x0B
/*
* Transmit Place Registers (0x10+4*channel)
*/
#define MID_TX_PLACE(c) (0x10+4*(c))
#define MID_SIZE 0x00003800 /* size, N*256 x 32 bit */
#define MID_SIZE_SHIFT 11
#define MID_LOCATION 0x000007FF /* location in adapter memory (word) */
#define MID_LOC_SKIP 8 /* 8 bits of location are always zero
(applies to all uses of location) */
/*
* Transmit ReadPtr Registers (0x11+4*channel)
*/
#define MID_TX_RDPTR(c) (0x11+4*(c))
#define MID_READ_PTR 0x00007FFF /* next word for PHY */
/*
* Transmit DescrStart Registers (0x12+4*channel)
*/
#define MID_TX_DESCRSTART(c) (0x12+4*(c))
#define MID_DESCR_START 0x00007FFF /* seg buffer being DMAed */
#define ENI155_MAGIC 0xa54b872d
struct midway_eprom {
unsigned char mac[MAC_LEN],inv_mac[MAC_LEN];
unsigned char pad[36];
u32 serial,inv_serial;
u32 magic,inv_magic;
};
/*
* VCI table entry
*/
#define MID_VCI_IN_SERVICE 0x00000001 /* set if VCI is currently in
service list */
#define MID_VCI_SIZE 0x00038000 /* reassembly buffer size,
2*<size> kB */
#define MID_VCI_SIZE_SHIFT 15
#define MID_VCI_LOCATION 0x1ffc0000 /* buffer location */
#define MID_VCI_LOCATION_SHIFT 18
#define MID_VCI_PTI_MODE 0x20000000 /* 0: trash, 1: preserve */
#define MID_VCI_MODE 0xc0000000
#define MID_VCI_MODE_SHIFT 30
#define MID_VCI_READ 0x00007fff
#define MID_VCI_READ_SHIFT 0
#define MID_VCI_DESCR 0x7fff0000
#define MID_VCI_DESCR_SHIFT 16
#define MID_VCI_COUNT 0x000007ff
#define MID_VCI_COUNT_SHIFT 0
#define MID_VCI_STATE 0x0000c000
#define MID_VCI_STATE_SHIFT 14
#define MID_VCI_WRITE 0x7fff0000
#define MID_VCI_WRITE_SHIFT 16
#define MID_MODE_TRASH 0
#define MID_MODE_RAW 1
#define MID_MODE_AAL5 2
/*
* Reassembly buffer descriptor
*/
#define MID_RED_COUNT 0x000007ff
#define MID_RED_CRC_ERR 0x00000800
#define MID_RED_T 0x00001000
#define MID_RED_CE 0x00010000
#define MID_RED_CLP 0x01000000
#define MID_RED_IDEN 0xfe000000
#define MID_RED_SHIFT 25
#define MID_RED_RX_ID 0x1b /* constant identifier */
/*
* Segmentation buffer descriptor
*/
#define MID_SEG_COUNT MID_RED_COUNT
#define MID_SEG_RATE 0x01f80000
#define MID_SEG_RATE_SHIFT 19
#define MID_SEG_PR 0x06000000
#define MID_SEG_PR_SHIFT 25
#define MID_SEG_AAL5 0x08000000
#define MID_SEG_ID 0xf0000000
#define MID_SEG_ID_SHIFT 28
#define MID_SEG_MAX_RATE 63
#define MID_SEG_CLP 0x00000001
#define MID_SEG_PTI 0x0000000e
#define MID_SEG_PTI_SHIFT 1
#define MID_SEG_VCI 0x00003ff0
#define MID_SEG_VCI_SHIFT 4
#define MID_SEG_TX_ID 0xb /* constant identifier */
/*
* DMA entry
*/
#define MID_DMA_COUNT 0xffff0000
#define MID_DMA_COUNT_SHIFT 16
#define MID_DMA_END 0x00000020
#define MID_DMA_TYPE 0x0000000f
#define MID_DT_JK 0x3
#define MID_DT_WORD 0x0
#define MID_DT_2W 0x7
#define MID_DT_4W 0x4
#define MID_DT_8W 0x5
#define MID_DT_16W 0x6
#define MID_DT_2WM 0xf
#define MID_DT_4WM 0xc
#define MID_DT_8WM 0xd
#define MID_DT_16WM 0xe
/* only for RX*/
#define MID_DMA_VCI 0x0000ffc0
#define MID_DMA_VCI_SHIFT 6
/* only for TX */
#define MID_DMA_CHAN 0x000001c0
#define MID_DMA_CHAN_SHIFT 6
#define MID_DT_BYTE 0x1
#define MID_DT_HWORD 0x2
#endif

2837
drivers/atm/nicstar.c Normal file

File diff suppressed because it is too large Load diff

758
drivers/atm/nicstar.h Normal file
View file

@ -0,0 +1,758 @@
/*
* nicstar.h
*
* Header file for the nicstar device driver.
*
* Author: Rui Prior (rprior@inescn.pt)
* PowerPC support by Jay Talbott (jay_talbott@mcg.mot.com) April 1999
*
* (C) INESC 1998
*/
#ifndef _LINUX_NICSTAR_H_
#define _LINUX_NICSTAR_H_
/* Includes */
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/idr.h>
#include <linux/uio.h>
#include <linux/skbuff.h>
#include <linux/atmdev.h>
#include <linux/atm_nicstar.h>
/* Options */
#define NS_MAX_CARDS 4 /* Maximum number of NICStAR based cards
controlled by the device driver. Must
be <= 5 */
#undef RCQ_SUPPORT /* Do not define this for now */
#define NS_TST_NUM_ENTRIES 2340 /* + 1 for return */
#define NS_TST_RESERVED 340 /* N. entries reserved for UBR/ABR/VBR */
#define NS_SMBUFSIZE 48 /* 48, 96, 240 or 2048 */
#define NS_LGBUFSIZE 16384 /* 2048, 4096, 8192 or 16384 */
#define NS_RSQSIZE 8192 /* 2048, 4096 or 8192 */
#define NS_VPIBITS 2 /* 0, 1, 2, or 8 */
#define NS_MAX_RCTSIZE 4096 /* Number of entries. 4096 or 16384.
Define 4096 only if (all) your card(s)
have 32K x 32bit SRAM, in which case
setting this to 16384 will just waste a
lot of memory.
Setting this to 4096 for a card with
128K x 32bit SRAM will limit the maximum
VCI. */
/*#define NS_PCI_LATENCY 64*//* Must be a multiple of 32 */
/* Number of buffers initially allocated */
#define NUM_SB 32 /* Must be even */
#define NUM_LB 24 /* Must be even */
#define NUM_HB 8 /* Pre-allocated huge buffers */
#define NUM_IOVB 48 /* Iovec buffers */
/* Lower level for count of buffers */
#define MIN_SB 8 /* Must be even */
#define MIN_LB 8 /* Must be even */
#define MIN_HB 6
#define MIN_IOVB 8
/* Upper level for count of buffers */
#define MAX_SB 64 /* Must be even, <= 508 */
#define MAX_LB 48 /* Must be even, <= 508 */
#define MAX_HB 10
#define MAX_IOVB 80
/* These are the absolute maximum allowed for the ioctl() */
#define TOP_SB 256 /* Must be even, <= 508 */
#define TOP_LB 128 /* Must be even, <= 508 */
#define TOP_HB 64
#define TOP_IOVB 256
#define MAX_TBD_PER_VC 1 /* Number of TBDs before a TSR */
#define MAX_TBD_PER_SCQ 10 /* Only meaningful for variable rate SCQs */
#undef ENABLE_TSQFIE
#define SCQFULL_TIMEOUT (5 * HZ)
#define NS_POLL_PERIOD (HZ)
#define PCR_TOLERANCE (1.0001)
/* ESI stuff */
#define NICSTAR_EPROM_MAC_ADDR_OFFSET 0x6C
#define NICSTAR_EPROM_MAC_ADDR_OFFSET_ALT 0xF6
/* #defines */
#define NS_IOREMAP_SIZE 4096
/*
* BUF_XX distinguish the Rx buffers depending on their (small/large) size.
* BUG_SM and BUG_LG are both used by the driver and the device.
* BUF_NONE is only used by the driver.
*/
#define BUF_SM 0x00000000 /* These two are used for push_rxbufs() */
#define BUF_LG 0x00000001 /* CMD, Write_FreeBufQ, LBUF bit */
#define BUF_NONE 0xffffffff /* Software only: */
#define NS_HBUFSIZE 65568 /* Size of max. AAL5 PDU */
#define NS_MAX_IOVECS (2 + (65568 - NS_SMBUFSIZE) / \
(NS_LGBUFSIZE - (NS_LGBUFSIZE % 48)))
#define NS_IOVBUFSIZE (NS_MAX_IOVECS * (sizeof(struct iovec)))
#define NS_SMBUFSIZE_USABLE (NS_SMBUFSIZE - NS_SMBUFSIZE % 48)
#define NS_LGBUFSIZE_USABLE (NS_LGBUFSIZE - NS_LGBUFSIZE % 48)
#define NS_AAL0_HEADER (ATM_AAL0_SDU - ATM_CELL_PAYLOAD) /* 4 bytes */
#define NS_SMSKBSIZE (NS_SMBUFSIZE + NS_AAL0_HEADER)
#define NS_LGSKBSIZE (NS_SMBUFSIZE + NS_LGBUFSIZE)
/* NICStAR structures located in host memory */
/*
* RSQ - Receive Status Queue
*
* Written by the NICStAR, read by the device driver.
*/
typedef struct ns_rsqe {
u32 word_1;
u32 buffer_handle;
u32 final_aal5_crc32;
u32 word_4;
} ns_rsqe;
#define ns_rsqe_vpi(ns_rsqep) \
((le32_to_cpu((ns_rsqep)->word_1) & 0x00FF0000) >> 16)
#define ns_rsqe_vci(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_1) & 0x0000FFFF)
#define NS_RSQE_VALID 0x80000000
#define NS_RSQE_NZGFC 0x00004000
#define NS_RSQE_EOPDU 0x00002000
#define NS_RSQE_BUFSIZE 0x00001000
#define NS_RSQE_CONGESTION 0x00000800
#define NS_RSQE_CLP 0x00000400
#define NS_RSQE_CRCERR 0x00000200
#define NS_RSQE_BUFSIZE_SM 0x00000000
#define NS_RSQE_BUFSIZE_LG 0x00001000
#define ns_rsqe_valid(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_VALID)
#define ns_rsqe_nzgfc(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_NZGFC)
#define ns_rsqe_eopdu(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_EOPDU)
#define ns_rsqe_bufsize(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_BUFSIZE)
#define ns_rsqe_congestion(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CONGESTION)
#define ns_rsqe_clp(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CLP)
#define ns_rsqe_crcerr(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & NS_RSQE_CRCERR)
#define ns_rsqe_cellcount(ns_rsqep) \
(le32_to_cpu((ns_rsqep)->word_4) & 0x000001FF)
#define ns_rsqe_init(ns_rsqep) \
((ns_rsqep)->word_4 = cpu_to_le32(0x00000000))
#define NS_RSQ_NUM_ENTRIES (NS_RSQSIZE / 16)
#define NS_RSQ_ALIGNMENT NS_RSQSIZE
/*
* RCQ - Raw Cell Queue
*
* Written by the NICStAR, read by the device driver.
*/
typedef struct cell_payload {
u32 word[12];
} cell_payload;
typedef struct ns_rcqe {
u32 word_1;
u32 word_2;
u32 word_3;
u32 word_4;
cell_payload payload;
} ns_rcqe;
#define NS_RCQE_SIZE 64 /* bytes */
#define ns_rcqe_islast(ns_rcqep) \
(le32_to_cpu((ns_rcqep)->word_2) != 0x00000000)
#define ns_rcqe_cellheader(ns_rcqep) \
(le32_to_cpu((ns_rcqep)->word_1))
#define ns_rcqe_nextbufhandle(ns_rcqep) \
(le32_to_cpu((ns_rcqep)->word_2))
/*
* SCQ - Segmentation Channel Queue
*
* Written by the device driver, read by the NICStAR.
*/
typedef struct ns_scqe {
u32 word_1;
u32 word_2;
u32 word_3;
u32 word_4;
} ns_scqe;
/* NOTE: SCQ entries can be either a TBD (Transmit Buffer Descriptors)
or TSR (Transmit Status Requests) */
#define NS_SCQE_TYPE_TBD 0x00000000
#define NS_SCQE_TYPE_TSR 0x80000000
#define NS_TBD_EOPDU 0x40000000
#define NS_TBD_AAL0 0x00000000
#define NS_TBD_AAL34 0x04000000
#define NS_TBD_AAL5 0x08000000
#define NS_TBD_VPI_MASK 0x0FF00000
#define NS_TBD_VCI_MASK 0x000FFFF0
#define NS_TBD_VC_MASK (NS_TBD_VPI_MASK | NS_TBD_VCI_MASK)
#define NS_TBD_VPI_SHIFT 20
#define NS_TBD_VCI_SHIFT 4
#define ns_tbd_mkword_1(flags, m, n, buflen) \
(cpu_to_le32((flags) | (m) << 23 | (n) << 16 | (buflen)))
#define ns_tbd_mkword_1_novbr(flags, buflen) \
(cpu_to_le32((flags) | (buflen) | 0x00810000))
#define ns_tbd_mkword_3(control, pdulen) \
(cpu_to_le32((control) << 16 | (pdulen)))
#define ns_tbd_mkword_4(gfc, vpi, vci, pt, clp) \
(cpu_to_le32((gfc) << 28 | (vpi) << 20 | (vci) << 4 | (pt) << 1 | (clp)))
#define NS_TSR_INTENABLE 0x20000000
#define NS_TSR_SCDISVBR 0xFFFF /* Use as scdi for VBR SCD */
#define ns_tsr_mkword_1(flags) \
(cpu_to_le32(NS_SCQE_TYPE_TSR | (flags)))
#define ns_tsr_mkword_2(scdi, scqi) \
(cpu_to_le32((scdi) << 16 | 0x00008000 | (scqi)))
#define ns_scqe_is_tsr(ns_scqep) \
(le32_to_cpu((ns_scqep)->word_1) & NS_SCQE_TYPE_TSR)
#define VBR_SCQ_NUM_ENTRIES 512
#define VBR_SCQSIZE 8192
#define CBR_SCQ_NUM_ENTRIES 64
#define CBR_SCQSIZE 1024
#define NS_SCQE_SIZE 16
/*
* TSQ - Transmit Status Queue
*
* Written by the NICStAR, read by the device driver.
*/
typedef struct ns_tsi {
u32 word_1;
u32 word_2;
} ns_tsi;
/* NOTE: The first word can be a status word copied from the TSR which
originated the TSI, or a timer overflow indicator. In this last
case, the value of the first word is all zeroes. */
#define NS_TSI_EMPTY 0x80000000
#define NS_TSI_TIMESTAMP_MASK 0x00FFFFFF
#define ns_tsi_isempty(ns_tsip) \
(le32_to_cpu((ns_tsip)->word_2) & NS_TSI_EMPTY)
#define ns_tsi_gettimestamp(ns_tsip) \
(le32_to_cpu((ns_tsip)->word_2) & NS_TSI_TIMESTAMP_MASK)
#define ns_tsi_init(ns_tsip) \
((ns_tsip)->word_2 = cpu_to_le32(NS_TSI_EMPTY))
#define NS_TSQSIZE 8192
#define NS_TSQ_NUM_ENTRIES 1024
#define NS_TSQ_ALIGNMENT 8192
#define NS_TSI_SCDISVBR NS_TSR_SCDISVBR
#define ns_tsi_tmrof(ns_tsip) \
(le32_to_cpu((ns_tsip)->word_1) == 0x00000000)
#define ns_tsi_getscdindex(ns_tsip) \
((le32_to_cpu((ns_tsip)->word_1) & 0xFFFF0000) >> 16)
#define ns_tsi_getscqpos(ns_tsip) \
(le32_to_cpu((ns_tsip)->word_1) & 0x00007FFF)
/* NICStAR structures located in local SRAM */
/*
* RCT - Receive Connection Table
*
* Written by both the NICStAR and the device driver.
*/
typedef struct ns_rcte {
u32 word_1;
u32 buffer_handle;
u32 dma_address;
u32 aal5_crc32;
} ns_rcte;
#define NS_RCTE_BSFB 0x00200000 /* Rev. D only */
#define NS_RCTE_NZGFC 0x00100000
#define NS_RCTE_CONNECTOPEN 0x00080000
#define NS_RCTE_AALMASK 0x00070000
#define NS_RCTE_AAL0 0x00000000
#define NS_RCTE_AAL34 0x00010000
#define NS_RCTE_AAL5 0x00020000
#define NS_RCTE_RCQ 0x00030000
#define NS_RCTE_RAWCELLINTEN 0x00008000
#define NS_RCTE_RXCONSTCELLADDR 0x00004000
#define NS_RCTE_BUFFVALID 0x00002000
#define NS_RCTE_FBDSIZE 0x00001000
#define NS_RCTE_EFCI 0x00000800
#define NS_RCTE_CLP 0x00000400
#define NS_RCTE_CRCERROR 0x00000200
#define NS_RCTE_CELLCOUNT_MASK 0x000001FF
#define NS_RCTE_FBDSIZE_SM 0x00000000
#define NS_RCTE_FBDSIZE_LG 0x00001000
#define NS_RCT_ENTRY_SIZE 4 /* Number of dwords */
/* NOTE: We could make macros to contruct the first word of the RCTE,
but that doesn't seem to make much sense... */
/*
* FBD - Free Buffer Descriptor
*
* Written by the device driver using via the command register.
*/
typedef struct ns_fbd {
u32 buffer_handle;
u32 dma_address;
} ns_fbd;
/*
* TST - Transmit Schedule Table
*
* Written by the device driver.
*/
typedef u32 ns_tste;
#define NS_TST_OPCODE_MASK 0x60000000
#define NS_TST_OPCODE_NULL 0x00000000 /* Insert null cell */
#define NS_TST_OPCODE_FIXED 0x20000000 /* Cell from a fixed rate channel */
#define NS_TST_OPCODE_VARIABLE 0x40000000
#define NS_TST_OPCODE_END 0x60000000 /* Jump */
#define ns_tste_make(opcode, sramad) (opcode | sramad)
/* NOTE:
- When the opcode is FIXED, sramad specifies the SRAM address of the
SCD for that fixed rate channel.
- When the opcode is END, sramad specifies the SRAM address of the
location of the next TST entry to read.
*/
/*
* SCD - Segmentation Channel Descriptor
*
* Written by both the device driver and the NICStAR
*/
typedef struct ns_scd {
u32 word_1;
u32 word_2;
u32 partial_aal5_crc;
u32 reserved;
ns_scqe cache_a;
ns_scqe cache_b;
} ns_scd;
#define NS_SCD_BASE_MASK_VAR 0xFFFFE000 /* Variable rate */
#define NS_SCD_BASE_MASK_FIX 0xFFFFFC00 /* Fixed rate */
#define NS_SCD_TAIL_MASK_VAR 0x00001FF0
#define NS_SCD_TAIL_MASK_FIX 0x000003F0
#define NS_SCD_HEAD_MASK_VAR 0x00001FF0
#define NS_SCD_HEAD_MASK_FIX 0x000003F0
#define NS_SCD_XMITFOREVER 0x02000000
/* NOTE: There are other fields in word 2 of the SCD, but as they should
not be needed in the device driver they are not defined here. */
/* NICStAR local SRAM memory map */
#define NS_RCT 0x00000
#define NS_RCT_32_END 0x03FFF
#define NS_RCT_128_END 0x0FFFF
#define NS_UNUSED_32 0x04000
#define NS_UNUSED_128 0x10000
#define NS_UNUSED_END 0x1BFFF
#define NS_TST_FRSCD 0x1C000
#define NS_TST_FRSCD_END 0x1E7DB
#define NS_VRSCD2 0x1E7DC
#define NS_VRSCD2_END 0x1E7E7
#define NS_VRSCD1 0x1E7E8
#define NS_VRSCD1_END 0x1E7F3
#define NS_VRSCD0 0x1E7F4
#define NS_VRSCD0_END 0x1E7FF
#define NS_RXFIFO 0x1E800
#define NS_RXFIFO_END 0x1F7FF
#define NS_SMFBQ 0x1F800
#define NS_SMFBQ_END 0x1FBFF
#define NS_LGFBQ 0x1FC00
#define NS_LGFBQ_END 0x1FFFF
/* NISCtAR operation registers */
/* See Section 3.4 of `IDT77211 NICStAR User Manual' from www.idt.com */
enum ns_regs {
DR0 = 0x00, /* Data Register 0 R/W */
DR1 = 0x04, /* Data Register 1 W */
DR2 = 0x08, /* Data Register 2 W */
DR3 = 0x0C, /* Data Register 3 W */
CMD = 0x10, /* Command W */
CFG = 0x14, /* Configuration R/W */
STAT = 0x18, /* Status R/W */
RSQB = 0x1C, /* Receive Status Queue Base W */
RSQT = 0x20, /* Receive Status Queue Tail R */
RSQH = 0x24, /* Receive Status Queue Head W */
CDC = 0x28, /* Cell Drop Counter R/clear */
VPEC = 0x2C, /* VPI/VCI Lookup Error Count R/clear */
ICC = 0x30, /* Invalid Cell Count R/clear */
RAWCT = 0x34, /* Raw Cell Tail R */
TMR = 0x38, /* Timer R */
TSTB = 0x3C, /* Transmit Schedule Table Base R/W */
TSQB = 0x40, /* Transmit Status Queue Base W */
TSQT = 0x44, /* Transmit Status Queue Tail R */
TSQH = 0x48, /* Transmit Status Queue Head W */
GP = 0x4C, /* General Purpose R/W */
VPM = 0x50 /* VPI/VCI Mask W */
};
/* NICStAR commands issued to the CMD register */
/* Top 4 bits are command opcode, lower 28 are parameters. */
#define NS_CMD_NO_OPERATION 0x00000000
/* params always 0 */
#define NS_CMD_OPENCLOSE_CONNECTION 0x20000000
/* b19{1=open,0=close} b18-2{SRAM addr} */
#define NS_CMD_WRITE_SRAM 0x40000000
/* b18-2{SRAM addr} b1-0{burst size} */
#define NS_CMD_READ_SRAM 0x50000000
/* b18-2{SRAM addr} */
#define NS_CMD_WRITE_FREEBUFQ 0x60000000
/* b0{large buf indicator} */
#define NS_CMD_READ_UTILITY 0x80000000
/* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */
#define NS_CMD_WRITE_UTILITY 0x90000000
/* b8{1=select UTL_CS1} b9{1=select UTL_CS0} b7-0{bus addr} */
#define NS_CMD_OPEN_CONNECTION (NS_CMD_OPENCLOSE_CONNECTION | 0x00080000)
#define NS_CMD_CLOSE_CONNECTION NS_CMD_OPENCLOSE_CONNECTION
/* NICStAR configuration bits */
#define NS_CFG_SWRST 0x80000000 /* Software Reset */
#define NS_CFG_RXPATH 0x20000000 /* Receive Path Enable */
#define NS_CFG_SMBUFSIZE_MASK 0x18000000 /* Small Receive Buffer Size */
#define NS_CFG_LGBUFSIZE_MASK 0x06000000 /* Large Receive Buffer Size */
#define NS_CFG_EFBIE 0x01000000 /* Empty Free Buffer Queue
Interrupt Enable */
#define NS_CFG_RSQSIZE_MASK 0x00C00000 /* Receive Status Queue Size */
#define NS_CFG_ICACCEPT 0x00200000 /* Invalid Cell Accept */
#define NS_CFG_IGNOREGFC 0x00100000 /* Ignore General Flow Control */
#define NS_CFG_VPIBITS_MASK 0x000C0000 /* VPI/VCI Bits Size Select */
#define NS_CFG_RCTSIZE_MASK 0x00030000 /* Receive Connection Table Size */
#define NS_CFG_VCERRACCEPT 0x00008000 /* VPI/VCI Error Cell Accept */
#define NS_CFG_RXINT_MASK 0x00007000 /* End of Receive PDU Interrupt
Handling */
#define NS_CFG_RAWIE 0x00000800 /* Raw Cell Qu' Interrupt Enable */
#define NS_CFG_RSQAFIE 0x00000400 /* Receive Queue Almost Full
Interrupt Enable */
#define NS_CFG_RXRM 0x00000200 /* Receive RM Cells */
#define NS_CFG_TMRROIE 0x00000080 /* Timer Roll Over Interrupt
Enable */
#define NS_CFG_TXEN 0x00000020 /* Transmit Operation Enable */
#define NS_CFG_TXIE 0x00000010 /* Transmit Status Interrupt
Enable */
#define NS_CFG_TXURIE 0x00000008 /* Transmit Under-run Interrupt
Enable */
#define NS_CFG_UMODE 0x00000004 /* Utopia Mode (cell/byte) Select */
#define NS_CFG_TSQFIE 0x00000002 /* Transmit Status Queue Full
Interrupt Enable */
#define NS_CFG_PHYIE 0x00000001 /* PHY Interrupt Enable */
#define NS_CFG_SMBUFSIZE_48 0x00000000
#define NS_CFG_SMBUFSIZE_96 0x08000000
#define NS_CFG_SMBUFSIZE_240 0x10000000
#define NS_CFG_SMBUFSIZE_2048 0x18000000
#define NS_CFG_LGBUFSIZE_2048 0x00000000
#define NS_CFG_LGBUFSIZE_4096 0x02000000
#define NS_CFG_LGBUFSIZE_8192 0x04000000
#define NS_CFG_LGBUFSIZE_16384 0x06000000
#define NS_CFG_RSQSIZE_2048 0x00000000
#define NS_CFG_RSQSIZE_4096 0x00400000
#define NS_CFG_RSQSIZE_8192 0x00800000
#define NS_CFG_VPIBITS_0 0x00000000
#define NS_CFG_VPIBITS_1 0x00040000
#define NS_CFG_VPIBITS_2 0x00080000
#define NS_CFG_VPIBITS_8 0x000C0000
#define NS_CFG_RCTSIZE_4096_ENTRIES 0x00000000
#define NS_CFG_RCTSIZE_8192_ENTRIES 0x00010000
#define NS_CFG_RCTSIZE_16384_ENTRIES 0x00020000
#define NS_CFG_RXINT_NOINT 0x00000000
#define NS_CFG_RXINT_NODELAY 0x00001000
#define NS_CFG_RXINT_314US 0x00002000
#define NS_CFG_RXINT_624US 0x00003000
#define NS_CFG_RXINT_899US 0x00004000
/* NICStAR STATus bits */
#define NS_STAT_SFBQC_MASK 0xFF000000 /* hi 8 bits Small Buffer Queue Count */
#define NS_STAT_LFBQC_MASK 0x00FF0000 /* hi 8 bits Large Buffer Queue Count */
#define NS_STAT_TSIF 0x00008000 /* Transmit Status Queue Indicator */
#define NS_STAT_TXICP 0x00004000 /* Transmit Incomplete PDU */
#define NS_STAT_TSQF 0x00001000 /* Transmit Status Queue Full */
#define NS_STAT_TMROF 0x00000800 /* Timer Overflow */
#define NS_STAT_PHYI 0x00000400 /* PHY Device Interrupt */
#define NS_STAT_CMDBZ 0x00000200 /* Command Busy */
#define NS_STAT_SFBQF 0x00000100 /* Small Buffer Queue Full */
#define NS_STAT_LFBQF 0x00000080 /* Large Buffer Queue Full */
#define NS_STAT_RSQF 0x00000040 /* Receive Status Queue Full */
#define NS_STAT_EOPDU 0x00000020 /* End of PDU */
#define NS_STAT_RAWCF 0x00000010 /* Raw Cell Flag */
#define NS_STAT_SFBQE 0x00000008 /* Small Buffer Queue Empty */
#define NS_STAT_LFBQE 0x00000004 /* Large Buffer Queue Empty */
#define NS_STAT_RSQAF 0x00000002 /* Receive Status Queue Almost Full */
#define ns_stat_sfbqc_get(stat) (((stat) & NS_STAT_SFBQC_MASK) >> 23)
#define ns_stat_lfbqc_get(stat) (((stat) & NS_STAT_LFBQC_MASK) >> 15)
/* #defines which depend on other #defines */
#define NS_TST0 NS_TST_FRSCD
#define NS_TST1 (NS_TST_FRSCD + NS_TST_NUM_ENTRIES + 1)
#define NS_FRSCD (NS_TST1 + NS_TST_NUM_ENTRIES + 1)
#define NS_FRSCD_SIZE 12 /* 12 dwords */
#define NS_FRSCD_NUM ((NS_TST_FRSCD_END + 1 - NS_FRSCD) / NS_FRSCD_SIZE)
#if (NS_SMBUFSIZE == 48)
#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_48
#elif (NS_SMBUFSIZE == 96)
#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_96
#elif (NS_SMBUFSIZE == 240)
#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_240
#elif (NS_SMBUFSIZE == 2048)
#define NS_CFG_SMBUFSIZE NS_CFG_SMBUFSIZE_2048
#else
#error NS_SMBUFSIZE is incorrect in nicstar.h
#endif /* NS_SMBUFSIZE */
#if (NS_LGBUFSIZE == 2048)
#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_2048
#elif (NS_LGBUFSIZE == 4096)
#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_4096
#elif (NS_LGBUFSIZE == 8192)
#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_8192
#elif (NS_LGBUFSIZE == 16384)
#define NS_CFG_LGBUFSIZE NS_CFG_LGBUFSIZE_16384
#else
#error NS_LGBUFSIZE is incorrect in nicstar.h
#endif /* NS_LGBUFSIZE */
#if (NS_RSQSIZE == 2048)
#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_2048
#elif (NS_RSQSIZE == 4096)
#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_4096
#elif (NS_RSQSIZE == 8192)
#define NS_CFG_RSQSIZE NS_CFG_RSQSIZE_8192
#else
#error NS_RSQSIZE is incorrect in nicstar.h
#endif /* NS_RSQSIZE */
#if (NS_VPIBITS == 0)
#define NS_CFG_VPIBITS NS_CFG_VPIBITS_0
#elif (NS_VPIBITS == 1)
#define NS_CFG_VPIBITS NS_CFG_VPIBITS_1
#elif (NS_VPIBITS == 2)
#define NS_CFG_VPIBITS NS_CFG_VPIBITS_2
#elif (NS_VPIBITS == 8)
#define NS_CFG_VPIBITS NS_CFG_VPIBITS_8
#else
#error NS_VPIBITS is incorrect in nicstar.h
#endif /* NS_VPIBITS */
#ifdef RCQ_SUPPORT
#define NS_CFG_RAWIE_OPT NS_CFG_RAWIE
#else
#define NS_CFG_RAWIE_OPT 0x00000000
#endif /* RCQ_SUPPORT */
#ifdef ENABLE_TSQFIE
#define NS_CFG_TSQFIE_OPT NS_CFG_TSQFIE
#else
#define NS_CFG_TSQFIE_OPT 0x00000000
#endif /* ENABLE_TSQFIE */
/* PCI stuff */
#ifndef PCI_VENDOR_ID_IDT
#define PCI_VENDOR_ID_IDT 0x111D
#endif /* PCI_VENDOR_ID_IDT */
#ifndef PCI_DEVICE_ID_IDT_IDT77201
#define PCI_DEVICE_ID_IDT_IDT77201 0x0001
#endif /* PCI_DEVICE_ID_IDT_IDT77201 */
/* Device driver structures */
struct ns_skb_prv {
u32 buf_type; /* BUF_SM/BUF_LG/BUF_NONE */
u32 dma;
int iovcnt;
};
#define NS_PRV_BUFTYPE(skb) \
(((struct ns_skb_prv *)(ATM_SKB(skb)+1))->buf_type)
#define NS_PRV_DMA(skb) \
(((struct ns_skb_prv *)(ATM_SKB(skb)+1))->dma)
#define NS_PRV_IOVCNT(skb) \
(((struct ns_skb_prv *)(ATM_SKB(skb)+1))->iovcnt)
typedef struct tsq_info {
void *org;
dma_addr_t dma;
ns_tsi *base;
ns_tsi *next;
ns_tsi *last;
} tsq_info;
typedef struct scq_info {
void *org;
dma_addr_t dma;
ns_scqe *base;
ns_scqe *last;
ns_scqe *next;
volatile ns_scqe *tail; /* Not related to the nicstar register */
unsigned num_entries;
struct sk_buff **skb; /* Pointer to an array of pointers
to the sk_buffs used for tx */
u32 scd; /* SRAM address of the corresponding
SCD */
int tbd_count; /* Only meaningful on variable rate */
wait_queue_head_t scqfull_waitq;
volatile char full; /* SCQ full indicator */
spinlock_t lock; /* SCQ spinlock */
} scq_info;
typedef struct rsq_info {
void *org;
dma_addr_t dma;
ns_rsqe *base;
ns_rsqe *next;
ns_rsqe *last;
} rsq_info;
typedef struct skb_pool {
volatile int count; /* number of buffers in the queue */
struct sk_buff_head queue;
} skb_pool;
/* NOTE: for small and large buffer pools, the count is not used, as the
actual value used for buffer management is the one read from the
card. */
typedef struct vc_map {
volatile unsigned int tx:1; /* TX vc? */
volatile unsigned int rx:1; /* RX vc? */
struct atm_vcc *tx_vcc, *rx_vcc;
struct sk_buff *rx_iov; /* RX iovector skb */
scq_info *scq; /* To keep track of the SCQ */
u32 cbr_scd; /* SRAM address of the corresponding
SCD. 0x00000000 for UBR/VBR/ABR */
int tbd_count;
} vc_map;
typedef struct ns_dev {
int index; /* Card ID to the device driver */
int sram_size; /* In k x 32bit words. 32 or 128 */
void __iomem *membase; /* Card's memory base address */
unsigned long max_pcr;
int rct_size; /* Number of entries */
int vpibits;
int vcibits;
struct pci_dev *pcidev;
struct idr idr;
struct atm_dev *atmdev;
tsq_info tsq;
rsq_info rsq;
scq_info *scq0, *scq1, *scq2; /* VBR SCQs */
skb_pool sbpool; /* Small buffers */
skb_pool lbpool; /* Large buffers */
skb_pool hbpool; /* Pre-allocated huge buffers */
skb_pool iovpool; /* iovector buffers */
volatile int efbie; /* Empty free buf. queue int. enabled */
volatile u32 tst_addr; /* SRAM address of the TST in use */
volatile int tst_free_entries;
vc_map vcmap[NS_MAX_RCTSIZE];
vc_map *tste2vc[NS_TST_NUM_ENTRIES];
vc_map *scd2vc[NS_FRSCD_NUM];
buf_nr sbnr;
buf_nr lbnr;
buf_nr hbnr;
buf_nr iovnr;
int sbfqc;
int lbfqc;
struct sk_buff *sm_handle;
u32 sm_addr;
struct sk_buff *lg_handle;
u32 lg_addr;
struct sk_buff *rcbuf; /* Current raw cell buffer */
struct ns_rcqe *rawcell;
u32 rawch; /* Raw cell queue head */
unsigned intcnt; /* Interrupt counter */
spinlock_t int_lock; /* Interrupt lock */
spinlock_t res_lock; /* Card resource lock */
} ns_dev;
/* NOTE: Each tste2vc entry relates a given TST entry to the corresponding
CBR vc. If the entry is not allocated, it must be NULL.
There are two TSTs so the driver can modify them on the fly
without stopping the transmission.
scd2vc allows us to find out unused fixed rate SCDs, because
they must have a NULL pointer here. */
#endif /* _LINUX_NICSTAR_H_ */

248
drivers/atm/nicstarmac.c Normal file
View file

@ -0,0 +1,248 @@
/*
* this file included by nicstar.c
*/
/*
* nicstarmac.c
* Read this ForeRunner's MAC address from eprom/eeprom
*/
#include <linux/kernel.h>
typedef void __iomem *virt_addr_t;
#define CYCLE_DELAY 5
/*
This was the original definition
#define osp_MicroDelay(microsec) \
do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
*/
#define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
udelay((useconds));}
/*
* The following tables represent the timing diagrams found in
* the Data Sheet for the Xicor X25020 EEProm. The #defines below
* represent the bits in the NICStAR's General Purpose register
* that must be toggled for the corresponding actions on the EEProm
* to occur.
*/
/* Write Data To EEProm from SI line on rising edge of CLK */
/* Read Data From EEProm on falling edge of CLK */
#define CS_HIGH 0x0002 /* Chip select high */
#define CS_LOW 0x0000 /* Chip select low (active low) */
#define CLK_HIGH 0x0004 /* Clock high */
#define CLK_LOW 0x0000 /* Clock low */
#define SI_HIGH 0x0001 /* Serial input data high */
#define SI_LOW 0x0000 /* Serial input data low */
/* Read Status Register = 0000 0101b */
#if 0
static u_int32_t rdsrtab[] = {
CS_HIGH | CLK_HIGH,
CS_LOW | CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW | SI_HIGH,
CLK_HIGH | SI_HIGH, /* 1 */
CLK_LOW | SI_LOW,
CLK_HIGH, /* 0 */
CLK_LOW | SI_HIGH,
CLK_HIGH | SI_HIGH /* 1 */
};
#endif /* 0 */
/* Read from EEPROM = 0000 0011b */
static u_int32_t readtab[] = {
/*
CS_HIGH | CLK_HIGH,
*/
CS_LOW | CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW,
CLK_HIGH, /* 0 */
CLK_LOW | SI_HIGH,
CLK_HIGH | SI_HIGH, /* 1 */
CLK_LOW | SI_HIGH,
CLK_HIGH | SI_HIGH /* 1 */
};
/* Clock to read from/write to the eeprom */
static u_int32_t clocktab[] = {
CLK_LOW,
CLK_HIGH,
CLK_LOW,
CLK_HIGH,
CLK_LOW,
CLK_HIGH,
CLK_LOW,
CLK_HIGH,
CLK_LOW,
CLK_HIGH,
CLK_LOW,
CLK_HIGH,
CLK_LOW,
CLK_HIGH,
CLK_LOW,
CLK_HIGH,
CLK_LOW
};
#define NICSTAR_REG_WRITE(bs, reg, val) \
while ( readl(bs + STAT) & 0x0200 ) ; \
writel((val),(base)+(reg))
#define NICSTAR_REG_READ(bs, reg) \
readl((base)+(reg))
#define NICSTAR_REG_GENERAL_PURPOSE GP
/*
* This routine will clock the Read_Status_reg function into the X2520
* eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose
* register.
*/
#if 0
u_int32_t nicstar_read_eprom_status(virt_addr_t base)
{
u_int32_t val;
u_int32_t rbyte;
int32_t i, j;
/* Send read instruction */
val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | rdsrtab[i]));
osp_MicroDelay(CYCLE_DELAY);
}
/* Done sending instruction - now pull data off of bit 16, MSB first */
/* Data clocked out of eeprom on falling edge of clock */
rbyte = 0;
for (i = 7, j = 0; i >= 0; i--) {
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | clocktab[j++]));
rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
& 0x00010000) >> 16) << i);
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | clocktab[j++]));
osp_MicroDelay(CYCLE_DELAY);
}
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
osp_MicroDelay(CYCLE_DELAY);
return rbyte;
}
#endif /* 0 */
/*
* This routine will clock the Read_data function into the X2520
* eeprom, followed by the address to read from, through the NicSTaR's General
* Purpose register.
*/
static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
{
u_int32_t val = 0;
int i, j = 0;
u_int8_t tempread = 0;
val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
/* Send READ instruction */
for (i = 0; i < ARRAY_SIZE(readtab); i++) {
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | readtab[i]));
osp_MicroDelay(CYCLE_DELAY);
}
/* Next, we need to send the byte address to read from */
for (i = 7; i >= 0; i--) {
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | clocktab[j++] | ((offset >> i) & 1)));
osp_MicroDelay(CYCLE_DELAY);
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | clocktab[j++] | ((offset >> i) & 1)));
osp_MicroDelay(CYCLE_DELAY);
}
j = 0;
/* Now, we can read data from the eeprom by clocking it in */
for (i = 7; i >= 0; i--) {
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | clocktab[j++]));
osp_MicroDelay(CYCLE_DELAY);
tempread |=
(((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
& 0x00010000) >> 16) << i);
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | clocktab[j++]));
osp_MicroDelay(CYCLE_DELAY);
}
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
osp_MicroDelay(CYCLE_DELAY);
return tempread;
}
static void nicstar_init_eprom(virt_addr_t base)
{
u_int32_t val;
/*
* turn chip select off
*/
val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | CS_HIGH | CLK_HIGH));
osp_MicroDelay(CYCLE_DELAY);
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | CS_HIGH | CLK_LOW));
osp_MicroDelay(CYCLE_DELAY);
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | CS_HIGH | CLK_HIGH));
osp_MicroDelay(CYCLE_DELAY);
NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
(val | CS_HIGH | CLK_LOW));
osp_MicroDelay(CYCLE_DELAY);
}
/*
* This routine will be the interface to the ReadPromByte function
* above.
*/
static void
nicstar_read_eprom(virt_addr_t base,
u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
{
u_int i;
for (i = 0; i < nbytes; i++) {
buffer[i] = read_eprom_byte(base, prom_offset);
++prom_offset;
osp_MicroDelay(CYCLE_DELAY);
}
}

View file

@ -0,0 +1,61 @@
/* nicstar.c v0.22 Jawaid Bazyar (bazyar@hypermall.com)
* nicstar.c, M. Welsh (matt.welsh@cl.cam.ac.uk)
*
* Hacked October, 1997 by Jawaid Bazyar, Interlink Advertising Services Inc.
* http://www.hypermall.com/
* 10/1/97 - commented out CFG_PHYIE bit - we don't care when the PHY
* interrupts us (except possibly for removal/insertion of the cable?)
* 10/4/97 - began heavy inline documentation of the code. Corrected typos
* and spelling mistakes.
* 10/5/97 - added code to handle PHY interrupts, disable PHY on
* loss of link, and correctly re-enable PHY when link is
* re-established. (put back CFG_PHYIE)
*
* Modified to work with the IDT7721 nicstar -- AAL5 (tested) only.
*
* R. D. Rechenmacher <ron@fnal.gov>, Aug. 6, 1997
*
* Linux driver for the IDT77201 NICStAR PCI ATM controller.
* PHY component is expected to be 155 Mbps S/UNI-Lite or IDT 77155;
* see init_nicstar() for PHY initialization to change this. This driver
* expects the Linux ATM stack to support scatter-gather lists
* (skb->atm.iovcnt != 0) for Rx skb's passed to vcc->push.
*
* Implementing minimal-copy of received data:
* IDT always receives data into a small buffer, then large buffers
* as needed. This means that data must always be copied to create
* the linear buffer needed by most non-ATM protocol stacks (e.g. IP)
* Fix is simple: make large buffers large enough to hold entire
* SDU, and leave <small_buffer_data> bytes empty at the start. Then
* copy small buffer contents to head of large buffer.
* Trick is to avoid fragmenting Linux, due to need for a lot of large
* buffers. This is done by 2 things:
* 1) skb->destructor / skb->atm.recycle_buffer
* combined, allow nicstar_free_rx_skb to be called to
* recycle large data buffers
* 2) skb_clone of received buffers
* See nicstar_free_rx_skb and linearize_buffer for implementation
* details.
*
*
*
* Copyright (c) 1996 University of Cambridge Computer Laboratory
*
* 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.
*
* M. Welsh, 6 July 1996
*
*
*/

View file

@ -0,0 +1,82 @@
SOLOS_ATTR_RO(DriverVersion)
SOLOS_ATTR_RO(APIVersion)
SOLOS_ATTR_RO(FirmwareVersion)
SOLOS_ATTR_RO(Version)
// SOLOS_ATTR_RO(DspVersion)
// SOLOS_ATTR_RO(CommonHandshake)
SOLOS_ATTR_RO(Connected)
SOLOS_ATTR_RO(OperationalMode)
SOLOS_ATTR_RO(State)
SOLOS_ATTR_RO(Watchdog)
SOLOS_ATTR_RO(OperationProgress)
SOLOS_ATTR_RO(LastFailed)
SOLOS_ATTR_RO(TxBitRate)
SOLOS_ATTR_RO(RxBitRate)
// SOLOS_ATTR_RO(DeltACTATPds)
// SOLOS_ATTR_RO(DeltACTATPus)
SOLOS_ATTR_RO(TxATTNDR)
SOLOS_ATTR_RO(RxATTNDR)
SOLOS_ATTR_RO(AnnexType)
SOLOS_ATTR_RO(GeneralFailure)
SOLOS_ATTR_RO(InterleaveDpDn)
SOLOS_ATTR_RO(InterleaveDpUp)
SOLOS_ATTR_RO(RSCorrectedErrorsDn)
SOLOS_ATTR_RO(RSUnCorrectedErrorsDn)
SOLOS_ATTR_RO(RSCorrectedErrorsUp)
SOLOS_ATTR_RO(RSUnCorrectedErrorsUp)
SOLOS_ATTR_RO(InterleaveRDn)
SOLOS_ATTR_RO(InterleaveRUp)
SOLOS_ATTR_RO(BisRDn)
SOLOS_ATTR_RO(BisRUp)
SOLOS_ATTR_RO(INPdown)
SOLOS_ATTR_RO(INPup)
SOLOS_ATTR_RO(ShowtimeStart)
SOLOS_ATTR_RO(ATURVendor)
SOLOS_ATTR_RO(ATUCCountry)
SOLOS_ATTR_RO(ATURANSIRev)
SOLOS_ATTR_RO(ATURANSISTD)
SOLOS_ATTR_RO(ATUCANSIRev)
SOLOS_ATTR_RO(ATUCANSIId)
SOLOS_ATTR_RO(ATUCANSISTD)
SOLOS_ATTR_RO(DataBoost)
SOLOS_ATTR_RO(LocalITUCountryCode)
SOLOS_ATTR_RO(LocalSEF)
SOLOS_ATTR_RO(LocalEndLOS)
SOLOS_ATTR_RO(LocalSNRMargin)
SOLOS_ATTR_RO(LocalLineAttn)
SOLOS_ATTR_RO(RawAttn)
SOLOS_ATTR_RO(LocalTxPower)
SOLOS_ATTR_RO(RemoteTxPower)
SOLOS_ATTR_RO(RemoteSEF)
SOLOS_ATTR_RO(RemoteLOS)
SOLOS_ATTR_RO(RemoteLineAttn)
SOLOS_ATTR_RO(RemoteSNRMargin)
SOLOS_ATTR_RO(LineUpCount)
SOLOS_ATTR_RO(SRACnt)
SOLOS_ATTR_RO(SRACntUp)
SOLOS_ATTR_RO(ProfileStatus)
SOLOS_ATTR_RW(Action)
SOLOS_ATTR_RW(ActivateLine)
SOLOS_ATTR_RO(LineStatus)
SOLOS_ATTR_RW(HostControl)
SOLOS_ATTR_RW(AutoStart)
SOLOS_ATTR_RW(Failsafe)
SOLOS_ATTR_RW(ShowtimeLed)
SOLOS_ATTR_RW(Retrain)
SOLOS_ATTR_RW(Defaults)
SOLOS_ATTR_RW(LineMode)
SOLOS_ATTR_RW(Profile)
SOLOS_ATTR_RW(DetectNoise)
SOLOS_ATTR_RW(BisAForceSNRMarginDn)
SOLOS_ATTR_RW(BisMForceSNRMarginDn)
SOLOS_ATTR_RW(BisAMaxMargin)
SOLOS_ATTR_RW(BisMMaxMargin)
SOLOS_ATTR_RW(AnnexAForceSNRMarginDn)
SOLOS_ATTR_RW(AnnexAMaxMargin)
SOLOS_ATTR_RW(AnnexMMaxMargin)
SOLOS_ATTR_RO(SupportedAnnexes)
SOLOS_ATTR_RO(Status)
SOLOS_ATTR_RO(TotalStart)
SOLOS_ATTR_RO(RecentShowtimeStart)
SOLOS_ATTR_RO(TotalRxBlocks)
SOLOS_ATTR_RO(TotalTxBlocks)

1495
drivers/atm/solos-pci.c Normal file

File diff suppressed because it is too large Load diff

392
drivers/atm/suni.c Normal file
View file

@ -0,0 +1,392 @@
/*
* drivers/atm/suni.c - S/UNI PHY driver
*
* Supports the following:
* PMC PM5346 S/UNI LITE
* PMC PM5350 S/UNI 155 ULTRA
* PMC PM5355 S/UNI 622
*/
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
#include <linux/module.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/capability.h>
#include <linux/atm_suni.h>
#include <linux/slab.h>
#include <asm/param.h>
#include <asm/uaccess.h>
#include <linux/atomic.h>
#include "suni.h"
#if 0
#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
#else
#define DPRINTK(format,args...)
#endif
#define PRIV(dev) ((struct suni_priv *) dev->phy_data)
#define PUT(val,reg) dev->ops->phy_put(dev,val,SUNI_##reg)
#define GET(reg) dev->ops->phy_get(dev,SUNI_##reg)
#define REG_CHANGE(mask,shift,value,reg) \
PUT((GET(reg) & ~(mask)) | ((value) << (shift)),reg)
static struct timer_list poll_timer;
static struct suni_priv *sunis = NULL;
static DEFINE_SPINLOCK(sunis_lock);
#define ADD_LIMITED(s,v) \
atomic_add((v),&stats->s); \
if (atomic_read(&stats->s) < 0) atomic_set(&stats->s,INT_MAX);
static void suni_hz(unsigned long from_timer)
{
struct suni_priv *walk;
struct atm_dev *dev;
struct k_sonet_stats *stats;
for (walk = sunis; walk; walk = walk->next) {
dev = walk->dev;
stats = &walk->sonet_stats;
PUT(0,MRI); /* latch counters */
udelay(1);
ADD_LIMITED(section_bip,(GET(RSOP_SBL) & 0xff) |
((GET(RSOP_SBM) & 0xff) << 8));
ADD_LIMITED(line_bip,(GET(RLOP_LBL) & 0xff) |
((GET(RLOP_LB) & 0xff) << 8) |
((GET(RLOP_LBM) & 0xf) << 16));
ADD_LIMITED(path_bip,(GET(RPOP_PBL) & 0xff) |
((GET(RPOP_PBM) & 0xff) << 8));
ADD_LIMITED(line_febe,(GET(RLOP_LFL) & 0xff) |
((GET(RLOP_LF) & 0xff) << 8) |
((GET(RLOP_LFM) & 0xf) << 16));
ADD_LIMITED(path_febe,(GET(RPOP_PFL) & 0xff) |
((GET(RPOP_PFM) & 0xff) << 8));
ADD_LIMITED(corr_hcs,GET(RACP_CHEC) & 0xff);
ADD_LIMITED(uncorr_hcs,GET(RACP_UHEC) & 0xff);
ADD_LIMITED(rx_cells,(GET(RACP_RCCL) & 0xff) |
((GET(RACP_RCC) & 0xff) << 8) |
((GET(RACP_RCCM) & 7) << 16));
ADD_LIMITED(tx_cells,(GET(TACP_TCCL) & 0xff) |
((GET(TACP_TCC) & 0xff) << 8) |
((GET(TACP_TCCM) & 7) << 16));
}
if (from_timer) mod_timer(&poll_timer,jiffies+HZ);
}
#undef ADD_LIMITED
static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
{
struct sonet_stats tmp;
int error = 0;
sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
if (zero && !error) sonet_subtract_stats(&PRIV(dev)->sonet_stats,&tmp);
return error ? -EFAULT : 0;
}
#define HANDLE_FLAG(flag,reg,bit) \
if (todo & flag) { \
if (set) PUT(GET(reg) | bit,reg); \
else PUT(GET(reg) & ~bit,reg); \
todo &= ~flag; \
}
static int change_diag(struct atm_dev *dev,void __user *arg,int set)
{
int todo;
if (get_user(todo,(int __user *)arg)) return -EFAULT;
HANDLE_FLAG(SONET_INS_SBIP,TSOP_DIAG,SUNI_TSOP_DIAG_DBIP8);
HANDLE_FLAG(SONET_INS_LBIP,TLOP_DIAG,SUNI_TLOP_DIAG_DBIP);
HANDLE_FLAG(SONET_INS_PBIP,TPOP_CD,SUNI_TPOP_DIAG_DB3);
HANDLE_FLAG(SONET_INS_FRAME,RSOP_CIE,SUNI_RSOP_CIE_FOOF);
HANDLE_FLAG(SONET_INS_LAIS,TSOP_CTRL,SUNI_TSOP_CTRL_LAIS);
HANDLE_FLAG(SONET_INS_PAIS,TPOP_CD,SUNI_TPOP_DIAG_PAIS);
HANDLE_FLAG(SONET_INS_LOS,TSOP_DIAG,SUNI_TSOP_DIAG_DLOS);
HANDLE_FLAG(SONET_INS_HCS,TACP_CS,SUNI_TACP_CS_DHCS);
return put_user(todo,(int __user *)arg) ? -EFAULT : 0;
}
#undef HANDLE_FLAG
static int get_diag(struct atm_dev *dev,void __user *arg)
{
int set;
set = 0;
if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DBIP8) set |= SONET_INS_SBIP;
if (GET(TLOP_DIAG) & SUNI_TLOP_DIAG_DBIP) set |= SONET_INS_LBIP;
if (GET(TPOP_CD) & SUNI_TPOP_DIAG_DB3) set |= SONET_INS_PBIP;
/* SONET_INS_FRAME is one-shot only */
if (GET(TSOP_CTRL) & SUNI_TSOP_CTRL_LAIS) set |= SONET_INS_LAIS;
if (GET(TPOP_CD) & SUNI_TPOP_DIAG_PAIS) set |= SONET_INS_PAIS;
if (GET(TSOP_DIAG) & SUNI_TSOP_DIAG_DLOS) set |= SONET_INS_LOS;
if (GET(TACP_CS) & SUNI_TACP_CS_DHCS) set |= SONET_INS_HCS;
return put_user(set,(int __user *)arg) ? -EFAULT : 0;
}
static int set_loopback(struct atm_dev *dev,int mode)
{
unsigned char control;
int reg, dle, lle;
if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
reg = SUNI_MCM;
dle = SUNI_MCM_DLE;
lle = SUNI_MCM_LLE;
} else {
reg = SUNI_MCT;
dle = SUNI_MCT_DLE;
lle = SUNI_MCT_LLE;
}
control = dev->ops->phy_get(dev, reg) & ~(dle | lle);
switch (mode) {
case ATM_LM_NONE:
break;
case ATM_LM_LOC_PHY:
control |= dle;
break;
case ATM_LM_RMT_PHY:
control |= lle;
break;
default:
return -EINVAL;
}
dev->ops->phy_put(dev, control, reg);
PRIV(dev)->loop_mode = mode;
return 0;
}
/*
* SONET vs. SDH Configuration
*
* Z0INS (register 0x06): 0 for SONET, 1 for SDH
* ENSS (register 0x3D): 0 for SONET, 1 for SDH
* LEN16 (register 0x28): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
* LEN16 (register 0x50): 0 for SONET, 1 for SDH (n/a for S/UNI 155 QUAD)
* S[1:0] (register 0x46): 00 for SONET, 10 for SDH
*/
static int set_sonet(struct atm_dev *dev)
{
if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
PUT(GET(RPOP_RC) & ~SUNI_RPOP_RC_ENSS, RPOP_RC);
PUT(GET(SSTB_CTRL) & ~SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
PUT(GET(SPTB_CTRL) & ~SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
}
REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
SUNI_TPOP_S_SONET, TPOP_APM);
return 0;
}
static int set_sdh(struct atm_dev *dev)
{
if (PRIV(dev)->type == SUNI_MRI_TYPE_PM5355) {
PUT(GET(RPOP_RC) | SUNI_RPOP_RC_ENSS, RPOP_RC);
PUT(GET(SSTB_CTRL) | SUNI_SSTB_CTRL_LEN16, SSTB_CTRL);
PUT(GET(SPTB_CTRL) | SUNI_SPTB_CTRL_LEN16, SPTB_CTRL);
}
REG_CHANGE(SUNI_TPOP_APM_S, SUNI_TPOP_APM_S_SHIFT,
SUNI_TPOP_S_SDH, TPOP_APM);
return 0;
}
static int get_framing(struct atm_dev *dev, void __user *arg)
{
int framing;
unsigned char s;
s = (GET(TPOP_APM) & SUNI_TPOP_APM_S) >> SUNI_TPOP_APM_S_SHIFT;
if (s == SUNI_TPOP_S_SONET)
framing = SONET_FRAME_SONET;
else
framing = SONET_FRAME_SDH;
return put_user(framing, (int __user *) arg) ? -EFAULT : 0;
}
static int set_framing(struct atm_dev *dev, void __user *arg)
{
int mode;
if (get_user(mode, (int __user *) arg))
return -EFAULT;
if (mode == SONET_FRAME_SONET)
return set_sonet(dev);
else if (mode == SONET_FRAME_SDH)
return set_sdh(dev);
return -EINVAL;
}
static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
switch (cmd) {
case SONET_GETSTATZ:
case SONET_GETSTAT:
return fetch_stats(dev, arg, cmd == SONET_GETSTATZ);
case SONET_SETDIAG:
return change_diag(dev,arg,1);
case SONET_CLRDIAG:
return change_diag(dev,arg,0);
case SONET_GETDIAG:
return get_diag(dev,arg);
case SONET_SETFRAMING:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
return set_framing(dev, arg);
case SONET_GETFRAMING:
return get_framing(dev, arg);
case SONET_GETFRSENSE:
return -EINVAL;
case ATM_SETLOOP:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
return set_loopback(dev,(int)(unsigned long)arg);
case ATM_GETLOOP:
return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-EFAULT : 0;
case ATM_QUERYLOOP:
return put_user(ATM_LM_LOC_PHY | ATM_LM_RMT_PHY,
(int __user *) arg) ? -EFAULT : 0;
default:
return -ENOIOCTLCMD;
}
}
static void poll_los(struct atm_dev *dev)
{
atm_dev_signal_change(dev,
GET(RSOP_SIS) & SUNI_RSOP_SIS_LOSV ?
ATM_PHY_SIG_LOST : ATM_PHY_SIG_FOUND);
}
static void suni_int(struct atm_dev *dev)
{
poll_los(dev);
printk(KERN_NOTICE "%s(itf %d): signal %s\n",dev->type,dev->number,
dev->signal == ATM_PHY_SIG_LOST ? "lost" : "detected again");
}
static int suni_start(struct atm_dev *dev)
{
unsigned long flags;
int first;
spin_lock_irqsave(&sunis_lock,flags);
first = !sunis;
PRIV(dev)->next = sunis;
sunis = PRIV(dev);
spin_unlock_irqrestore(&sunis_lock,flags);
memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats));
PUT(GET(RSOP_CIE) | SUNI_RSOP_CIE_LOSE,RSOP_CIE);
/* interrupt on loss of signal */
poll_los(dev); /* ... and clear SUNI interrupts */
if (dev->signal == ATM_PHY_SIG_LOST)
printk(KERN_WARNING "%s(itf %d): no signal\n",dev->type,
dev->number);
PRIV(dev)->loop_mode = ATM_LM_NONE;
suni_hz(0); /* clear SUNI counters */
(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
if (first) {
init_timer(&poll_timer);
poll_timer.expires = jiffies+HZ;
poll_timer.function = suni_hz;
poll_timer.data = 1;
#if 0
printk(KERN_DEBUG "[u] p=0x%lx,n=0x%lx\n",(unsigned long) poll_timer.list.prev,
(unsigned long) poll_timer.list.next);
#endif
add_timer(&poll_timer);
}
return 0;
}
static int suni_stop(struct atm_dev *dev)
{
struct suni_priv **walk;
unsigned long flags;
/* let SAR driver worry about stopping interrupts */
spin_lock_irqsave(&sunis_lock,flags);
for (walk = &sunis; *walk != PRIV(dev);
walk = &PRIV((*walk)->dev)->next);
*walk = PRIV((*walk)->dev)->next;
if (!sunis) del_timer_sync(&poll_timer);
spin_unlock_irqrestore(&sunis_lock,flags);
kfree(PRIV(dev));
return 0;
}
static const struct atmphy_ops suni_ops = {
.start = suni_start,
.ioctl = suni_ioctl,
.interrupt = suni_int,
.stop = suni_stop,
};
int suni_init(struct atm_dev *dev)
{
unsigned char mri;
if (!(dev->phy_data = kmalloc(sizeof(struct suni_priv),GFP_KERNEL)))
return -ENOMEM;
PRIV(dev)->dev = dev;
mri = GET(MRI); /* reset SUNI */
PRIV(dev)->type = (mri & SUNI_MRI_TYPE) >> SUNI_MRI_TYPE_SHIFT;
PUT(mri | SUNI_MRI_RESET,MRI);
PUT(mri,MRI);
PUT((GET(MT) & SUNI_MT_DS27_53),MT); /* disable all tests */
set_sonet(dev);
REG_CHANGE(SUNI_TACP_IUCHP_CLP,0,SUNI_TACP_IUCHP_CLP,
TACP_IUCHP); /* idle cells */
PUT(SUNI_IDLE_PATTERN,TACP_IUCPOP);
dev->phy = &suni_ops;
return 0;
}
EXPORT_SYMBOL(suni_init);
MODULE_LICENSE("GPL");

241
drivers/atm/suni.h Normal file
View file

@ -0,0 +1,241 @@
/*
* drivers/atm/suni.h - S/UNI PHY driver
*/
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
#ifndef DRIVER_ATM_SUNI_H
#define DRIVER_ATM_SUNI_H
#include <linux/atmdev.h>
#include <linux/atmioc.h>
#include <linux/sonet.h>
/* SUNI registers */
#define SUNI_MRI 0x00 /* Master Reset and Identity / Load
Meter */
#define SUNI_MC 0x01 /* Master Configuration */
#define SUNI_MIS 0x02 /* Master Interrupt Status */
/* no 0x03 */
#define SUNI_MCM 0x04 /* Master Clock Monitor */
#define SUNI_MCT 0x05 /* Master Control */
#define SUNI_CSCS 0x06 /* Clock Synthesis Control and Status */
#define SUNI_CRCS 0x07 /* Clock Recovery Control and Status */
/* 0x08-0x0F reserved */
#define SUNI_RSOP_CIE 0x10 /* RSOP Control/Interrupt Enable */
#define SUNI_RSOP_SIS 0x11 /* RSOP Status/Interrupt Status */
#define SUNI_RSOP_SBL 0x12 /* RSOP Section BIP-8 LSB */
#define SUNI_RSOP_SBM 0x13 /* RSOP Section BIP-8 MSB */
#define SUNI_TSOP_CTRL 0x14 /* TSOP Control */
#define SUNI_TSOP_DIAG 0x15 /* TSOP Diagnostic */
/* 0x16-0x17 reserved */
#define SUNI_RLOP_CS 0x18 /* RLOP Control/Status */
#define SUNI_RLOP_IES 0x19 /* RLOP Interrupt Enable/Status */
#define SUNI_RLOP_LBL 0x1A /* RLOP Line BIP-8/24 LSB */
#define SUNI_RLOP_LB 0x1B /* RLOP Line BIP-8/24 */
#define SUNI_RLOP_LBM 0x1C /* RLOP Line BIP-8/24 MSB */
#define SUNI_RLOP_LFL 0x1D /* RLOP Line FEBE LSB */
#define SUNI_RLOP_LF 0x1E /* RLOP Line FEBE */
#define SUNI_RLOP_LFM 0x1F /* RLOP Line FEBE MSB */
#define SUNI_TLOP_CTRL 0x20 /* TLOP Control */
#define SUNI_TLOP_DIAG 0x21 /* TLOP Diagnostic */
/* 0x22-0x27 reserved */
#define SUNI_SSTB_CTRL 0x28
#define SUNI_RPOP_SC 0x30 /* RPOP Status/Control */
#define SUNI_RPOP_IS 0x31 /* RPOP Interrupt Status */
/* 0x32 reserved */
#define SUNI_RPOP_IE 0x33 /* RPOP Interrupt Enable */
/* 0x34-0x36 reserved */
#define SUNI_RPOP_PSL 0x37 /* RPOP Path Signal Label */
#define SUNI_RPOP_PBL 0x38 /* RPOP Path BIP-8 LSB */
#define SUNI_RPOP_PBM 0x39 /* RPOP Path BIP-8 MSB */
#define SUNI_RPOP_PFL 0x3A /* RPOP Path FEBE LSB */
#define SUNI_RPOP_PFM 0x3B /* RPOP Path FEBE MSB */
/* 0x3C reserved */
#define SUNI_RPOP_PBC 0x3D /* RPOP Path BIP-8 Configuration */
#define SUNI_RPOP_RC 0x3D /* RPOP Ring Control (PM5355) */
/* 0x3E-0x3F reserved */
#define SUNI_TPOP_CD 0x40 /* TPOP Control/Diagnostic */
#define SUNI_TPOP_PC 0x41 /* TPOP Pointer Control */
/* 0x42-0x44 reserved */
#define SUNI_TPOP_APL 0x45 /* TPOP Arbitrary Pointer LSB */
#define SUNI_TPOP_APM 0x46 /* TPOP Arbitrary Pointer MSB */
/* 0x47 reserved */
#define SUNI_TPOP_PSL 0x48 /* TPOP Path Signal Label */
#define SUNI_TPOP_PS 0x49 /* TPOP Path Status */
/* 0x4A-0x4F reserved */
#define SUNI_RACP_CS 0x50 /* RACP Control/Status */
#define SUNI_RACP_IES 0x51 /* RACP Interrupt Enable/Status */
#define SUNI_RACP_MHP 0x52 /* RACP Match Header Pattern */
#define SUNI_RACP_MHM 0x53 /* RACP Match Header Mask */
#define SUNI_RACP_CHEC 0x54 /* RACP Correctable HCS Error Count */
#define SUNI_RACP_UHEC 0x55 /* RACP Uncorrectable HCS Err Count */
#define SUNI_RACP_RCCL 0x56 /* RACP Receive Cell Counter LSB */
#define SUNI_RACP_RCC 0x57 /* RACP Receive Cell Counter */
#define SUNI_RACP_RCCM 0x58 /* RACP Receive Cell Counter MSB */
#define SUNI_RACP_CFG 0x59 /* RACP Configuration */
/* 0x5A-0x5F reserved */
#define SUNI_TACP_CS 0x60 /* TACP Control/Status */
#define SUNI_TACP_IUCHP 0x61 /* TACP Idle/Unassigned Cell Hdr Pat */
#define SUNI_TACP_IUCPOP 0x62 /* TACP Idle/Unassigned Cell Payload
Octet Pattern */
#define SUNI_TACP_FIFO 0x63 /* TACP FIFO Configuration */
#define SUNI_TACP_TCCL 0x64 /* TACP Transmit Cell Counter LSB */
#define SUNI_TACP_TCC 0x65 /* TACP Transmit Cell Counter */
#define SUNI_TACP_TCCM 0x66 /* TACP Transmit Cell Counter MSB */
#define SUNI_TACP_CFG 0x67 /* TACP Configuration */
#define SUNI_SPTB_CTRL 0x68 /* SPTB Control */
/* 0x69-0x7F reserved */
#define SUNI_MT 0x80 /* Master Test */
/* 0x81-0xFF reserved */
/* SUNI register values */
/* MRI is reg 0 */
#define SUNI_MRI_ID 0x0f /* R, SUNI revision number */
#define SUNI_MRI_ID_SHIFT 0
#define SUNI_MRI_TYPE 0x70 /* R, SUNI type (lite is 011) */
#define SUNI_MRI_TYPE_SHIFT 4
#define SUNI_MRI_TYPE_PM5346 0x3 /* S/UNI 155 LITE */
#define SUNI_MRI_TYPE_PM5347 0x4 /* S/UNI 155 PLUS */
#define SUNI_MRI_TYPE_PM5350 0x7 /* S/UNI 155 ULTRA */
#define SUNI_MRI_TYPE_PM5355 0x1 /* S/UNI 622 */
#define SUNI_MRI_RESET 0x80 /* RW, reset & power down chip
0: normal operation
1: reset & low power */
/* MCM is reg 0x4 */
#define SUNI_MCM_LLE 0x20 /* line loopback (PM5355) */
#define SUNI_MCM_DLE 0x10 /* diagnostic loopback (PM5355) */
/* MCT is reg 5 */
#define SUNI_MCT_LOOPT 0x01 /* RW, timing source, 0: from
TRCLK+/- */
#define SUNI_MCT_DLE 0x02 /* RW, diagnostic loopback */
#define SUNI_MCT_LLE 0x04 /* RW, line loopback */
#define SUNI_MCT_FIXPTR 0x20 /* RW, disable transmit payload pointer
adjustments
0: payload ptr controlled by TPOP
ptr control reg
1: payload pointer fixed at 522 */
#define SUNI_MCT_LCDV 0x40 /* R, loss of cell delineation */
#define SUNI_MCT_LCDE 0x80 /* RW, loss of cell delineation
interrupt (1: on) */
/* RSOP_CIE is reg 0x10 */
#define SUNI_RSOP_CIE_OOFE 0x01 /* RW, enable interrupt on frame alarm
state change */
#define SUNI_RSOP_CIE_LOFE 0x02 /* RW, enable interrupt on loss of
frame state change */
#define SUNI_RSOP_CIE_LOSE 0x04 /* RW, enable interrupt on loss of
signal state change */
#define SUNI_RSOP_CIE_BIPEE 0x08 /* RW, enable interrupt on section
BIP-8 error (B1) */
#define SUNI_RSOP_CIE_FOOF 0x20 /* W, force RSOP out of frame at next
boundary */
#define SUNI_RSOP_CIE_DDS 0x40 /* RW, disable scrambling */
/* RSOP_SIS is reg 0x11 */
#define SUNI_RSOP_SIS_OOFV 0x01 /* R, out of frame */
#define SUNI_RSOP_SIS_LOFV 0x02 /* R, loss of frame */
#define SUNI_RSOP_SIS_LOSV 0x04 /* R, loss of signal */
#define SUNI_RSOP_SIS_OOFI 0x08 /* R, out of frame interrupt */
#define SUNI_RSOP_SIS_LOFI 0x10 /* R, loss of frame interrupt */
#define SUNI_RSOP_SIS_LOSI 0x20 /* R, loss of signal interrupt */
#define SUNI_RSOP_SIS_BIPEI 0x40 /* R, section BIP-8 interrupt */
/* TSOP_CTRL is reg 0x14 */
#define SUNI_TSOP_CTRL_LAIS 0x01 /* insert alarm indication signal */
#define SUNI_TSOP_CTRL_DS 0x40 /* disable scrambling */
/* TSOP_DIAG is reg 0x15 */
#define SUNI_TSOP_DIAG_DFP 0x01 /* insert single bit error cont. */
#define SUNI_TSOP_DIAG_DBIP8 0x02 /* insert section BIP err (cont) */
#define SUNI_TSOP_DIAG_DLOS 0x04 /* set line to zero (loss of signal) */
/* TLOP_DIAG is reg 0x21 */
#define SUNI_TLOP_DIAG_DBIP 0x01 /* insert line BIP err (continuously) */
/* SSTB_CTRL is reg 0x28 */
#define SUNI_SSTB_CTRL_LEN16 0x01 /* path trace message length bit */
/* RPOP_RC is reg 0x3D (PM5355) */
#define SUNI_RPOP_RC_ENSS 0x40 /* enable size bit */
/* TPOP_DIAG is reg 0x40 */
#define SUNI_TPOP_DIAG_PAIS 0x01 /* insert STS path alarm ind (cont) */
#define SUNI_TPOP_DIAG_DB3 0x02 /* insert path BIP err (continuously) */
/* TPOP_APM is reg 0x46 */
#define SUNI_TPOP_APM_APTR 0x03 /* RW, arbitrary pointer, upper 2
bits */
#define SUNI_TPOP_APM_APTR_SHIFT 0
#define SUNI_TPOP_APM_S 0x0c /* RW, "unused" bits of payload
pointer */
#define SUNI_TPOP_APM_S_SHIFT 2
#define SUNI_TPOP_APM_NDF 0xf0 /* RW, NDF bits */
#define SUNI_TPOP_APM_NDF_SHIFT 4
#define SUNI_TPOP_S_SONET 0 /* set S bits to 00 */
#define SUNI_TPOP_S_SDH 2 /* set S bits to 10 */
/* RACP_IES is reg 0x51 */
#define SUNI_RACP_IES_FOVRI 0x02 /* R, FIFO overrun */
#define SUNI_RACP_IES_UHCSI 0x04 /* R, uncorrectable HCS error */
#define SUNI_RACP_IES_CHCSI 0x08 /* R, correctable HCS error */
#define SUNI_RACP_IES_OOCDI 0x10 /* R, change of cell delineation
state */
#define SUNI_RACP_IES_FIFOE 0x20 /* RW, enable FIFO overrun interrupt */
#define SUNI_RACP_IES_HCSE 0x40 /* RW, enable HCS error interrupt */
#define SUNI_RACP_IES_OOCDE 0x80 /* RW, enable cell delineation state
change interrupt */
/* TACP_CS is reg 0x60 */
#define SUNI_TACP_CS_FIFORST 0x01 /* RW, reset transmit FIFO (sticky) */
#define SUNI_TACP_CS_DSCR 0x02 /* RW, disable payload scrambling */
#define SUNI_TACP_CS_HCAADD 0x04 /* RW, add coset polynomial to HCS */
#define SUNI_TACP_CS_DHCS 0x10 /* RW, insert HCS errors */
#define SUNI_TACP_CS_FOVRI 0x20 /* R, FIFO overrun */
#define SUNI_TACP_CS_TSOCI 0x40 /* R, TSOC input high */
#define SUNI_TACP_CS_FIFOE 0x80 /* RW, enable FIFO overrun interrupt */
/* TACP_IUCHP is reg 0x61 */
#define SUNI_TACP_IUCHP_CLP 0x01 /* RW, 8th bit of 4th octet of i/u
pattern */
#define SUNI_TACP_IUCHP_PTI 0x0e /* RW, 5th-7th bits of 4th octet of i/u
pattern */
#define SUNI_TACP_IUCHP_PTI_SHIFT 1
#define SUNI_TACP_IUCHP_GFC 0xf0 /* RW, 1st-4th bits of 1st octet of i/u
pattern */
#define SUNI_TACP_IUCHP_GFC_SHIFT 4
/* SPTB_CTRL is reg 0x68 */
#define SUNI_SPTB_CTRL_LEN16 0x01 /* path trace message length */
/* MT is reg 0x80 */
#define SUNI_MT_HIZIO 0x01 /* RW, all but data bus & MP interface
tri-state */
#define SUNI_MT_HIZDATA 0x02 /* W, also tri-state data bus */
#define SUNI_MT_IOTST 0x04 /* RW, enable test mode */
#define SUNI_MT_DBCTRL 0x08 /* W, control data bus by CSB pin */
#define SUNI_MT_PMCTST 0x10 /* W, PMC test mode */
#define SUNI_MT_DS27_53 0x80 /* RW, select between 8- or 16- bit */
#define SUNI_IDLE_PATTERN 0x6a /* idle pattern */
#ifdef __KERNEL__
struct suni_priv {
struct k_sonet_stats sonet_stats; /* link diagnostics */
int loop_mode; /* loopback mode */
int type; /* phy type */
struct atm_dev *dev; /* device back-pointer */
struct suni_priv *next; /* next SUNI */
};
int suni_init(struct atm_dev *dev);
#endif
#endif

20
drivers/atm/tonga.h Normal file
View file

@ -0,0 +1,20 @@
/* drivers/atm/tonga.h - Efficient Networks Tonga (PCI bridge) declarations */
/* Written 1995 by Werner Almesberger, EPFL LRC */
#ifndef DRIVER_ATM_TONGA_H
#define DRIVER_ATM_TONGA_H
#define PCI_TONGA_CTRL 0x60 /* control register */
#define END_SWAP_DMA 0x80 /* endian swap on DMA */
#define END_SWAP_BYTE 0x40 /* endian swap on slave byte accesses */
#define END_SWAP_WORD 0x20 /* endian swap on slave word accesses */
#define SEPROM_MAGIC 0x0c /* obscure required pattern (ASIC only) */
#define SEPROM_DATA 0x02 /* serial EEPROM data (ASIC only) */
#define SEPROM_CLK 0x01 /* serial EEPROM clock (ASIC only) */
#define SEPROM_ESI_BASE 64 /* start of ESI in serial EEPROM */
#endif

292
drivers/atm/uPD98401.h Normal file
View file

@ -0,0 +1,292 @@
/* drivers/atm/uPD98401.h - NEC uPD98401 (SAR) declarations */
/* Written 1995 by Werner Almesberger, EPFL LRC */
#ifndef DRIVERS_ATM_uPD98401_H
#define DRIVERS_ATM_uPD98401_H
#define MAX_CRAM_SIZE (1 << 18) /* 2^18 words */
#define RAM_INCREMENT 1024 /* check in 4 kB increments */
#define uPD98401_PORTS 0x24 /* probably more ? */
/*
* Commands
*/
#define uPD98401_OPEN_CHAN 0x20000000 /* open channel */
#define uPD98401_CHAN_ADDR 0x0003fff8 /* channel address */
#define uPD98401_CHAN_ADDR_SHIFT 3
#define uPD98401_CLOSE_CHAN 0x24000000 /* close channel */
#define uPD98401_CHAN_RT 0x02000000 /* RX/TX (0 TX, 1 RX) */
#define uPD98401_DEACT_CHAN 0x28000000 /* deactivate channel */
#define uPD98401_TX_READY 0x30000000 /* TX ready */
#define uPD98401_ADD_BAT 0x34000000 /* add batches */
#define uPD98401_POOL 0x000f0000 /* pool number */
#define uPD98401_POOL_SHIFT 16
#define uPD98401_POOL_NUMBAT 0x0000ffff /* number of batches */
#define uPD98401_NOP 0x3f000000 /* NOP */
#define uPD98401_IND_ACC 0x00000000 /* Indirect Access */
#define uPD98401_IA_RW 0x10000000 /* Read/Write (0 W, 1 R) */
#define uPD98401_IA_B3 0x08000000 /* Byte select, 1 enable */
#define uPD98401_IA_B2 0x04000000
#define uPD98401_IA_B1 0x02000000
#define uPD98401_IA_B0 0x01000000
#define uPD98401_IA_BALL 0x0f000000 /* whole longword */
#define uPD98401_IA_TGT 0x000c0000 /* Target */
#define uPD98401_IA_TGT_SHIFT 18
#define uPD98401_IA_TGT_CM 0 /* - Control Memory */
#define uPD98401_IA_TGT_SAR 1 /* - uPD98401 registers */
#define uPD98401_IA_TGT_PHY 3 /* - PHY device */
#define uPD98401_IA_ADDR 0x0003ffff
/*
* Command Register Status
*/
#define uPD98401_BUSY 0x80000000 /* SAR is busy */
#define uPD98401_LOCKED 0x40000000 /* SAR is locked by other CPU */
/*
* Indications
*/
/* Normal (AAL5) Receive Indication */
#define uPD98401_AAL5_UINFO 0xffff0000 /* user-supplied information */
#define uPD98401_AAL5_UINFO_SHIFT 16
#define uPD98401_AAL5_SIZE 0x0000ffff /* PDU size (in _CELLS_ !!) */
#define uPD98401_AAL5_CHAN 0x7fff0000 /* Channel number */
#define uPD98401_AAL5_CHAN_SHIFT 16
#define uPD98401_AAL5_ERR 0x00008000 /* Error indication */
#define uPD98401_AAL5_CI 0x00004000 /* Congestion Indication */
#define uPD98401_AAL5_CLP 0x00002000 /* CLP (>= 1 cell had CLP=1) */
#define uPD98401_AAL5_ES 0x00000f00 /* Error Status */
#define uPD98401_AAL5_ES_SHIFT 8
#define uPD98401_AAL5_ES_NONE 0 /* No error */
#define uPD98401_AAL5_ES_FREE 1 /* Receiver free buf underflow */
#define uPD98401_AAL5_ES_FIFO 2 /* Receiver FIFO overrun */
#define uPD98401_AAL5_ES_TOOBIG 3 /* Maximum length violation */
#define uPD98401_AAL5_ES_CRC 4 /* CRC error */
#define uPD98401_AAL5_ES_ABORT 5 /* User abort */
#define uPD98401_AAL5_ES_LENGTH 6 /* Length violation */
#define uPD98401_AAL5_ES_T1 7 /* T1 error (timeout) */
#define uPD98401_AAL5_ES_DEACT 8 /* Deactivated with DEACT_CHAN */
#define uPD98401_AAL5_POOL 0x0000001f /* Free buffer pool number */
/* Raw Cell Indication */
#define uPD98401_RAW_UINFO uPD98401_AAL5_UINFO
#define uPD98401_RAW_UINFO_SHIFT uPD98401_AAL5_UINFO_SHIFT
#define uPD98401_RAW_HEC 0x000000ff /* HEC */
#define uPD98401_RAW_CHAN uPD98401_AAL5_CHAN
#define uPD98401_RAW_CHAN_SHIFT uPD98401_AAL5_CHAN_SHIFT
/* Transmit Indication */
#define uPD98401_TXI_CONN 0x7fff0000 /* Connection Number */
#define uPD98401_TXI_CONN_SHIFT 16
#define uPD98401_TXI_ACTIVE 0x00008000 /* Channel remains active */
#define uPD98401_TXI_PQP 0x00007fff /* Packet Queue Pointer */
/*
* Directly Addressable Registers
*/
#define uPD98401_GMR 0x00 /* General Mode Register */
#define uPD98401_GSR 0x01 /* General Status Register */
#define uPD98401_IMR 0x02 /* Interrupt Mask Register */
#define uPD98401_RQU 0x03 /* Receive Queue Underrun */
#define uPD98401_RQA 0x04 /* Receive Queue Alert */
#define uPD98401_ADDR 0x05 /* Last Burst Address */
#define uPD98401_VER 0x06 /* Version Number */
#define uPD98401_SWR 0x07 /* Software Reset */
#define uPD98401_CMR 0x08 /* Command Register */
#define uPD98401_CMR_L 0x09 /* Command Register and Lock/Unlock */
#define uPD98401_CER 0x0a /* Command Extension Register */
#define uPD98401_CER_L 0x0b /* Command Ext Reg and Lock/Unlock */
#define uPD98401_MSH(n) (0x10+(n)) /* Mailbox n Start Address High */
#define uPD98401_MSL(n) (0x14+(n)) /* Mailbox n Start Address High */
#define uPD98401_MBA(n) (0x18+(n)) /* Mailbox n Bottom Address */
#define uPD98401_MTA(n) (0x1c+(n)) /* Mailbox n Tail Address */
#define uPD98401_MWA(n) (0x20+(n)) /* Mailbox n Write Address */
/* GMR is at 0x00 */
#define uPD98401_GMR_ONE 0x80000000 /* Must be set to one */
#define uPD98401_GMR_SLM 0x40000000 /* Address mode (0 word, 1 byte) */
#define uPD98401_GMR_CPE 0x00008000 /* Control Memory Parity Enable */
#define uPD98401_GMR_LP 0x00004000 /* Loopback */
#define uPD98401_GMR_WA 0x00002000 /* Early Bus Write Abort/RDY */
#define uPD98401_GMR_RA 0x00001000 /* Early Read Abort/RDY */
#define uPD98401_GMR_SZ 0x00000f00 /* Burst Size Enable */
#define uPD98401_BURST16 0x00000800 /* 16-word burst */
#define uPD98401_BURST8 0x00000400 /* 8-word burst */
#define uPD98401_BURST4 0x00000200 /* 4-word burst */
#define uPD98401_BURST2 0x00000100 /* 2-word burst */
#define uPD98401_GMR_AD 0x00000080 /* Address (burst resolution) Disable */
#define uPD98401_GMR_BO 0x00000040 /* Byte Order (0 little, 1 big) */
#define uPD98401_GMR_PM 0x00000020 /* Bus Parity Mode (0 byte, 1 word)*/
#define uPD98401_GMR_PC 0x00000010 /* Bus Parity Control (0even,1odd) */
#define uPD98401_GMR_BPE 0x00000008 /* Bus Parity Enable */
#define uPD98401_GMR_DR 0x00000004 /* Receive Drop Mode (0drop,1don't)*/
#define uPD98401_GMR_SE 0x00000002 /* Shapers Enable */
#define uPD98401_GMR_RE 0x00000001 /* Receiver Enable */
/* GSR is at 0x01, IMR is at 0x02 */
#define uPD98401_INT_PI 0x80000000 /* PHY interrupt */
#define uPD98401_INT_RQA 0x40000000 /* Receive Queue Alert */
#define uPD98401_INT_RQU 0x20000000 /* Receive Queue Underrun */
#define uPD98401_INT_RD 0x10000000 /* Receiver Deactivated */
#define uPD98401_INT_SPE 0x08000000 /* System Parity Error */
#define uPD98401_INT_CPE 0x04000000 /* Control Memory Parity Error */
#define uPD98401_INT_SBE 0x02000000 /* System Bus Error */
#define uPD98401_INT_IND 0x01000000 /* Initialization Done */
#define uPD98401_INT_RCR 0x0000ff00 /* Raw Cell Received */
#define uPD98401_INT_RCR_SHIFT 8
#define uPD98401_INT_MF 0x000000f0 /* Mailbox Full */
#define uPD98401_INT_MF_SHIFT 4
#define uPD98401_INT_MM 0x0000000f /* Mailbox Modified */
/* VER is at 0x06 */
#define uPD98401_MAJOR 0x0000ff00 /* Major revision */
#define uPD98401_MAJOR_SHIFT 8
#define uPD98401_MINOR 0x000000ff /* Minor revision */
/*
* Indirectly Addressable Registers
*/
#define uPD98401_IM(n) (0x40000+(n)) /* Scheduler n I and M */
#define uPD98401_X(n) (0x40010+(n)) /* Scheduler n X */
#define uPD98401_Y(n) (0x40020+(n)) /* Scheduler n Y */
#define uPD98401_PC(n) (0x40030+(n)) /* Scheduler n P, C, p and c */
#define uPD98401_PS(n) (0x40040+(n)) /* Scheduler n priority and status */
/* IM contents */
#define uPD98401_IM_I 0xff000000 /* I */
#define uPD98401_IM_I_SHIFT 24
#define uPD98401_IM_M 0x00ffffff /* M */
/* PC contents */
#define uPD98401_PC_P 0xff000000 /* P */
#define uPD98401_PC_P_SHIFT 24
#define uPD98401_PC_C 0x00ff0000 /* C */
#define uPD98401_PC_C_SHIFT 16
#define uPD98401_PC_p 0x0000ff00 /* p */
#define uPD98401_PC_p_SHIFT 8
#define uPD98401_PC_c 0x000000ff /* c */
/* PS contents */
#define uPD98401_PS_PRIO 0xf0 /* Priority level (0 high, 15 low) */
#define uPD98401_PS_PRIO_SHIFT 4
#define uPD98401_PS_S 0x08 /* Scan - must be 0 (internal) */
#define uPD98401_PS_R 0x04 /* Round Robin (internal) */
#define uPD98401_PS_A 0x02 /* Active (internal) */
#define uPD98401_PS_E 0x01 /* Enabled */
#define uPD98401_TOS 0x40100 /* Top of Stack Control Memory Address */
#define uPD98401_SMA 0x40200 /* Shapers Control Memory Start Address */
#define uPD98401_PMA 0x40201 /* Receive Pool Control Memory Start Address */
#define uPD98401_T1R 0x40300 /* T1 Register */
#define uPD98401_VRR 0x40301 /* VPI/VCI Reduction Register/Recv. Shutdown */
#define uPD98401_TSR 0x40302 /* Time-Stamp Register */
/* VRR is at 0x40301 */
#define uPD98401_VRR_SDM 0x80000000 /* Shutdown Mode */
#define uPD98401_VRR_SHIFT 0x000f0000 /* VPI/VCI Shift */
#define uPD98401_VRR_SHIFT_SHIFT 16
#define uPD98401_VRR_MASK 0x0000ffff /* VPI/VCI mask */
/*
* TX packet descriptor
*/
#define uPD98401_TXPD_SIZE 16 /* descriptor size (in bytes) */
#define uPD98401_TXPD_V 0x80000000 /* Valid bit */
#define uPD98401_TXPD_DP 0x40000000 /* Descriptor (1) or Pointer (0) */
#define uPD98401_TXPD_SM 0x20000000 /* Single (1) or Multiple (0) */
#define uPD98401_TXPD_CLPM 0x18000000 /* CLP mode */
#define uPD98401_CLPM_0 0 /* 00 CLP = 0 */
#define uPD98401_CLPM_1 3 /* 11 CLP = 1 */
#define uPD98401_CLPM_LAST 1 /* 01 CLP unless last cell */
#define uPD98401_TXPD_CLPM_SHIFT 27
#define uPD98401_TXPD_PTI 0x07000000 /* PTI pattern */
#define uPD98401_TXPD_PTI_SHIFT 24
#define uPD98401_TXPD_GFC 0x00f00000 /* GFC pattern */
#define uPD98401_TXPD_GFC_SHIFT 20
#define uPD98401_TXPD_C10 0x00040000 /* insert CRC-10 */
#define uPD98401_TXPD_AAL5 0x00020000 /* AAL5 processing */
#define uPD98401_TXPD_MB 0x00010000 /* TX mailbox number */
#define uPD98401_TXPD_UU 0x0000ff00 /* CPCS-UU */
#define uPD98401_TXPD_UU_SHIFT 8
#define uPD98401_TXPD_CPI 0x000000ff /* CPI */
/*
* TX buffer descriptor
*/
#define uPD98401_TXBD_SIZE 8 /* descriptor size (in bytes) */
#define uPD98401_TXBD_LAST 0x80000000 /* last buffer in packet */
/*
* TX VC table
*/
/* 1st word has the same structure as in a TX packet descriptor */
#define uPD98401_TXVC_L 0x80000000 /* last buffer */
#define uPD98401_TXVC_SHP 0x0f000000 /* shaper number */
#define uPD98401_TXVC_SHP_SHIFT 24
#define uPD98401_TXVC_VPI 0x00ff0000 /* VPI */
#define uPD98401_TXVC_VPI_SHIFT 16
#define uPD98401_TXVC_VCI 0x0000ffff /* VCI */
#define uPD98401_TXVC_QRP 6 /* Queue Read Pointer is in word 6 */
/*
* RX free buffer pools descriptor
*/
#define uPD98401_RXFP_ALERT 0x70000000 /* low water mark */
#define uPD98401_RXFP_ALERT_SHIFT 28
#define uPD98401_RXFP_BFSZ 0x0f000000 /* buffer size, 64*2^n */
#define uPD98401_RXFP_BFSZ_SHIFT 24
#define uPD98401_RXFP_BTSZ 0x00ff0000 /* batch size, n+1 */
#define uPD98401_RXFP_BTSZ_SHIFT 16
#define uPD98401_RXFP_REMAIN 0x0000ffff /* remaining batches in pool */
/*
* RX VC table
*/
#define uPD98401_RXVC_BTSZ 0xff000000 /* remaining free buffers in batch */
#define uPD98401_RXVC_BTSZ_SHIFT 24
#define uPD98401_RXVC_MB 0x00200000 /* RX mailbox number */
#define uPD98401_RXVC_POOL 0x001f0000 /* free buffer pool number */
#define uPD98401_RXVC_POOL_SHIFT 16
#define uPD98401_RXVC_UINFO 0x0000ffff /* user-supplied information */
#define uPD98401_RXVC_T1 0xffff0000 /* T1 timestamp */
#define uPD98401_RXVC_T1_SHIFT 16
#define uPD98401_RXVC_PR 0x00008000 /* Packet Reception, 1 if busy */
#define uPD98401_RXVC_DR 0x00004000 /* FIFO Drop */
#define uPD98401_RXVC_OD 0x00001000 /* Drop OAM cells */
#define uPD98401_RXVC_AR 0x00000800 /* AAL5 or raw cell; 1 if AAL5 */
#define uPD98401_RXVC_MAXSEG 0x000007ff /* max number of segments per PDU */
#define uPD98401_RXVC_REM 0xfffe0000 /* remaining words in curr buffer */
#define uPD98401_RXVC_REM_SHIFT 17
#define uPD98401_RXVC_CLP 0x00010000 /* CLP received */
#define uPD98401_RXVC_BFA 0x00008000 /* Buffer Assigned */
#define uPD98401_RXVC_BTA 0x00004000 /* Batch Assigned */
#define uPD98401_RXVC_CI 0x00002000 /* Congestion Indication */
#define uPD98401_RXVC_DD 0x00001000 /* Dropping incoming cells */
#define uPD98401_RXVC_DP 0x00000800 /* like PR ? */
#define uPD98401_RXVC_CURSEG 0x000007ff /* Current Segment count */
/*
* RX lookup table
*/
#define uPD98401_RXLT_ENBL 0x8000 /* Enable */
#endif

265
drivers/atm/uPD98402.c Normal file
View file

@ -0,0 +1,265 @@
/* drivers/atm/uPD98402.c - NEC uPD98402 (PHY) declarations */
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
#include <linux/atomic.h>
#include "uPD98402.h"
#if 0
#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
#else
#define DPRINTK(format,args...)
#endif
struct uPD98402_priv {
struct k_sonet_stats sonet_stats;/* link diagnostics */
unsigned char framing; /* SONET/SDH framing */
int loop_mode; /* loopback mode */
spinlock_t lock;
};
#define PRIV(dev) ((struct uPD98402_priv *) dev->phy_data)
#define PUT(val,reg) dev->ops->phy_put(dev,val,uPD98402_##reg)
#define GET(reg) dev->ops->phy_get(dev,uPD98402_##reg)
static int fetch_stats(struct atm_dev *dev,struct sonet_stats __user *arg,int zero)
{
struct sonet_stats tmp;
int error = 0;
atomic_add(GET(HECCT),&PRIV(dev)->sonet_stats.uncorr_hcs);
sonet_copy_stats(&PRIV(dev)->sonet_stats,&tmp);
if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
if (zero && !error) {
/* unused fields are reported as -1, but we must not "adjust"
them */
tmp.corr_hcs = tmp.tx_cells = tmp.rx_cells = 0;
sonet_subtract_stats(&PRIV(dev)->sonet_stats,&tmp);
}
return error ? -EFAULT : 0;
}
static int set_framing(struct atm_dev *dev,unsigned char framing)
{
static const unsigned char sonet[] = { 1,2,3,0 };
static const unsigned char sdh[] = { 1,0,0,2 };
const char *set;
unsigned long flags;
switch (framing) {
case SONET_FRAME_SONET:
set = sonet;
break;
case SONET_FRAME_SDH:
set = sdh;
break;
default:
return -EINVAL;
}
spin_lock_irqsave(&PRIV(dev)->lock, flags);
PUT(set[0],C11T);
PUT(set[1],C12T);
PUT(set[2],C13T);
PUT((GET(MDR) & ~uPD98402_MDR_SS_MASK) | (set[3] <<
uPD98402_MDR_SS_SHIFT),MDR);
spin_unlock_irqrestore(&PRIV(dev)->lock, flags);
return 0;
}
static int get_sense(struct atm_dev *dev,u8 __user *arg)
{
unsigned long flags;
unsigned char s[3];
spin_lock_irqsave(&PRIV(dev)->lock, flags);
s[0] = GET(C11R);
s[1] = GET(C12R);
s[2] = GET(C13R);
spin_unlock_irqrestore(&PRIV(dev)->lock, flags);
return (put_user(s[0], arg) || put_user(s[1], arg+1) ||
put_user(s[2], arg+2) || put_user(0xff, arg+3) ||
put_user(0xff, arg+4) || put_user(0xff, arg+5)) ? -EFAULT : 0;
}
static int set_loopback(struct atm_dev *dev,int mode)
{
unsigned char mode_reg;
mode_reg = GET(MDR) & ~(uPD98402_MDR_TPLP | uPD98402_MDR_ALP |
uPD98402_MDR_RPLP);
switch (__ATM_LM_XTLOC(mode)) {
case __ATM_LM_NONE:
break;
case __ATM_LM_PHY:
mode_reg |= uPD98402_MDR_TPLP;
break;
case __ATM_LM_ATM:
mode_reg |= uPD98402_MDR_ALP;
break;
default:
return -EINVAL;
}
switch (__ATM_LM_XTRMT(mode)) {
case __ATM_LM_NONE:
break;
case __ATM_LM_PHY:
mode_reg |= uPD98402_MDR_RPLP;
break;
default:
return -EINVAL;
}
PUT(mode_reg,MDR);
PRIV(dev)->loop_mode = mode;
return 0;
}
static int uPD98402_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
{
switch (cmd) {
case SONET_GETSTATZ:
case SONET_GETSTAT:
return fetch_stats(dev,arg, cmd == SONET_GETSTATZ);
case SONET_SETFRAMING:
return set_framing(dev, (int)(unsigned long)arg);
case SONET_GETFRAMING:
return put_user(PRIV(dev)->framing,(int __user *)arg) ?
-EFAULT : 0;
case SONET_GETFRSENSE:
return get_sense(dev,arg);
case ATM_SETLOOP:
return set_loopback(dev, (int)(unsigned long)arg);
case ATM_GETLOOP:
return put_user(PRIV(dev)->loop_mode,(int __user *)arg) ?
-EFAULT : 0;
case ATM_QUERYLOOP:
return put_user(ATM_LM_LOC_PHY | ATM_LM_LOC_ATM |
ATM_LM_RMT_PHY,(int __user *)arg) ? -EFAULT : 0;
default:
return -ENOIOCTLCMD;
}
}
#define ADD_LIMITED(s,v) \
{ atomic_add(GET(v),&PRIV(dev)->sonet_stats.s); \
if (atomic_read(&PRIV(dev)->sonet_stats.s) < 0) \
atomic_set(&PRIV(dev)->sonet_stats.s,INT_MAX); }
static void stat_event(struct atm_dev *dev)
{
unsigned char events;
events = GET(PCR);
if (events & uPD98402_PFM_PFEB) ADD_LIMITED(path_febe,PFECB);
if (events & uPD98402_PFM_LFEB) ADD_LIMITED(line_febe,LECCT);
if (events & uPD98402_PFM_B3E) ADD_LIMITED(path_bip,B3ECT);
if (events & uPD98402_PFM_B2E) ADD_LIMITED(line_bip,B2ECT);
if (events & uPD98402_PFM_B1E) ADD_LIMITED(section_bip,B1ECT);
}
#undef ADD_LIMITED
static void uPD98402_int(struct atm_dev *dev)
{
static unsigned long silence = 0;
unsigned char reason;
while ((reason = GET(PICR))) {
if (reason & uPD98402_INT_LOS)
printk(KERN_NOTICE "%s(itf %d): signal lost\n",
dev->type,dev->number);
if (reason & uPD98402_INT_PFM) stat_event(dev);
if (reason & uPD98402_INT_PCO) {
(void) GET(PCOCR); /* clear interrupt cause */
atomic_add(GET(HECCT),
&PRIV(dev)->sonet_stats.uncorr_hcs);
}
if ((reason & uPD98402_INT_RFO) &&
(time_after(jiffies, silence) || silence == 0)) {
printk(KERN_WARNING "%s(itf %d): uPD98402 receive "
"FIFO overflow\n",dev->type,dev->number);
silence = (jiffies+HZ/2)|1;
}
}
}
static int uPD98402_start(struct atm_dev *dev)
{
DPRINTK("phy_start\n");
if (!(dev->dev_data = kmalloc(sizeof(struct uPD98402_priv),GFP_KERNEL)))
return -ENOMEM;
spin_lock_init(&PRIV(dev)->lock);
memset(&PRIV(dev)->sonet_stats,0,sizeof(struct k_sonet_stats));
(void) GET(PCR); /* clear performance events */
PUT(uPD98402_PFM_FJ,PCMR); /* ignore frequency adj */
(void) GET(PCOCR); /* clear overflows */
PUT(~uPD98402_PCO_HECC,PCOMR);
(void) GET(PICR); /* clear interrupts */
PUT(~(uPD98402_INT_PFM | uPD98402_INT_ALM | uPD98402_INT_RFO |
uPD98402_INT_LOS),PIMR); /* enable them */
(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
atomic_set(&PRIV(dev)->sonet_stats.corr_hcs,-1);
atomic_set(&PRIV(dev)->sonet_stats.tx_cells,-1);
atomic_set(&PRIV(dev)->sonet_stats.rx_cells,-1);
return 0;
}
static int uPD98402_stop(struct atm_dev *dev)
{
/* let SAR driver worry about stopping interrupts */
kfree(PRIV(dev));
return 0;
}
static const struct atmphy_ops uPD98402_ops = {
.start = uPD98402_start,
.ioctl = uPD98402_ioctl,
.interrupt = uPD98402_int,
.stop = uPD98402_stop,
};
int uPD98402_init(struct atm_dev *dev)
{
DPRINTK("phy_init\n");
dev->phy = &uPD98402_ops;
return 0;
}
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(uPD98402_init);
static __init int uPD98402_module_init(void)
{
return 0;
}
module_init(uPD98402_module_init);
/* module_exit not defined so not unloadable */

106
drivers/atm/uPD98402.h Normal file
View file

@ -0,0 +1,106 @@
/* drivers/atm/uPD98402.h - NEC uPD98402 (PHY) declarations */
/* Written 1995 by Werner Almesberger, EPFL LRC */
#ifndef DRIVERS_ATM_uPD98402_H
#define DRIVERS_ATM_uPD98402_H
/*
* Registers
*/
#define uPD98402_CMR 0x00 /* Command Register */
#define uPD98402_MDR 0x01 /* Mode Register */
#define uPD98402_PICR 0x02 /* PHY Interrupt Cause Register */
#define uPD98402_PIMR 0x03 /* PHY Interrupt Mask Register */
#define uPD98402_ACR 0x04 /* Alarm Cause Register */
#define uPD98402_ACMR 0x05 /* Alarm Cause Mask Register */
#define uPD98402_PCR 0x06 /* Performance Cause Register */
#define uPD98402_PCMR 0x07 /* Performance Cause Mask Register */
#define uPD98402_IACM 0x08 /* Internal Alarm Cause Mask Register */
#define uPD98402_B1ECT 0x09 /* B1 Error Count Register */
#define uPD98402_B2ECT 0x0a /* B2 Error Count Register */
#define uPD98402_B3ECT 0x0b /* B3 Error Count Regster */
#define uPD98402_PFECB 0x0c /* Path FEBE Count Register */
#define uPD98402_LECCT 0x0d /* Line FEBE Count Register */
#define uPD98402_HECCT 0x0e /* HEC Error Count Register */
#define uPD98402_FJCT 0x0f /* Frequence Justification Count Reg */
#define uPD98402_PCOCR 0x10 /* Perf. Counter Overflow Cause Reg */
#define uPD98402_PCOMR 0x11 /* Perf. Counter Overflow Mask Reg */
#define uPD98402_C11T 0x20 /* C11T Data Register */
#define uPD98402_C12T 0x21 /* C12T Data Register */
#define uPD98402_C13T 0x22 /* C13T Data Register */
#define uPD98402_F1T 0x23 /* F1T Data Register */
#define uPD98402_K2T 0x25 /* K2T Data Register */
#define uPD98402_C2T 0x26 /* C2T Data Register */
#define uPD98402_F2T 0x27 /* F2T Data Register */
#define uPD98402_C11R 0x30 /* C11T Data Register */
#define uPD98402_C12R 0x31 /* C12T Data Register */
#define uPD98402_C13R 0x32 /* C13T Data Register */
#define uPD98402_F1R 0x33 /* F1T Data Register */
#define uPD98402_K2R 0x35 /* K2T Data Register */
#define uPD98402_C2R 0x36 /* C2T Data Register */
#define uPD98402_F2R 0x37 /* F2T Data Register */
/* CMR is at 0x00 */
#define uPD98402_CMR_PFRF 0x01 /* Send path FERF */
#define uPD98402_CMR_LFRF 0x02 /* Send line FERF */
#define uPD98402_CMR_PAIS 0x04 /* Send path AIS */
#define uPD98402_CMR_LAIS 0x08 /* Send line AIS */
/* MDR is at 0x01 */
#define uPD98402_MDR_ALP 0x01 /* ATM layer loopback */
#define uPD98402_MDR_TPLP 0x02 /* PMD loopback, to host */
#define uPD98402_MDR_RPLP 0x04 /* PMD loopback, to network */
#define uPD98402_MDR_SS0 0x08 /* SS0 */
#define uPD98402_MDR_SS1 0x10 /* SS1 */
#define uPD98402_MDR_SS_MASK 0x18 /* mask */
#define uPD98402_MDR_SS_SHIFT 3 /* shift */
#define uPD98402_MDR_HEC 0x20 /* disable HEC inbound processing */
#define uPD98402_MDR_FSR 0x40 /* disable frame scrambler */
#define uPD98402_MDR_CSR 0x80 /* disable cell scrambler */
/* PICR is at 0x02, PIMR is at 0x03 */
#define uPD98402_INT_PFM 0x01 /* performance counter has changed */
#define uPD98402_INT_ALM 0x02 /* line fault */
#define uPD98402_INT_RFO 0x04 /* receive FIFO overflow */
#define uPD98402_INT_PCO 0x08 /* performance counter overflow */
#define uPD98402_INT_OTD 0x20 /* OTD has occurred */
#define uPD98402_INT_LOS 0x40 /* Loss Of Signal */
#define uPD98402_INT_LOF 0x80 /* Loss Of Frame */
/* ACR is as 0x04, ACMR is at 0x05 */
#define uPD98402_ALM_PFRF 0x01 /* path FERF */
#define uPD98402_ALM_LFRF 0x02 /* line FERF */
#define uPD98402_ALM_PAIS 0x04 /* path AIS */
#define uPD98402_ALM_LAIS 0x08 /* line AIS */
#define uPD98402_ALM_LOD 0x10 /* loss of delineation */
#define uPD98402_ALM_LOP 0x20 /* loss of pointer */
#define uPD98402_ALM_OOF 0x40 /* out of frame */
/* PCR is at 0x06, PCMR is at 0x07 */
#define uPD98402_PFM_PFEB 0x01 /* path FEBE */
#define uPD98402_PFM_LFEB 0x02 /* line FEBE */
#define uPD98402_PFM_B3E 0x04 /* B3 error */
#define uPD98402_PFM_B2E 0x08 /* B2 error */
#define uPD98402_PFM_B1E 0x10 /* B1 error */
#define uPD98402_PFM_FJ 0x20 /* frequency justification */
/* IACM is at 0x08 */
#define uPD98402_IACM_PFRF 0x01 /* don't generate path FERF */
#define uPD98402_IACM_LFRF 0x02 /* don't generate line FERF */
/* PCOCR is at 0x010, PCOMR is at 0x11 */
#define uPD98402_PCO_B1EC 0x01 /* B1ECT overflow */
#define uPD98402_PCO_B2EC 0x02 /* B2ECT overflow */
#define uPD98402_PCO_B3EC 0x04 /* B3ECT overflow */
#define uPD98402_PCO_PFBC 0x08 /* PFEBC overflow */
#define uPD98402_PCO_LFBC 0x10 /* LFEVC overflow */
#define uPD98402_PCO_HECC 0x20 /* HECCT overflow */
#define uPD98402_PCO_FJC 0x40 /* FJCT overflow */
int uPD98402_init(struct atm_dev *dev);
#endif

1657
drivers/atm/zatm.c Normal file

File diff suppressed because it is too large Load diff

103
drivers/atm/zatm.h Normal file
View file

@ -0,0 +1,103 @@
/* drivers/atm/zatm.h - ZeitNet ZN122x device driver declarations */
/* Written 1995-1998 by Werner Almesberger, EPFL LRC/ICA */
#ifndef DRIVER_ATM_ZATM_H
#define DRIVER_ATM_ZATM_H
#include <linux/skbuff.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/sonet.h>
#include <linux/pci.h>
#define DEV_LABEL "zatm"
#define MAX_AAL5_PDU 10240 /* allocate for AAL5 PDUs of this size */
#define MAX_RX_SIZE_LD 14 /* ceil(log2((MAX_AAL5_PDU+47)/48)) */
#define LOW_MARK 12 /* start adding new buffers if less than 12 */
#define HIGH_MARK 30 /* stop adding buffers after reaching 30 */
#define OFF_CNG_THRES 5 /* threshold for offset changes */
#define RX_SIZE 2 /* RX lookup entry size (in bytes) */
#define NR_POOLS 32 /* number of free buffer pointers */
#define POOL_SIZE 8 /* buffer entry size (in bytes) */
#define NR_SHAPERS 16 /* number of shapers */
#define SHAPER_SIZE 4 /* shaper entry size (in bytes) */
#define VC_SIZE 32 /* VC dsc (TX or RX) size (in bytes) */
#define RING_ENTRIES 32 /* ring entries (without back pointer) */
#define RING_WORDS 4 /* ring element size */
#define RING_SIZE (sizeof(unsigned long)*(RING_ENTRIES+1)*RING_WORDS)
#define NR_MBX 4 /* four mailboxes */
#define MBX_RX_0 0 /* mailbox indices */
#define MBX_RX_1 1
#define MBX_TX_0 2
#define MBX_TX_1 3
struct zatm_vcc {
/*-------------------------------- RX part */
int rx_chan; /* RX channel, 0 if none */
int pool; /* free buffer pool */
/*-------------------------------- TX part */
int tx_chan; /* TX channel, 0 if none */
int shaper; /* shaper, <0 if none */
struct sk_buff_head tx_queue; /* list of buffers in transit */
wait_queue_head_t tx_wait; /* for close */
u32 *ring; /* transmit ring */
int ring_curr; /* current write position */
int txing; /* number of transmits in progress */
struct sk_buff_head backlog; /* list of buffers waiting for ring */
};
struct zatm_dev {
/*-------------------------------- TX part */
int tx_bw; /* remaining bandwidth */
u32 free_shapers; /* bit set */
int ubr; /* UBR shaper; -1 if none */
int ubr_ref_cnt; /* number of VCs using UBR shaper */
/*-------------------------------- RX part */
int pool_ref[NR_POOLS]; /* free buffer pool usage counters */
volatile struct sk_buff *last_free[NR_POOLS];
/* last entry in respective pool */
struct sk_buff_head pool[NR_POOLS];/* free buffer pools */
struct zatm_pool_info pool_info[NR_POOLS]; /* pool information */
/*-------------------------------- maps */
struct atm_vcc **tx_map; /* TX VCCs */
struct atm_vcc **rx_map; /* RX VCCs */
int chans; /* map size, must be 2^n */
/*-------------------------------- mailboxes */
unsigned long mbx_start[NR_MBX];/* start addresses */
dma_addr_t mbx_dma[NR_MBX];
u16 mbx_end[NR_MBX]; /* end offset (in bytes) */
/*-------------------------------- other pointers */
u32 pool_base; /* Free buffer pool dsc (word addr) */
/*-------------------------------- ZATM links */
struct atm_dev *more; /* other ZATM devices */
/*-------------------------------- general information */
int mem; /* RAM on board (in bytes) */
int khz; /* timer clock */
int copper; /* PHY type */
unsigned char irq; /* IRQ */
unsigned int base; /* IO base address */
struct pci_dev *pci_dev; /* PCI stuff */
spinlock_t lock;
};
#define ZATM_DEV(d) ((struct zatm_dev *) (d)->dev_data)
#define ZATM_VCC(d) ((struct zatm_vcc *) (d)->dev_data)
struct zatm_skb_prv {
struct atm_skb_data _; /* reserved */
u32 *dsc; /* pointer to skb's descriptor */
};
#define ZATM_PRV_DSC(skb) (((struct zatm_skb_prv *) (skb)->cb)->dsc)
#endif

34
drivers/atm/zeprom.h Normal file
View file

@ -0,0 +1,34 @@
/* drivers/atm/zeprom.h - ZeitNet ZN122x EEPROM (NM93C46) declarations */
/* Written 1995,1996 by Werner Almesberger, EPFL LRC */
#ifndef DRIVER_ATM_ZEPROM_H
#define DRIVER_ATM_ZEPROM_H
/* Different versions use different control registers */
#define ZEPROM_V1_REG PCI_VENDOR_ID /* PCI register */
#define ZEPROM_V2_REG 0x40
/* Bits in contol register */
#define ZEPROM_SK 0x80000000 /* strobe (probably on raising edge) */
#define ZEPROM_CS 0x40000000 /* Chip Select */
#define ZEPROM_DI 0x20000000 /* Data Input */
#define ZEPROM_DO 0x10000000 /* Data Output */
#define ZEPROM_SIZE 32 /* 32 bytes */
#define ZEPROM_V1_ESI_OFF 24 /* ESI offset in EEPROM (V1) */
#define ZEPROM_V2_ESI_OFF 4 /* ESI offset in EEPROM (V2) */
#define ZEPROM_CMD_LEN 3 /* commands are three bits */
#define ZEPROM_ADDR_LEN 6 /* addresses are six bits */
/* Commands (3 bits) */
#define ZEPROM_CMD_READ 6
/* No other commands are needed. */
#endif