mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-15 23:41:35 -04:00
net: remove unused ATM protocols and legacy ATM device drivers
Remove the ATM protocol modules and PCI/SBUS ATM device drivers that are no longer in active use. The ATM core protocol stack, PPPoATM, BR2684, and USB DSL modem drivers (drivers/usb/atm/) are retained in-tree to maintain PPP over ATM (PPPoA) and PPPoE-over-BR2684 support for DSL connections. The Solos ADSL2+ PCI driver is also retained. Removed ATM protocol modules: - net/atm/clip.c - Classical IP over ATM (RFC 2225) - net/atm/lec.c - LAN Emulation Client (LANE) - net/atm/mpc.c, mpoa_caches.c, mpoa_proc.c - Multi-Protocol Over ATM Removed PCI/SBUS ATM device drivers (drivers/atm/): - adummy, atmtcp - software/testing ATM devices - eni - Efficient Networks ENI155P (OC-3, ~1995) - fore200e - FORE Systems 200E PCI/SBUS (OC-3, ~1999) - he - ForeRunner HE (OC-3/OC-12, ~2000) - idt77105 - IDT 77105 25 Mbps ATM PHY - idt77252 - IDT 77252 NICStAR II (OC-3, ~2000) - iphase - Interphase ATM PCI (OC-3/DS3/E3) - lanai - Efficient Networks Speedstream 3010 - nicstar - IDT 77201 NICStAR (155/25 Mbps, ~1999) - suni - PMC S/UNI SONET PHY library Also clean up references in: - net/bridge/ - remove ATM LANE hook (br_fdb_test_addr_hook, br_fdb_test_addr) - net/core/dev.c - remove br_fdb_test_addr_hook export - defconfig files - remove ATM driver config options The removed code is moved to an out-of-tree module package (mod-orphan). Acked-by: Andy Shevchenko <andriy.shevchenko@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/20260422041846.2035118-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -835,14 +835,12 @@ networking/e100 networking/device_drivers/ethernet/intel/e100
|
||||
networking/e1000 networking/device_drivers/ethernet/intel/e1000
|
||||
networking/e1000e networking/device_drivers/ethernet/intel/e1000e
|
||||
networking/fm10k networking/device_drivers/ethernet/intel/fm10k
|
||||
networking/fore200e networking/device_drivers/atm/fore200e
|
||||
networking/hinic networking/device_drivers/ethernet/huawei/hinic
|
||||
networking/i40e networking/device_drivers/ethernet/intel/i40e
|
||||
networking/iavf networking/device_drivers/ethernet/intel/iavf
|
||||
networking/ice networking/device_drivers/ethernet/intel/ice
|
||||
networking/igb networking/device_drivers/ethernet/intel/igb
|
||||
networking/igbvf networking/device_drivers/ethernet/intel/igbvf
|
||||
networking/iphase networking/device_drivers/atm/iphase
|
||||
networking/ixgbe networking/device_drivers/ethernet/intel/ixgbe
|
||||
networking/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
|
||||
networking/netdev-FAQ process/maintainer-netdev
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
=============================================
|
||||
FORE Systems PCA-200E/SBA-200E ATM NIC driver
|
||||
=============================================
|
||||
|
||||
This driver adds support for the FORE Systems 200E-series ATM adapters
|
||||
to the Linux operating system. It is based on the earlier PCA-200E driver
|
||||
written by Uwe Dannowski.
|
||||
|
||||
The driver simultaneously supports PCA-200E and SBA-200E adapters on
|
||||
i386, alpha (untested), powerpc, sparc and sparc64 archs.
|
||||
|
||||
The intent is to enable the use of different models of FORE adapters at the
|
||||
same time, by hosts that have several bus interfaces (such as PCI+SBUS,
|
||||
or PCI+EISA).
|
||||
|
||||
Only PCI and SBUS devices are currently supported by the driver, but support
|
||||
for other bus interfaces such as EISA should not be too hard to add.
|
||||
|
||||
|
||||
Firmware Copyright Notice
|
||||
-------------------------
|
||||
|
||||
Please read the fore200e_firmware_copyright file present
|
||||
in the linux/drivers/atm directory for details and restrictions.
|
||||
|
||||
|
||||
Firmware Updates
|
||||
----------------
|
||||
|
||||
The FORE Systems 200E-series driver is shipped with firmware data being
|
||||
uploaded to the ATM adapters at system boot time or at module loading time.
|
||||
The supplied firmware images should work with all adapters.
|
||||
|
||||
However, if you encounter problems (the firmware doesn't start or the driver
|
||||
is unable to read the PROM data), you may consider trying another firmware
|
||||
version. Alternative binary firmware images can be found somewhere on the
|
||||
ForeThought CD-ROM supplied with your adapter by FORE Systems.
|
||||
|
||||
You can also get the latest firmware images from FORE Systems at
|
||||
https://en.wikipedia.org/wiki/FORE_Systems. Register TACTics Online and go to
|
||||
the 'software updates' pages. The firmware binaries are part of
|
||||
the various ForeThought software distributions.
|
||||
|
||||
Notice that different versions of the PCA-200E firmware exist, depending
|
||||
on the endianness of the host architecture. The driver is shipped with
|
||||
both little and big endian PCA firmware images.
|
||||
|
||||
Name and location of the new firmware images can be set at kernel
|
||||
configuration time:
|
||||
|
||||
1. Copy the new firmware binary files (with .bin, .bin1 or .bin2 suffix)
|
||||
to some directory, such as linux/drivers/atm.
|
||||
|
||||
2. Reconfigure your kernel to set the new firmware name and location.
|
||||
Expected pathnames are absolute or relative to the drivers/atm directory.
|
||||
|
||||
3. Rebuild and re-install your kernel or your module.
|
||||
|
||||
|
||||
Feedback
|
||||
--------
|
||||
|
||||
Feedback is welcome. Please send success stories/bug reports/
|
||||
patches/improvement/comments/flames to <lizzi@cnam.fr>.
|
||||
@@ -9,5 +9,3 @@ Contents:
|
||||
:maxdepth: 2
|
||||
|
||||
cxacru
|
||||
fore200e
|
||||
iphase
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
==================================
|
||||
ATM (i)Chip IA Linux Driver Source
|
||||
==================================
|
||||
|
||||
READ ME FIRST
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Read This Before You Begin!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
This is the README file for the Interphase PCI ATM (i)Chip IA Linux driver
|
||||
source release.
|
||||
|
||||
The features and limitations of this driver are as follows:
|
||||
|
||||
- A single VPI (VPI value of 0) is supported.
|
||||
- Supports 4K VCs for the server board (with 512K control memory) and 1K
|
||||
VCs for the client board (with 128K control memory).
|
||||
- UBR, ABR and CBR service categories are supported.
|
||||
- Only AAL5 is supported.
|
||||
- Supports setting of PCR on the VCs.
|
||||
- Multiple adapters in a system are supported.
|
||||
- All variants of Interphase ATM PCI (i)Chip adapter cards are supported,
|
||||
including x575 (OC3, control memory 128K , 512K and packet memory 128K,
|
||||
512K and 1M), x525 (UTP25) and x531 (DS3 and E3). See
|
||||
http://www.iphase.com/
|
||||
for details.
|
||||
- Only x86 platforms are supported.
|
||||
- SMP is supported.
|
||||
|
||||
|
||||
Before You Start
|
||||
================
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
1. Installing the adapters in the system
|
||||
|
||||
To install the ATM adapters in the system, follow the steps below.
|
||||
|
||||
a. Login as root.
|
||||
b. Shut down the system and power off the system.
|
||||
c. Install one or more ATM adapters in the system.
|
||||
d. Connect each adapter to a port on an ATM switch. The green 'Link'
|
||||
LED on the front panel of the adapter will be on if the adapter is
|
||||
connected to the switch properly when the system is powered up.
|
||||
e. Power on and boot the system.
|
||||
|
||||
2. [ Removed ]
|
||||
|
||||
3. Rebuild kernel with ABR support
|
||||
|
||||
[ a. and b. removed ]
|
||||
|
||||
c. Reconfigure the kernel, choose the Interphase ia driver through "make
|
||||
menuconfig" or "make xconfig".
|
||||
d. Rebuild the kernel, loadable modules and the atm tools.
|
||||
e. Install the new built kernel and modules and reboot.
|
||||
|
||||
4. Load the adapter hardware driver (ia driver) if it is built as a module
|
||||
|
||||
a. Login as root.
|
||||
b. Change directory to /lib/modules/<kernel-version>/atm.
|
||||
c. Run "insmod suni.o;insmod iphase.o"
|
||||
The yellow 'status' LED on the front panel of the adapter will blink
|
||||
while the driver is loaded in the system.
|
||||
d. To verify that the 'ia' driver is loaded successfully, run the
|
||||
following command::
|
||||
|
||||
cat /proc/atm/devices
|
||||
|
||||
If the driver is loaded successfully, the output of the command will
|
||||
be similar to the following lines::
|
||||
|
||||
Itf Type ESI/"MAC"addr AAL(TX,err,RX,err,drop) ...
|
||||
0 ia xxxxxxxxx 0 ( 0 0 0 0 0 ) 5 ( 0 0 0 0 0 )
|
||||
|
||||
You can also check the system log file /var/log/messages for messages
|
||||
related to the ATM driver.
|
||||
|
||||
5. Ia Driver Configuration
|
||||
|
||||
5.1 Configuration of adapter buffers
|
||||
The (i)Chip boards have 3 different packet RAM size variants: 128K, 512K and
|
||||
1M. The RAM size decides the number of buffers and buffer size. The default
|
||||
size and number of buffers are set as following:
|
||||
|
||||
========= ======= ====== ====== ====== ====== ======
|
||||
Total Rx RAM Tx RAM Rx Buf Tx Buf Rx buf Tx buf
|
||||
RAM size size size size size cnt cnt
|
||||
========= ======= ====== ====== ====== ====== ======
|
||||
128K 64K 64K 10K 10K 6 6
|
||||
512K 256K 256K 10K 10K 25 25
|
||||
1M 512K 512K 10K 10K 51 51
|
||||
========= ======= ====== ====== ====== ====== ======
|
||||
|
||||
These setting should work well in most environments, but can be
|
||||
changed by typing the following command::
|
||||
|
||||
insmod <IA_DIR>/ia.o IA_RX_BUF=<RX_CNT> IA_RX_BUF_SZ=<RX_SIZE> \
|
||||
IA_TX_BUF=<TX_CNT> IA_TX_BUF_SZ=<TX_SIZE>
|
||||
|
||||
Where:
|
||||
|
||||
- RX_CNT = number of receive buffers in the range (1-128)
|
||||
- RX_SIZE = size of receive buffers in the range (48-64K)
|
||||
- TX_CNT = number of transmit buffers in the range (1-128)
|
||||
- TX_SIZE = size of transmit buffers in the range (48-64K)
|
||||
|
||||
1. Transmit and receive buffer size must be a multiple of 4.
|
||||
2. Care should be taken so that the memory required for the
|
||||
transmit and receive buffers is less than or equal to the
|
||||
total adapter packet memory.
|
||||
|
||||
5.2 Turn on ia debug trace
|
||||
|
||||
When the ia driver is built with the CONFIG_ATM_IA_DEBUG flag, the driver
|
||||
can provide more debug trace if needed. There is a bit mask variable,
|
||||
IADebugFlag, which controls the output of the traces. You can find the bit
|
||||
map of the IADebugFlag in iphase.h.
|
||||
The debug trace can be turn on through the insmod command line option, for
|
||||
example, "insmod iphase.o IADebugFlag=0xffffffff" can turn on all the debug
|
||||
traces together with loading the driver.
|
||||
|
||||
6. Ia Driver Test Using ttcp_atm and PVC
|
||||
|
||||
For the PVC setup, the test machines can either be connected back-to-back or
|
||||
through a switch. If connected through the switch, the switch must be
|
||||
configured for the PVC(s).
|
||||
|
||||
a. For UBR test:
|
||||
|
||||
At the test machine intended to receive data, type::
|
||||
|
||||
ttcp_atm -r -a -s 0.100
|
||||
|
||||
At the other test machine, type::
|
||||
|
||||
ttcp_atm -t -a -s 0.100 -n 10000
|
||||
|
||||
Run "ttcp_atm -h" to display more options of the ttcp_atm tool.
|
||||
b. For ABR test:
|
||||
|
||||
It is the same as the UBR testing, but with an extra command option::
|
||||
|
||||
-Pabr:max_pcr=<xxx>
|
||||
|
||||
where:
|
||||
|
||||
xxx = the maximum peak cell rate, from 170 - 353207.
|
||||
|
||||
This option must be set on both the machines.
|
||||
|
||||
c. For CBR test:
|
||||
|
||||
It is the same as the UBR testing, but with an extra command option::
|
||||
|
||||
-Pcbr:max_pcr=<xxx>
|
||||
|
||||
where:
|
||||
|
||||
xxx = the maximum peak cell rate, from 170 - 353207.
|
||||
|
||||
This option may only be set on the transmit machine.
|
||||
|
||||
|
||||
Outstanding Issues
|
||||
==================
|
||||
|
||||
|
||||
|
||||
Contact Information
|
||||
-------------------
|
||||
|
||||
::
|
||||
|
||||
Customer Support:
|
||||
United States: Telephone: (214) 654-5555
|
||||
Fax: (214) 654-5500
|
||||
E-Mail: intouch@iphase.com
|
||||
Europe: Telephone: 33 (0)1 41 15 44 00
|
||||
Fax: 33 (0)1 41 15 12 13
|
||||
World Wide Web: http://www.iphase.com
|
||||
Anonymous FTP: ftp.iphase.com
|
||||
@@ -4151,10 +4151,12 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://linux-atm.sourceforge.net
|
||||
F: drivers/atm/
|
||||
F: drivers/usb/atm/
|
||||
F: include/linux/atm*
|
||||
F: include/linux/sonet.h
|
||||
F: include/uapi/linux/atm*
|
||||
F: include/uapi/linux/sonet.h
|
||||
F: net/atm/
|
||||
|
||||
ATMEL MACB ETHERNET DRIVER
|
||||
M: Nicolas Ferre <nicolas.ferre@microchip.com>
|
||||
|
||||
@@ -52,9 +52,6 @@ CONFIG_IP_NF_MANGLE=m
|
||||
CONFIG_IP_NF_ARPTABLES=m
|
||||
CONFIG_IP_NF_ARPFILTER=m
|
||||
CONFIG_ATM=y
|
||||
CONFIG_ATM_CLIP=y
|
||||
CONFIG_ATM_LANE=m
|
||||
CONFIG_ATM_MPOA=m
|
||||
CONFIG_ATM_BR2684=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
@@ -108,7 +105,6 @@ CONFIG_ATA=y
|
||||
CONFIG_PATA_IXP4XX_CF=y
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=y
|
||||
CONFIG_ATM_TCP=m
|
||||
CONFIG_IXP4XX_ETH=y
|
||||
CONFIG_WAN=y
|
||||
CONFIG_HDLC=y
|
||||
|
||||
@@ -87,9 +87,6 @@ CONFIG_BRIDGE_EBT_LOG=m
|
||||
CONFIG_IP_SCTP=m
|
||||
CONFIG_TIPC=m
|
||||
CONFIG_ATM=y
|
||||
CONFIG_ATM_CLIP=y
|
||||
CONFIG_ATM_LANE=m
|
||||
CONFIG_ATM_MPOA=m
|
||||
CONFIG_ATM_BR2684=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
@@ -104,7 +101,6 @@ CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_HFSC=m
|
||||
CONFIG_NET_SCH_ATM=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_SFQ=m
|
||||
@@ -156,15 +152,6 @@ CONFIG_SCSI_SAS_LIBSAS=m
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_NET_FC=y
|
||||
CONFIG_NETCONSOLE=m
|
||||
CONFIG_ATM_TCP=m
|
||||
CONFIG_ATM_LANAI=m
|
||||
CONFIG_ATM_ENI=m
|
||||
CONFIG_ATM_NICSTAR=m
|
||||
CONFIG_ATM_IDT77252=m
|
||||
CONFIG_ATM_IA=m
|
||||
CONFIG_ATM_FORE200E=m
|
||||
CONFIG_ATM_HE=m
|
||||
CONFIG_ATM_HE_USE_SUNI=y
|
||||
CONFIG_MIPS_AU1X00_ENET=y
|
||||
CONFIG_CICADA_PHY=m
|
||||
CONFIG_DAVICOM_PHY=m
|
||||
|
||||
@@ -133,9 +133,6 @@ CONFIG_BRIDGE_EBT_LOG=m
|
||||
CONFIG_IP_SCTP=m
|
||||
CONFIG_TIPC=m
|
||||
CONFIG_ATM=y
|
||||
CONFIG_ATM_CLIP=y
|
||||
CONFIG_ATM_LANE=m
|
||||
CONFIG_ATM_MPOA=m
|
||||
CONFIG_ATM_BR2684=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
@@ -150,7 +147,6 @@ CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_HFSC=m
|
||||
CONFIG_NET_SCH_ATM=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
CONFIG_NET_SCH_SFQ=m
|
||||
@@ -232,15 +228,6 @@ CONFIG_ARCNET_RIM_I=m
|
||||
CONFIG_ARCNET_COM20020=m
|
||||
CONFIG_ARCNET_COM20020_PCI=m
|
||||
CONFIG_ARCNET_COM20020_CS=m
|
||||
CONFIG_ATM_TCP=m
|
||||
CONFIG_ATM_LANAI=m
|
||||
CONFIG_ATM_ENI=m
|
||||
CONFIG_ATM_NICSTAR=m
|
||||
CONFIG_ATM_IDT77252=m
|
||||
CONFIG_ATM_IA=m
|
||||
CONFIG_ATM_FORE200E=m
|
||||
CONFIG_ATM_HE=m
|
||||
CONFIG_ATM_HE_USE_SUNI=y
|
||||
CONFIG_PCMCIA_3C574=m
|
||||
CONFIG_PCMCIA_3C589=m
|
||||
CONFIG_VORTEX=m
|
||||
|
||||
@@ -227,8 +227,6 @@ CONFIG_BRIDGE_EBT_LOG=m
|
||||
CONFIG_BRIDGE_EBT_NFLOG=m
|
||||
CONFIG_TIPC=m
|
||||
CONFIG_ATM=m
|
||||
CONFIG_ATM_CLIP=m
|
||||
CONFIG_ATM_LANE=m
|
||||
CONFIG_ATM_BR2684=m
|
||||
CONFIG_BRIDGE=m
|
||||
CONFIG_VLAN_8021Q=m
|
||||
@@ -240,7 +238,6 @@ CONFIG_NET_SCHED=y
|
||||
CONFIG_NET_SCH_CBQ=m
|
||||
CONFIG_NET_SCH_HTB=m
|
||||
CONFIG_NET_SCH_HFSC=m
|
||||
CONFIG_NET_SCH_ATM=m
|
||||
CONFIG_NET_SCH_PRIO=m
|
||||
CONFIG_NET_SCH_MULTIQ=m
|
||||
CONFIG_NET_SCH_RED=m
|
||||
@@ -398,12 +395,6 @@ CONFIG_NETCONSOLE=m
|
||||
CONFIG_TUN=m
|
||||
CONFIG_VETH=m
|
||||
CONFIG_VIRTIO_NET=m
|
||||
CONFIG_ATM_TCP=m
|
||||
CONFIG_ATM_LANAI=m
|
||||
CONFIG_ATM_ENI=m
|
||||
CONFIG_ATM_NICSTAR=m
|
||||
CONFIG_ATM_IDT77252=m
|
||||
CONFIG_ATM_HE=m
|
||||
CONFIG_EL3=m
|
||||
CONFIG_PCMCIA_3C574=m
|
||||
CONFIG_PCMCIA_3C589=m
|
||||
|
||||
5
drivers/atm/.gitignore
vendored
5
drivers/atm/.gitignore
vendored
@@ -1,5 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
fore200e_mkfirm
|
||||
fore200e_pca_fw.c
|
||||
pca200e.bin
|
||||
pca200e_ecd.bin2
|
||||
@@ -15,306 +15,6 @@ menuconfig ATM_DRIVERS
|
||||
|
||||
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_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 IDT77105 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_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/device_drivers/atm/iphase.rst>
|
||||
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/device_drivers/atm/fore200e.rst> 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
|
||||
|
||||
@@ -1,32 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Makefile for the Linux network (ATM) device drivers.
|
||||
#
|
||||
|
||||
fore_200e-y := fore200e.o
|
||||
|
||||
obj-$(CONFIG_ATM_NICSTAR) += nicstar.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_LANAI) += lanai.o
|
||||
|
||||
obj-$(CONFIG_ATM_HE) += he.o
|
||||
ifeq ($(CONFIG_ATM_HE_USE_SUNI),y)
|
||||
obj-$(CONFIG_ATM_HE) += suni.o
|
||||
endif
|
||||
|
||||
@@ -1,202 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* 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 <linux/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 const 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 const 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_obj(struct adummy_dev);
|
||||
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");
|
||||
@@ -1,513 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* 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 <linux/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 = 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 = 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_pre_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||
{
|
||||
struct atmtcp_hdr *hdr;
|
||||
|
||||
if (skb->len < sizeof(struct atmtcp_hdr))
|
||||
return -EINVAL;
|
||||
|
||||
hdr = (struct atmtcp_hdr *)skb->data;
|
||||
if (hdr->length == ATMTCP_HDR_MAGIC)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 const 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 const struct atmdev_ops atmtcp_c_dev_ops = {
|
||||
.close = atmtcp_c_close,
|
||||
.pre_send = atmtcp_c_pre_send,
|
||||
.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_obj(*dev_data);
|
||||
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) {
|
||||
atm_dev_put(dev);
|
||||
return 0;
|
||||
}
|
||||
dev_data->persist = 0;
|
||||
if (PRIV(dev)->vcc) {
|
||||
atm_dev_put(dev);
|
||||
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_DESCRIPTION("ATM over TCP");
|
||||
MODULE_LICENSE("GPL");
|
||||
module_init(atmtcp_init);
|
||||
module_exit(atmtcp_exit);
|
||||
2321
drivers/atm/eni.c
2321
drivers/atm/eni.c
File diff suppressed because it is too large
Load Diff
@@ -1,136 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,973 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#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 *);
|
||||
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 {
|
||||
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 */
|
||||
struct device *dev;
|
||||
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 */
|
||||
2861
drivers/atm/he.c
2861
drivers/atm/he.c
File diff suppressed because it is too large
Load Diff
845
drivers/atm/he.h
845
drivers/atm/he.h
@@ -1,845 +0,0 @@
|
||||
/*
|
||||
|
||||
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 dma_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 dma_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_ */
|
||||
@@ -1,376 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* 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 <linux/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(struct timer_list *);
|
||||
static void idt77105_restart_timer_func(struct timer_list *);
|
||||
|
||||
|
||||
static DEFINE_TIMER(stats_timer, idt77105_stats_timer_func);
|
||||
static DEFINE_TIMER(restart_timer, idt77105_restart_timer_func);
|
||||
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(struct timer_list *unused)
|
||||
{
|
||||
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(struct timer_list *unused)
|
||||
{
|
||||
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;
|
||||
fallthrough;
|
||||
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->phy_data = kmalloc_obj(struct idt77105_priv)))
|
||||
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;
|
||||
|
||||
stats_timer.expires = jiffies+IDT77105_STATS_TIMER_PERIOD;
|
||||
add_timer(&stats_timer);
|
||||
|
||||
restart_timer.expires = jiffies+IDT77105_RESTART_TIMER_PERIOD;
|
||||
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->phy_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 */
|
||||
timer_delete_sync(&stats_timer);
|
||||
timer_delete_sync(&restart_timer);
|
||||
}
|
||||
|
||||
module_exit(idt77105_exit);
|
||||
|
||||
MODULE_DESCRIPTION("IDT77105 PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,92 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,816 +0,0 @@
|
||||
/*******************************************************************
|
||||
*
|
||||
* 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 vc_map;
|
||||
|
||||
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 *vc;
|
||||
};
|
||||
|
||||
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 */
|
||||
} __packed;
|
||||
|
||||
#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) */
|
||||
@@ -1,781 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* 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 */
|
||||
};
|
||||
3283
drivers/atm/iphase.c
3283
drivers/atm/iphase.c
File diff suppressed because it is too large
Load Diff
1452
drivers/atm/iphase.h
1452
drivers/atm/iphase.h
File diff suppressed because it is too large
Load Diff
2603
drivers/atm/lanai.c
2603
drivers/atm/lanai.c
File diff suppressed because it is too large
Load Diff
@@ -1,266 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* 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 DAUGHTER_ID 0x0000001f /* daughter 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,759 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* 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_ */
|
||||
@@ -1,244 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* 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
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
/* 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
|
||||
*
|
||||
*
|
||||
*/
|
||||
@@ -1,391 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* 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/slab.h>
|
||||
#include <asm/param.h>
|
||||
#include <linux/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(struct timer_list *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 (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(NULL); /* clear SUNI counters */
|
||||
(void) fetch_stats(dev,NULL,1); /* clear kernel counters */
|
||||
if (first) {
|
||||
timer_setup(&poll_timer, suni_hz, 0);
|
||||
poll_timer.expires = jiffies+HZ;
|
||||
#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) timer_delete_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_obj(struct suni_priv)))
|
||||
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_DESCRIPTION("S/UNI PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,242 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* 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
|
||||
@@ -1,21 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* 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
|
||||
@@ -1,35 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* 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 control 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
|
||||
@@ -1,53 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* net/atm/atmarp.h - RFC1577 ATM ARP */
|
||||
|
||||
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
|
||||
|
||||
|
||||
#ifndef _ATMCLIP_H
|
||||
#define _ATMCLIP_H
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/atmarp.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <net/neighbour.h>
|
||||
|
||||
|
||||
#define CLIP_VCC(vcc) ((struct clip_vcc *) ((vcc)->user_back))
|
||||
|
||||
struct sk_buff;
|
||||
|
||||
struct clip_vcc {
|
||||
struct atm_vcc *vcc; /* VCC descriptor */
|
||||
struct atmarp_entry *entry; /* ATMARP table entry, NULL if IP addr.
|
||||
isn't known yet */
|
||||
int xoff; /* 1 if send buffer is full */
|
||||
unsigned char encap; /* 0: NULL, 1: LLC/SNAP */
|
||||
unsigned long last_use; /* last send or receive operation */
|
||||
unsigned long idle_timeout; /* keep open idle for so many jiffies*/
|
||||
void (*old_push)(struct atm_vcc *vcc,struct sk_buff *skb);
|
||||
/* keep old push fn for chaining */
|
||||
void (*old_pop)(struct atm_vcc *vcc,struct sk_buff *skb);
|
||||
/* keep old pop fn for chaining */
|
||||
struct clip_vcc *next; /* next VCC */
|
||||
};
|
||||
|
||||
|
||||
struct atmarp_entry {
|
||||
struct clip_vcc *vccs; /* active VCCs; NULL if resolution is
|
||||
pending */
|
||||
unsigned long expires; /* entry expiration time */
|
||||
struct neighbour *neigh; /* neighbour back-pointer */
|
||||
};
|
||||
|
||||
#define PRIV(dev) ((struct clip_priv *) netdev_priv(dev))
|
||||
|
||||
struct clip_priv {
|
||||
int number; /* for convenience ... */
|
||||
spinlock_t xoff_lock; /* ensures that pop is atomic (SMP) */
|
||||
struct net_device *next; /* next CLIP interface */
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -19,43 +19,6 @@ config ATM
|
||||
of ATM. See the file <file:Documentation/networking/atm.rst> for
|
||||
further details.
|
||||
|
||||
config ATM_CLIP
|
||||
tristate "Classical IP over ATM"
|
||||
depends on ATM && INET
|
||||
help
|
||||
Classical IP over ATM for PVCs and SVCs, supporting InARP and
|
||||
ATMARP. If you want to communication with other IP hosts on your ATM
|
||||
network, you will typically either say Y here or to "LAN Emulation
|
||||
(LANE)" below.
|
||||
|
||||
config ATM_CLIP_NO_ICMP
|
||||
bool "Do NOT send ICMP if no neighbour"
|
||||
depends on ATM_CLIP
|
||||
help
|
||||
Normally, an "ICMP host unreachable" message is sent if a neighbour
|
||||
cannot be reached because there is no VC to it in the kernel's
|
||||
ATMARP table. This may cause problems when ATMARP table entries are
|
||||
briefly removed during revalidation. If you say Y here, packets to
|
||||
such neighbours are silently discarded instead.
|
||||
|
||||
config ATM_LANE
|
||||
tristate "LAN Emulation (LANE) support"
|
||||
depends on ATM
|
||||
help
|
||||
LAN Emulation emulates services of existing LANs across an ATM
|
||||
network. Besides operating as a normal ATM end station client, Linux
|
||||
LANE client can also act as an proxy client bridging packets between
|
||||
ELAN and Ethernet segments. You need LANE if you want to try MPOA.
|
||||
|
||||
config ATM_MPOA
|
||||
tristate "Multi-Protocol Over ATM (MPOA) support"
|
||||
depends on ATM && INET && ATM_LANE!=n
|
||||
help
|
||||
Multi-Protocol Over ATM allows ATM edge devices such as routers,
|
||||
bridges and ATM attached hosts establish direct ATM VCs across
|
||||
subnetwork boundaries. These shortcut connections bypass routers
|
||||
enhancing overall network performance.
|
||||
|
||||
config ATM_BR2684
|
||||
tristate "RFC1483/2684 Bridged protocols"
|
||||
depends on ATM && INET
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
#
|
||||
|
||||
atm-y := addr.o pvc.o signaling.o svc.o ioctl.o common.o atm_misc.o raw.o resources.o atm_sysfs.o
|
||||
mpoa-objs := mpc.o mpoa_caches.o mpoa_proc.o
|
||||
|
||||
obj-$(CONFIG_ATM) += atm.o
|
||||
obj-$(CONFIG_ATM_CLIP) += clip.o
|
||||
obj-$(CONFIG_ATM_BR2684) += br2684.o
|
||||
atm-$(CONFIG_PROC_FS) += proc.o
|
||||
|
||||
obj-$(CONFIG_ATM_LANE) += lec.o
|
||||
obj-$(CONFIG_ATM_MPOA) += mpoa.o
|
||||
obj-$(CONFIG_PPPOATM) += pppoatm.o
|
||||
|
||||
960
net/atm/clip.c
960
net/atm/clip.c
@@ -1,960 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/* net/atm/clip.c - RFC1577 Classical IP over ATM */
|
||||
|
||||
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h> /* for UINT_MAX */
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/if_arp.h> /* for some manifest constants */
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/atmclip.h>
|
||||
#include <linux/atmarp.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/ip.h> /* for net/route.h */
|
||||
#include <linux/in.h> /* for struct sockaddr_in */
|
||||
#include <linux/if.h> /* for IFF_UP */
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/poison.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/jhash.h>
|
||||
#include <linux/slab.h>
|
||||
#include <net/route.h> /* for struct rtable and routing */
|
||||
#include <net/icmp.h> /* icmp_send */
|
||||
#include <net/arp.h>
|
||||
#include <linux/param.h> /* for HZ */
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/byteorder.h> /* for htons etc. */
|
||||
#include <linux/atomic.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "resources.h"
|
||||
#include <net/atmclip.h>
|
||||
|
||||
static struct net_device *clip_devs;
|
||||
static struct atm_vcc __rcu *atmarpd;
|
||||
static DEFINE_MUTEX(atmarpd_lock);
|
||||
static struct timer_list idle_timer;
|
||||
static const struct neigh_ops clip_neigh_ops;
|
||||
|
||||
static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
|
||||
{
|
||||
struct sock *sk;
|
||||
struct atmarp_ctrl *ctrl;
|
||||
struct atm_vcc *vcc;
|
||||
struct sk_buff *skb;
|
||||
int err = 0;
|
||||
|
||||
pr_debug("(%d)\n", type);
|
||||
|
||||
rcu_read_lock();
|
||||
vcc = rcu_dereference(atmarpd);
|
||||
if (!vcc) {
|
||||
err = -EUNATCH;
|
||||
goto unlock;
|
||||
}
|
||||
skb = alloc_skb(sizeof(struct atmarp_ctrl), GFP_ATOMIC);
|
||||
if (!skb) {
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
ctrl = skb_put(skb, sizeof(struct atmarp_ctrl));
|
||||
ctrl->type = type;
|
||||
ctrl->itf_num = itf;
|
||||
ctrl->ip = ip;
|
||||
atm_force_charge(vcc, skb->truesize);
|
||||
|
||||
sk = sk_atm(vcc);
|
||||
skb_queue_tail(&sk->sk_receive_queue, skb);
|
||||
sk->sk_data_ready(sk);
|
||||
unlock:
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry)
|
||||
{
|
||||
pr_debug("%p to entry %p (neigh %p)\n", clip_vcc, entry, entry->neigh);
|
||||
clip_vcc->entry = entry;
|
||||
clip_vcc->xoff = 0; /* @@@ may overrun buffer by one packet */
|
||||
clip_vcc->next = entry->vccs;
|
||||
entry->vccs = clip_vcc;
|
||||
entry->neigh->used = jiffies;
|
||||
}
|
||||
|
||||
static void unlink_clip_vcc(struct clip_vcc *clip_vcc)
|
||||
{
|
||||
struct atmarp_entry *entry = clip_vcc->entry;
|
||||
struct clip_vcc **walk;
|
||||
|
||||
if (!entry) {
|
||||
pr_err("!clip_vcc->entry (clip_vcc %p)\n", clip_vcc);
|
||||
return;
|
||||
}
|
||||
netif_tx_lock_bh(entry->neigh->dev); /* block clip_start_xmit() */
|
||||
entry->neigh->used = jiffies;
|
||||
for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
|
||||
if (*walk == clip_vcc) {
|
||||
int error;
|
||||
|
||||
*walk = clip_vcc->next; /* atomic */
|
||||
clip_vcc->entry = NULL;
|
||||
if (clip_vcc->xoff)
|
||||
netif_wake_queue(entry->neigh->dev);
|
||||
if (entry->vccs)
|
||||
goto out;
|
||||
entry->expires = jiffies - 1;
|
||||
/* force resolution or expiration */
|
||||
error = neigh_update(entry->neigh, NULL, NUD_NONE,
|
||||
NEIGH_UPDATE_F_ADMIN, 0);
|
||||
if (error)
|
||||
pr_err("neigh_update failed with %d\n", error);
|
||||
goto out;
|
||||
}
|
||||
pr_err("ATMARP: failed (entry %p, vcc 0x%p)\n", entry, clip_vcc);
|
||||
out:
|
||||
netif_tx_unlock_bh(entry->neigh->dev);
|
||||
}
|
||||
|
||||
/* The neighbour entry n->lock is held. */
|
||||
static int neigh_check_cb(struct neighbour *n)
|
||||
{
|
||||
struct atmarp_entry *entry = neighbour_priv(n);
|
||||
struct clip_vcc *cv;
|
||||
|
||||
if (n->ops != &clip_neigh_ops)
|
||||
return 0;
|
||||
for (cv = entry->vccs; cv; cv = cv->next) {
|
||||
unsigned long exp = cv->last_use + cv->idle_timeout;
|
||||
|
||||
if (cv->idle_timeout && time_after(jiffies, exp)) {
|
||||
pr_debug("releasing vcc %p->%p of entry %p\n",
|
||||
cv, cv->vcc, entry);
|
||||
vcc_release_async(cv->vcc, -ETIMEDOUT);
|
||||
}
|
||||
}
|
||||
|
||||
if (entry->vccs || time_before(jiffies, entry->expires))
|
||||
return 0;
|
||||
|
||||
if (refcount_read(&n->refcnt) > 1) {
|
||||
struct sk_buff *skb;
|
||||
|
||||
pr_debug("destruction postponed with ref %d\n",
|
||||
refcount_read(&n->refcnt));
|
||||
|
||||
while ((skb = skb_dequeue(&n->arp_queue)) != NULL)
|
||||
dev_kfree_skb(skb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr_debug("expired neigh %p\n", n);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void idle_timer_check(struct timer_list *unused)
|
||||
{
|
||||
spin_lock(&arp_tbl.lock);
|
||||
__neigh_for_each_release(&arp_tbl, neigh_check_cb);
|
||||
mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
|
||||
spin_unlock(&arp_tbl.lock);
|
||||
}
|
||||
|
||||
static int clip_arp_rcv(struct sk_buff *skb)
|
||||
{
|
||||
struct atm_vcc *vcc;
|
||||
|
||||
pr_debug("\n");
|
||||
vcc = ATM_SKB(skb)->vcc;
|
||||
if (!vcc || !atm_charge(vcc, skb->truesize)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return 0;
|
||||
}
|
||||
pr_debug("pushing to %p\n", vcc);
|
||||
pr_debug("using %p\n", CLIP_VCC(vcc)->old_push);
|
||||
CLIP_VCC(vcc)->old_push(vcc, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const unsigned char llc_oui[] = {
|
||||
0xaa, /* DSAP: non-ISO */
|
||||
0xaa, /* SSAP: non-ISO */
|
||||
0x03, /* Ctrl: Unnumbered Information Command PDU */
|
||||
0x00, /* OUI: EtherType */
|
||||
0x00,
|
||||
0x00
|
||||
};
|
||||
|
||||
static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||
{
|
||||
struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
|
||||
|
||||
pr_debug("\n");
|
||||
|
||||
if (!skb) {
|
||||
pr_debug("removing VCC %p\n", clip_vcc);
|
||||
if (clip_vcc->entry)
|
||||
unlink_clip_vcc(clip_vcc);
|
||||
clip_vcc->old_push(vcc, NULL); /* pass on the bad news */
|
||||
kfree(clip_vcc);
|
||||
return;
|
||||
}
|
||||
atm_return(vcc, skb->truesize);
|
||||
if (!clip_devs) {
|
||||
kfree_skb(skb);
|
||||
return;
|
||||
}
|
||||
|
||||
skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs;
|
||||
/* clip_vcc->entry == NULL if we don't have an IP address yet */
|
||||
if (!skb->dev) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return;
|
||||
}
|
||||
ATM_SKB(skb)->vcc = vcc;
|
||||
skb_reset_mac_header(skb);
|
||||
if (!clip_vcc->encap ||
|
||||
skb->len < RFC1483LLC_LEN ||
|
||||
memcmp(skb->data, llc_oui, sizeof(llc_oui)))
|
||||
skb->protocol = htons(ETH_P_IP);
|
||||
else {
|
||||
skb->protocol = ((__be16 *)skb->data)[3];
|
||||
skb_pull(skb, RFC1483LLC_LEN);
|
||||
if (skb->protocol == htons(ETH_P_ARP)) {
|
||||
skb->dev->stats.rx_packets++;
|
||||
skb->dev->stats.rx_bytes += skb->len;
|
||||
clip_arp_rcv(skb);
|
||||
return;
|
||||
}
|
||||
}
|
||||
clip_vcc->last_use = jiffies;
|
||||
skb->dev->stats.rx_packets++;
|
||||
skb->dev->stats.rx_bytes += skb->len;
|
||||
memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
|
||||
netif_rx(skb);
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
|
||||
* clip_pop is atomic with respect to the critical section in clip_start_xmit.
|
||||
*/
|
||||
|
||||
static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||
{
|
||||
struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
|
||||
struct net_device *dev = skb->dev;
|
||||
int old;
|
||||
unsigned long flags;
|
||||
|
||||
pr_debug("(vcc %p)\n", vcc);
|
||||
clip_vcc->old_pop(vcc, skb);
|
||||
/* skb->dev == NULL in outbound ARP packets */
|
||||
if (!dev)
|
||||
return;
|
||||
spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags);
|
||||
if (atm_may_send(vcc, 0)) {
|
||||
old = xchg(&clip_vcc->xoff, 0);
|
||||
if (old)
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
|
||||
}
|
||||
|
||||
static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
|
||||
{
|
||||
__be32 *ip = (__be32 *) neigh->primary_key;
|
||||
|
||||
pr_debug("(neigh %p, skb %p)\n", neigh, skb);
|
||||
to_atmarpd(act_need, PRIV(neigh->dev)->number, *ip);
|
||||
}
|
||||
|
||||
static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb)
|
||||
{
|
||||
#ifndef CONFIG_ATM_CLIP_NO_ICMP
|
||||
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
||||
#endif
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static const struct neigh_ops clip_neigh_ops = {
|
||||
.family = AF_INET,
|
||||
.solicit = clip_neigh_solicit,
|
||||
.error_report = clip_neigh_error,
|
||||
.output = neigh_direct_output,
|
||||
.connected_output = neigh_direct_output,
|
||||
};
|
||||
|
||||
static int clip_constructor(struct net_device *dev, struct neighbour *neigh)
|
||||
{
|
||||
struct atmarp_entry *entry = neighbour_priv(neigh);
|
||||
|
||||
if (neigh->tbl->family != AF_INET)
|
||||
return -EINVAL;
|
||||
|
||||
if (neigh->type != RTN_UNICAST)
|
||||
return -EINVAL;
|
||||
|
||||
neigh->nud_state = NUD_NONE;
|
||||
neigh->ops = &clip_neigh_ops;
|
||||
neigh->output = neigh->ops->output;
|
||||
entry->neigh = neigh;
|
||||
entry->vccs = NULL;
|
||||
entry->expires = jiffies - 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */
|
||||
|
||||
/*
|
||||
* We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
|
||||
* to allocate the neighbour entry but not to ask atmarpd for resolution. Also,
|
||||
* don't increment the usage count. This is used to create entries in
|
||||
* clip_setentry.
|
||||
*/
|
||||
|
||||
static int clip_encap(struct atm_vcc *vcc, int mode)
|
||||
{
|
||||
if (!CLIP_VCC(vcc))
|
||||
return -EBADFD;
|
||||
|
||||
CLIP_VCC(vcc)->encap = mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
struct clip_priv *clip_priv = PRIV(dev);
|
||||
struct dst_entry *dst = skb_dst(skb);
|
||||
struct atmarp_entry *entry;
|
||||
struct neighbour *n;
|
||||
struct atm_vcc *vcc;
|
||||
struct rtable *rt;
|
||||
__be32 *daddr;
|
||||
int old;
|
||||
unsigned long flags;
|
||||
|
||||
pr_debug("(skb %p)\n", skb);
|
||||
if (!dst) {
|
||||
pr_err("skb_dst(skb) == NULL\n");
|
||||
dev_kfree_skb(skb);
|
||||
dev->stats.tx_dropped++;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
rt = dst_rtable(dst);
|
||||
if (rt->rt_gw_family == AF_INET)
|
||||
daddr = &rt->rt_gw4;
|
||||
else
|
||||
daddr = &ip_hdr(skb)->daddr;
|
||||
n = dst_neigh_lookup(dst, daddr);
|
||||
if (!n) {
|
||||
pr_err("NO NEIGHBOUR !\n");
|
||||
dev_kfree_skb(skb);
|
||||
dev->stats.tx_dropped++;
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
entry = neighbour_priv(n);
|
||||
if (!entry->vccs) {
|
||||
if (time_after(jiffies, entry->expires)) {
|
||||
/* should be resolved */
|
||||
entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ;
|
||||
to_atmarpd(act_need, PRIV(dev)->number, *((__be32 *)n->primary_key));
|
||||
}
|
||||
if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS)
|
||||
skb_queue_tail(&entry->neigh->arp_queue, skb);
|
||||
else {
|
||||
dev_kfree_skb(skb);
|
||||
dev->stats.tx_dropped++;
|
||||
}
|
||||
goto out_release_neigh;
|
||||
}
|
||||
pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
|
||||
ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
|
||||
pr_debug("using neighbour %p, vcc %p\n", n, vcc);
|
||||
if (entry->vccs->encap) {
|
||||
void *here;
|
||||
|
||||
here = skb_push(skb, RFC1483LLC_LEN);
|
||||
memcpy(here, llc_oui, sizeof(llc_oui));
|
||||
((__be16 *) here)[3] = skb->protocol;
|
||||
}
|
||||
atm_account_tx(vcc, skb);
|
||||
entry->vccs->last_use = jiffies;
|
||||
pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev);
|
||||
old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */
|
||||
if (old) {
|
||||
pr_warn("XOFF->XOFF transition\n");
|
||||
goto out_release_neigh;
|
||||
}
|
||||
dev->stats.tx_packets++;
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
vcc->send(vcc, skb);
|
||||
if (atm_may_send(vcc, 0)) {
|
||||
entry->vccs->xoff = 0;
|
||||
goto out_release_neigh;
|
||||
}
|
||||
spin_lock_irqsave(&clip_priv->xoff_lock, flags);
|
||||
netif_stop_queue(dev); /* XOFF -> throttle immediately */
|
||||
barrier();
|
||||
if (!entry->vccs->xoff)
|
||||
netif_start_queue(dev);
|
||||
/* Oh, we just raced with clip_pop. netif_start_queue should be
|
||||
good enough, because nothing should really be asleep because
|
||||
of the brief netif_stop_queue. If this isn't true or if it
|
||||
changes, use netif_wake_queue instead. */
|
||||
spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
|
||||
out_release_neigh:
|
||||
neigh_release(n);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static int clip_mkip(struct atm_vcc *vcc, int timeout)
|
||||
{
|
||||
struct clip_vcc *clip_vcc;
|
||||
|
||||
if (!vcc->push)
|
||||
return -EBADFD;
|
||||
if (vcc->user_back)
|
||||
return -EINVAL;
|
||||
clip_vcc = kmalloc_obj(struct clip_vcc);
|
||||
if (!clip_vcc)
|
||||
return -ENOMEM;
|
||||
pr_debug("%p vcc %p\n", clip_vcc, vcc);
|
||||
clip_vcc->vcc = vcc;
|
||||
vcc->user_back = clip_vcc;
|
||||
set_bit(ATM_VF_IS_CLIP, &vcc->flags);
|
||||
clip_vcc->entry = NULL;
|
||||
clip_vcc->xoff = 0;
|
||||
clip_vcc->encap = 1;
|
||||
clip_vcc->last_use = jiffies;
|
||||
clip_vcc->idle_timeout = timeout * HZ;
|
||||
clip_vcc->old_push = vcc->push;
|
||||
clip_vcc->old_pop = vcc->pop;
|
||||
vcc->push = clip_push;
|
||||
vcc->pop = clip_pop;
|
||||
|
||||
/* re-process everything received between connection setup and MKIP */
|
||||
vcc_process_recv_queue(vcc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
|
||||
{
|
||||
struct neighbour *neigh;
|
||||
struct atmarp_entry *entry;
|
||||
int error;
|
||||
struct clip_vcc *clip_vcc;
|
||||
struct rtable *rt;
|
||||
|
||||
if (vcc->push != clip_push) {
|
||||
pr_warn("non-CLIP VCC\n");
|
||||
return -EBADF;
|
||||
}
|
||||
clip_vcc = CLIP_VCC(vcc);
|
||||
if (!ip) {
|
||||
if (!clip_vcc->entry) {
|
||||
pr_err("hiding hidden ATMARP entry\n");
|
||||
return 0;
|
||||
}
|
||||
pr_debug("remove\n");
|
||||
unlink_clip_vcc(clip_vcc);
|
||||
return 0;
|
||||
}
|
||||
rt = ip_route_output(&init_net, ip, 0, 0, 0, RT_SCOPE_LINK);
|
||||
if (IS_ERR(rt))
|
||||
return PTR_ERR(rt);
|
||||
neigh = __neigh_lookup(&arp_tbl, &ip, rt->dst.dev, 1);
|
||||
ip_rt_put(rt);
|
||||
if (!neigh)
|
||||
return -ENOMEM;
|
||||
entry = neighbour_priv(neigh);
|
||||
if (entry != clip_vcc->entry) {
|
||||
if (!clip_vcc->entry)
|
||||
pr_debug("add\n");
|
||||
else {
|
||||
pr_debug("update\n");
|
||||
unlink_clip_vcc(clip_vcc);
|
||||
}
|
||||
link_vcc(clip_vcc, entry);
|
||||
}
|
||||
error = neigh_update(neigh, llc_oui, NUD_PERMANENT,
|
||||
NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN, 0);
|
||||
neigh_release(neigh);
|
||||
return error;
|
||||
}
|
||||
|
||||
static const struct net_device_ops clip_netdev_ops = {
|
||||
.ndo_start_xmit = clip_start_xmit,
|
||||
.ndo_neigh_construct = clip_constructor,
|
||||
};
|
||||
|
||||
static void clip_setup(struct net_device *dev)
|
||||
{
|
||||
dev->netdev_ops = &clip_netdev_ops;
|
||||
dev->type = ARPHRD_ATM;
|
||||
dev->neigh_priv_len = sizeof(struct atmarp_entry);
|
||||
dev->hard_header_len = RFC1483LLC_LEN;
|
||||
dev->mtu = RFC1626_MTU;
|
||||
dev->tx_queue_len = 100; /* "normal" queue (packets) */
|
||||
/* When using a "real" qdisc, the qdisc determines the queue */
|
||||
/* length. tx_queue_len is only used for the default case, */
|
||||
/* without any more elaborate queuing. 100 is a reasonable */
|
||||
/* compromise between decent burst-tolerance and protection */
|
||||
/* against memory hogs. */
|
||||
netif_keep_dst(dev);
|
||||
}
|
||||
|
||||
static int clip_create(int number)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct clip_priv *clip_priv;
|
||||
int error;
|
||||
|
||||
if (number != -1) {
|
||||
for (dev = clip_devs; dev; dev = PRIV(dev)->next)
|
||||
if (PRIV(dev)->number == number)
|
||||
return -EEXIST;
|
||||
} else {
|
||||
number = 0;
|
||||
for (dev = clip_devs; dev; dev = PRIV(dev)->next)
|
||||
if (PRIV(dev)->number >= number)
|
||||
number = PRIV(dev)->number + 1;
|
||||
}
|
||||
dev = alloc_netdev(sizeof(struct clip_priv), "", NET_NAME_UNKNOWN,
|
||||
clip_setup);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
clip_priv = PRIV(dev);
|
||||
sprintf(dev->name, "atm%d", number);
|
||||
spin_lock_init(&clip_priv->xoff_lock);
|
||||
clip_priv->number = number;
|
||||
error = register_netdev(dev);
|
||||
if (error) {
|
||||
free_netdev(dev);
|
||||
return error;
|
||||
}
|
||||
clip_priv->next = clip_devs;
|
||||
clip_devs = dev;
|
||||
pr_debug("registered (net:%s)\n", dev->name);
|
||||
return number;
|
||||
}
|
||||
|
||||
static int clip_device_event(struct notifier_block *this, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
|
||||
if (!net_eq(dev_net(dev), &init_net))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (event == NETDEV_UNREGISTER)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
/* ignore non-CLIP devices */
|
||||
if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_UP:
|
||||
pr_debug("NETDEV_UP\n");
|
||||
to_atmarpd(act_up, PRIV(dev)->number, 0);
|
||||
break;
|
||||
case NETDEV_GOING_DOWN:
|
||||
pr_debug("NETDEV_DOWN\n");
|
||||
to_atmarpd(act_down, PRIV(dev)->number, 0);
|
||||
break;
|
||||
case NETDEV_CHANGE:
|
||||
case NETDEV_CHANGEMTU:
|
||||
pr_debug("NETDEV_CHANGE*\n");
|
||||
to_atmarpd(act_change, PRIV(dev)->number, 0);
|
||||
break;
|
||||
}
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int clip_inet_event(struct notifier_block *this, unsigned long event,
|
||||
void *ifa)
|
||||
{
|
||||
struct in_device *in_dev;
|
||||
struct netdev_notifier_info info;
|
||||
|
||||
in_dev = ((struct in_ifaddr *)ifa)->ifa_dev;
|
||||
/*
|
||||
* Transitions are of the down-change-up type, so it's sufficient to
|
||||
* handle the change on up.
|
||||
*/
|
||||
if (event != NETDEV_UP)
|
||||
return NOTIFY_DONE;
|
||||
netdev_notifier_info_init(&info, in_dev->dev);
|
||||
return clip_device_event(this, NETDEV_CHANGE, &info);
|
||||
}
|
||||
|
||||
static struct notifier_block clip_dev_notifier = {
|
||||
.notifier_call = clip_device_event,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct notifier_block clip_inet_notifier = {
|
||||
.notifier_call = clip_inet_event,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static void atmarpd_close(struct atm_vcc *vcc)
|
||||
{
|
||||
pr_debug("\n");
|
||||
|
||||
mutex_lock(&atmarpd_lock);
|
||||
RCU_INIT_POINTER(atmarpd, NULL);
|
||||
mutex_unlock(&atmarpd_lock);
|
||||
|
||||
synchronize_rcu();
|
||||
skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
|
||||
|
||||
pr_debug("(done)\n");
|
||||
module_put(THIS_MODULE);
|
||||
}
|
||||
|
||||
static int atmarpd_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||
{
|
||||
atm_return_tx(vcc, skb);
|
||||
dev_kfree_skb_any(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct atmdev_ops atmarpd_dev_ops = {
|
||||
.close = atmarpd_close,
|
||||
.send = atmarpd_send
|
||||
};
|
||||
|
||||
|
||||
static struct atm_dev atmarpd_dev = {
|
||||
.ops = &atmarpd_dev_ops,
|
||||
.type = "arpd",
|
||||
.number = 999,
|
||||
.lock = __SPIN_LOCK_UNLOCKED(atmarpd_dev.lock)
|
||||
};
|
||||
|
||||
|
||||
static int atm_init_atmarp(struct atm_vcc *vcc)
|
||||
{
|
||||
if (vcc->push == clip_push)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&atmarpd_lock);
|
||||
if (atmarpd) {
|
||||
mutex_unlock(&atmarpd_lock);
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
|
||||
mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
|
||||
|
||||
rcu_assign_pointer(atmarpd, vcc);
|
||||
set_bit(ATM_VF_META, &vcc->flags);
|
||||
set_bit(ATM_VF_READY, &vcc->flags);
|
||||
/* allow replies and avoid getting closed if signaling dies */
|
||||
vcc->dev = &atmarpd_dev;
|
||||
vcc_insert_socket(sk_atm(vcc));
|
||||
vcc->push = NULL;
|
||||
vcc->pop = NULL; /* crash */
|
||||
vcc->push_oam = NULL; /* crash */
|
||||
mutex_unlock(&atmarpd_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct atm_vcc *vcc = ATM_SD(sock);
|
||||
struct sock *sk = sock->sk;
|
||||
int err = 0;
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCMKCLIP:
|
||||
case ATMARPD_CTRL:
|
||||
case ATMARP_MKIP:
|
||||
case ATMARP_SETENTRY:
|
||||
case ATMARP_ENCAP:
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
break;
|
||||
default:
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCMKCLIP:
|
||||
err = clip_create(arg);
|
||||
break;
|
||||
case ATMARPD_CTRL:
|
||||
lock_sock(sk);
|
||||
err = atm_init_atmarp(vcc);
|
||||
if (!err) {
|
||||
sock->state = SS_CONNECTED;
|
||||
__module_get(THIS_MODULE);
|
||||
}
|
||||
release_sock(sk);
|
||||
break;
|
||||
case ATMARP_MKIP:
|
||||
lock_sock(sk);
|
||||
err = clip_mkip(vcc, arg);
|
||||
release_sock(sk);
|
||||
break;
|
||||
case ATMARP_SETENTRY:
|
||||
err = clip_setentry(vcc, (__force __be32)arg);
|
||||
break;
|
||||
case ATMARP_ENCAP:
|
||||
err = clip_encap(vcc, arg);
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct atm_ioctl clip_ioctl_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.ioctl = clip_ioctl,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
||||
static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
|
||||
{
|
||||
static int code[] = { 1, 2, 10, 6, 1, 0 };
|
||||
static int e164[] = { 1, 8, 4, 6, 1, 0 };
|
||||
|
||||
if (*addr->sas_addr.pub) {
|
||||
seq_printf(seq, "%s", addr->sas_addr.pub);
|
||||
if (*addr->sas_addr.prv)
|
||||
seq_putc(seq, '+');
|
||||
} else if (!*addr->sas_addr.prv) {
|
||||
seq_printf(seq, "%s", "(none)");
|
||||
return;
|
||||
}
|
||||
if (*addr->sas_addr.prv) {
|
||||
unsigned char *prv = addr->sas_addr.prv;
|
||||
int *fields;
|
||||
int i, j;
|
||||
|
||||
fields = *prv == ATM_AFI_E164 ? e164 : code;
|
||||
for (i = 0; fields[i]; i++) {
|
||||
for (j = fields[i]; j; j--)
|
||||
seq_printf(seq, "%02X", *prv++);
|
||||
if (fields[i + 1])
|
||||
seq_putc(seq, '.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This means the neighbour entry has no attached VCC objects. */
|
||||
#define SEQ_NO_VCC_TOKEN ((void *) 2)
|
||||
|
||||
static void atmarp_info(struct seq_file *seq, struct neighbour *n,
|
||||
struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
|
||||
{
|
||||
struct net_device *dev = n->dev;
|
||||
unsigned long exp;
|
||||
char buf[17];
|
||||
int svc, llc, off;
|
||||
|
||||
svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
|
||||
(sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC));
|
||||
|
||||
llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap);
|
||||
|
||||
if (clip_vcc == SEQ_NO_VCC_TOKEN)
|
||||
exp = entry->neigh->used;
|
||||
else
|
||||
exp = clip_vcc->last_use;
|
||||
|
||||
exp = (jiffies - exp) / HZ;
|
||||
|
||||
seq_printf(seq, "%-6s%-4s%-4s%5ld ",
|
||||
dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp);
|
||||
|
||||
off = scnprintf(buf, sizeof(buf) - 1, "%pI4", n->primary_key);
|
||||
while (off < 16)
|
||||
buf[off++] = ' ';
|
||||
buf[off] = '\0';
|
||||
seq_printf(seq, "%s", buf);
|
||||
|
||||
if (clip_vcc == SEQ_NO_VCC_TOKEN) {
|
||||
if (time_before(jiffies, entry->expires))
|
||||
seq_printf(seq, "(resolving)\n");
|
||||
else
|
||||
seq_printf(seq, "(expired, ref %d)\n",
|
||||
refcount_read(&entry->neigh->refcnt));
|
||||
} else if (!svc) {
|
||||
seq_printf(seq, "%d.%d.%d\n",
|
||||
clip_vcc->vcc->dev->number,
|
||||
clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
|
||||
} else {
|
||||
svc_addr(seq, &clip_vcc->vcc->remote);
|
||||
seq_putc(seq, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
struct clip_seq_state {
|
||||
/* This member must be first. */
|
||||
struct neigh_seq_state ns;
|
||||
|
||||
/* Local to clip specific iteration. */
|
||||
struct clip_vcc *vcc;
|
||||
};
|
||||
|
||||
static struct clip_vcc *clip_seq_next_vcc(struct atmarp_entry *e,
|
||||
struct clip_vcc *curr)
|
||||
{
|
||||
if (!curr) {
|
||||
curr = e->vccs;
|
||||
if (!curr)
|
||||
return SEQ_NO_VCC_TOKEN;
|
||||
return curr;
|
||||
}
|
||||
if (curr == SEQ_NO_VCC_TOKEN)
|
||||
return NULL;
|
||||
|
||||
curr = curr->next;
|
||||
|
||||
return curr;
|
||||
}
|
||||
|
||||
static void *clip_seq_vcc_walk(struct clip_seq_state *state,
|
||||
struct atmarp_entry *e, loff_t * pos)
|
||||
{
|
||||
struct clip_vcc *vcc = state->vcc;
|
||||
|
||||
vcc = clip_seq_next_vcc(e, vcc);
|
||||
if (vcc && pos != NULL) {
|
||||
while (*pos) {
|
||||
vcc = clip_seq_next_vcc(e, vcc);
|
||||
if (!vcc)
|
||||
break;
|
||||
--(*pos);
|
||||
}
|
||||
}
|
||||
state->vcc = vcc;
|
||||
|
||||
return vcc;
|
||||
}
|
||||
|
||||
static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
|
||||
struct neighbour *n, loff_t * pos)
|
||||
{
|
||||
struct clip_seq_state *state = (struct clip_seq_state *)_state;
|
||||
|
||||
if (n->dev->type != ARPHRD_ATM)
|
||||
return NULL;
|
||||
|
||||
return clip_seq_vcc_walk(state, neighbour_priv(n), pos);
|
||||
}
|
||||
|
||||
static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
|
||||
{
|
||||
struct clip_seq_state *state = seq->private;
|
||||
state->ns.neigh_sub_iter = clip_seq_sub_iter;
|
||||
return neigh_seq_start(seq, pos, &arp_tbl, NEIGH_SEQ_NEIGH_ONLY);
|
||||
}
|
||||
|
||||
static int clip_seq_show(struct seq_file *seq, void *v)
|
||||
{
|
||||
static char atm_arp_banner[] =
|
||||
"IPitf TypeEncp Idle IP address ATM address\n";
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
seq_puts(seq, atm_arp_banner);
|
||||
} else {
|
||||
struct clip_seq_state *state = seq->private;
|
||||
struct clip_vcc *vcc = state->vcc;
|
||||
struct neighbour *n = v;
|
||||
|
||||
atmarp_info(seq, n, neighbour_priv(n), vcc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations arp_seq_ops = {
|
||||
.start = clip_seq_start,
|
||||
.next = neigh_seq_next,
|
||||
.stop = neigh_seq_stop,
|
||||
.show = clip_seq_show,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void atm_clip_exit_noproc(void);
|
||||
|
||||
static int __init atm_clip_init(void)
|
||||
{
|
||||
register_atm_ioctl(&clip_ioctl_ops);
|
||||
register_netdevice_notifier(&clip_dev_notifier);
|
||||
register_inetaddr_notifier(&clip_inet_notifier);
|
||||
|
||||
timer_setup(&idle_timer, idle_timer_check, 0);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
p = proc_create_net("arp", 0444, atm_proc_root, &arp_seq_ops,
|
||||
sizeof(struct clip_seq_state));
|
||||
if (!p) {
|
||||
pr_err("Unable to initialize /proc/net/atm/arp\n");
|
||||
atm_clip_exit_noproc();
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void atm_clip_exit_noproc(void)
|
||||
{
|
||||
struct net_device *dev, *next;
|
||||
|
||||
unregister_inetaddr_notifier(&clip_inet_notifier);
|
||||
unregister_netdevice_notifier(&clip_dev_notifier);
|
||||
|
||||
deregister_atm_ioctl(&clip_ioctl_ops);
|
||||
|
||||
/* First, stop the idle timer, so it stops banging
|
||||
* on the table.
|
||||
*/
|
||||
timer_delete_sync(&idle_timer);
|
||||
|
||||
dev = clip_devs;
|
||||
while (dev) {
|
||||
next = PRIV(dev)->next;
|
||||
unregister_netdev(dev);
|
||||
free_netdev(dev);
|
||||
dev = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void __exit atm_clip_exit(void)
|
||||
{
|
||||
remove_proc_entry("arp", atm_proc_root);
|
||||
|
||||
atm_clip_exit_noproc();
|
||||
}
|
||||
|
||||
module_init(atm_clip_init);
|
||||
module_exit(atm_clip_exit);
|
||||
MODULE_AUTHOR("Werner Almesberger");
|
||||
MODULE_DESCRIPTION("Classical/IP over ATM interface");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -11,14 +11,10 @@
|
||||
#include <linux/net.h> /* struct socket, struct proto_ops */
|
||||
#include <linux/atm.h> /* ATM stuff */
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/atmclip.h> /* CLIP_*ENCAP */
|
||||
#include <linux/atmarp.h> /* manifest constants */
|
||||
#include <linux/capability.h>
|
||||
#include <linux/sonet.h> /* for ioctls */
|
||||
#include <linux/atmsvc.h>
|
||||
#include <linux/atmmpc.h>
|
||||
#include <net/atmclip.h>
|
||||
#include <linux/atmlec.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <asm/ioctls.h>
|
||||
#include <net/compat.h>
|
||||
@@ -138,16 +134,6 @@ static int do_vcc_ioctl(struct socket *sock, unsigned int cmd,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ATMMPC_CTRL:
|
||||
case ATMMPC_DATA:
|
||||
request_module("mpoa");
|
||||
break;
|
||||
case ATMARPD_CTRL:
|
||||
request_module("clip");
|
||||
break;
|
||||
case ATMLEC_CTRL:
|
||||
request_module("lec");
|
||||
break;
|
||||
}
|
||||
|
||||
error = -ENOIOCTLCMD;
|
||||
|
||||
2274
net/atm/lec.c
2274
net/atm/lec.c
File diff suppressed because it is too large
Load Diff
155
net/atm/lec.h
155
net/atm/lec.h
@@ -1,155 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Lan Emulation client header file
|
||||
*
|
||||
* Marko Kiiskila <mkiiskila@yahoo.com>
|
||||
*/
|
||||
|
||||
#ifndef _LEC_H_
|
||||
#define _LEC_H_
|
||||
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/atmlec.h>
|
||||
|
||||
#define LEC_HEADER_LEN 16
|
||||
|
||||
struct lecdatahdr_8023 {
|
||||
__be16 le_header;
|
||||
unsigned char h_dest[ETH_ALEN];
|
||||
unsigned char h_source[ETH_ALEN];
|
||||
__be16 h_type;
|
||||
};
|
||||
|
||||
struct lecdatahdr_8025 {
|
||||
__be16 le_header;
|
||||
unsigned char ac_pad;
|
||||
unsigned char fc;
|
||||
unsigned char h_dest[ETH_ALEN];
|
||||
unsigned char h_source[ETH_ALEN];
|
||||
};
|
||||
|
||||
#define LEC_MINIMUM_8023_SIZE 62
|
||||
#define LEC_MINIMUM_8025_SIZE 16
|
||||
|
||||
/*
|
||||
* Operations that LANE2 capable device can do. Two first functions
|
||||
* are used to make the device do things. See spec 3.1.3 and 3.1.4.
|
||||
*
|
||||
* The third function is intended for the MPOA component sitting on
|
||||
* top of the LANE device. The MPOA component assigns it's own function
|
||||
* to (*associate_indicator)() and the LANE device will use that
|
||||
* function to tell about TLVs it sees floating through.
|
||||
*
|
||||
*/
|
||||
struct lane2_ops {
|
||||
int (*resolve) (struct net_device *dev, const u8 *dst_mac, int force,
|
||||
u8 **tlvs, u32 *sizeoftlvs);
|
||||
int (*associate_req) (struct net_device *dev, const u8 *lan_dst,
|
||||
const u8 *tlvs, u32 sizeoftlvs);
|
||||
void (*associate_indicator) (struct net_device *dev, const u8 *mac_addr,
|
||||
const u8 *tlvs, u32 sizeoftlvs);
|
||||
};
|
||||
|
||||
/*
|
||||
* ATM LAN Emulation supports both LLC & Dix Ethernet EtherType
|
||||
* frames.
|
||||
*
|
||||
* 1. Dix Ethernet EtherType frames encoded by placing EtherType
|
||||
* field in h_type field. Data follows immediately after header.
|
||||
* 2. LLC Data frames whose total length, including LLC field and data,
|
||||
* but not padding required to meet the minimum data frame length,
|
||||
* is less than ETH_P_802_3_MIN MUST be encoded by placing that length
|
||||
* in the h_type field. The LLC field follows header immediately.
|
||||
* 3. LLC data frames longer than this maximum MUST be encoded by placing
|
||||
* the value 0 in the h_type field.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Hash table size */
|
||||
#define LEC_ARP_TABLE_SIZE 16
|
||||
|
||||
struct lec_priv {
|
||||
unsigned short lecid; /* Lecid of this client */
|
||||
struct hlist_head lec_arp_empty_ones;
|
||||
/* Used for storing VCC's that don't have a MAC address attached yet */
|
||||
struct hlist_head lec_arp_tables[LEC_ARP_TABLE_SIZE];
|
||||
/* Actual LE ARP table */
|
||||
struct hlist_head lec_no_forward;
|
||||
/*
|
||||
* Used for storing VCC's (and forward packets from) which are to
|
||||
* age out by not using them to forward packets.
|
||||
* This is because to some LE clients there will be 2 VCCs. Only
|
||||
* one of them gets used.
|
||||
*/
|
||||
struct hlist_head mcast_fwds;
|
||||
/*
|
||||
* With LANEv2 it is possible that BUS (or a special multicast server)
|
||||
* establishes multiple Multicast Forward VCCs to us. This list
|
||||
* collects all those VCCs. LANEv1 client has only one item in this
|
||||
* list. These entries are not aged out.
|
||||
*/
|
||||
spinlock_t lec_arp_lock;
|
||||
struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */
|
||||
struct atm_vcc __rcu *lecd;
|
||||
struct delayed_work lec_arp_work; /* C10 */
|
||||
unsigned int maximum_unknown_frame_count;
|
||||
/*
|
||||
* Within the period of time defined by this variable, the client will send
|
||||
* no more than C10 frames to BUS for a given unicast destination. (C11)
|
||||
*/
|
||||
unsigned long max_unknown_frame_time;
|
||||
/*
|
||||
* If no traffic has been sent in this vcc for this period of time,
|
||||
* vcc will be torn down (C12)
|
||||
*/
|
||||
unsigned long vcc_timeout_period;
|
||||
/*
|
||||
* An LE Client MUST not retry an LE_ARP_REQUEST for a
|
||||
* given frame's LAN Destination more than maximum retry count times,
|
||||
* after the first LEC_ARP_REQUEST (C13)
|
||||
*/
|
||||
unsigned short max_retry_count;
|
||||
/*
|
||||
* Max time the client will maintain an entry in its arp cache in
|
||||
* absence of a verification of that relationship (C17)
|
||||
*/
|
||||
unsigned long aging_time;
|
||||
/*
|
||||
* Max time the client will maintain an entry in cache when
|
||||
* topology change flag is true (C18)
|
||||
*/
|
||||
unsigned long forward_delay_time; /* Topology change flag (C19) */
|
||||
int topology_change;
|
||||
/*
|
||||
* Max time the client expects an LE_ARP_REQUEST/LE_ARP_RESPONSE
|
||||
* cycle to take (C20)
|
||||
*/
|
||||
unsigned long arp_response_time;
|
||||
/*
|
||||
* Time limit ot wait to receive an LE_FLUSH_RESPONSE after the
|
||||
* LE_FLUSH_REQUEST has been sent before taking recover action. (C21)
|
||||
*/
|
||||
unsigned long flush_timeout;
|
||||
/* The time since sending a frame to the bus after which the
|
||||
* LE Client may assume that the frame has been either discarded or
|
||||
* delivered to the recipient (C22)
|
||||
*/
|
||||
unsigned long path_switching_delay;
|
||||
|
||||
u8 *tlvs; /* LANE2: TLVs are new */
|
||||
u32 sizeoftlvs; /* The size of the tlv array in bytes */
|
||||
int lane_version; /* LANE2 */
|
||||
int itfnum; /* e.g. 2 for lec2, 5 for lec5 */
|
||||
struct lane2_ops *lane2_ops; /* can be NULL for LANE v1 */
|
||||
int is_proxy; /* bridge between ATM and Ethernet */
|
||||
};
|
||||
|
||||
struct lec_vcc_priv {
|
||||
void (*old_pop) (struct atm_vcc *vcc, struct sk_buff *skb);
|
||||
int xoff;
|
||||
};
|
||||
|
||||
#define LEC_VCC_PRIV(vcc) ((struct lec_vcc_priv *)((vcc)->user_back))
|
||||
|
||||
#endif /* _LEC_H_ */
|
||||
@@ -1,97 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Lec arp cache
|
||||
*
|
||||
* Marko Kiiskila <mkiiskila@yahoo.com>
|
||||
*/
|
||||
#ifndef _LEC_ARP_H_
|
||||
#define _LEC_ARP_H_
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/atmlec.h>
|
||||
|
||||
struct lec_arp_table {
|
||||
struct hlist_node next; /* Linked entry list */
|
||||
unsigned char atm_addr[ATM_ESA_LEN]; /* Atm address */
|
||||
unsigned char mac_addr[ETH_ALEN]; /* Mac address */
|
||||
int is_rdesc; /* Mac address is a route descriptor */
|
||||
struct atm_vcc *vcc; /* Vcc this entry is attached */
|
||||
struct atm_vcc *recv_vcc; /* Vcc we receive data from */
|
||||
|
||||
void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb);
|
||||
/* Push that leads to daemon */
|
||||
|
||||
void (*old_recv_push) (struct atm_vcc *vcc, struct sk_buff *skb);
|
||||
/* Push that leads to daemon */
|
||||
|
||||
unsigned long last_used; /* For expiry */
|
||||
unsigned long timestamp; /* Used for various timestamping things:
|
||||
* 1. FLUSH started
|
||||
* (status=ESI_FLUSH_PENDING)
|
||||
* 2. Counting to
|
||||
* max_unknown_frame_time
|
||||
* (status=ESI_ARP_PENDING||
|
||||
* status=ESI_VC_PENDING)
|
||||
*/
|
||||
unsigned char no_tries; /* No of times arp retry has been tried */
|
||||
unsigned char status; /* Status of this entry */
|
||||
unsigned short flags; /* Flags for this entry */
|
||||
unsigned short packets_flooded; /* Data packets flooded */
|
||||
unsigned long flush_tran_id; /* Transaction id in flush protocol */
|
||||
struct timer_list timer; /* Arping timer */
|
||||
struct lec_priv *priv; /* Pointer back */
|
||||
u8 *tlvs;
|
||||
u32 sizeoftlvs; /*
|
||||
* LANE2: Each MAC address can have TLVs
|
||||
* associated with it. sizeoftlvs tells
|
||||
* the length of the tlvs array
|
||||
*/
|
||||
struct sk_buff_head tx_wait; /* wait queue for outgoing packets */
|
||||
refcount_t usage; /* usage count */
|
||||
};
|
||||
|
||||
/*
|
||||
* LANE2: Template tlv struct for accessing
|
||||
* the tlvs in the lec_arp_table->tlvs array
|
||||
*/
|
||||
struct tlv {
|
||||
u32 type;
|
||||
u8 length;
|
||||
u8 value[255];
|
||||
};
|
||||
|
||||
/* Status fields */
|
||||
#define ESI_UNKNOWN 0 /*
|
||||
* Next packet sent to this mac address
|
||||
* causes ARP-request to be sent
|
||||
*/
|
||||
#define ESI_ARP_PENDING 1 /*
|
||||
* There is no ATM address associated with this
|
||||
* 48-bit address. The LE-ARP protocol is in
|
||||
* progress.
|
||||
*/
|
||||
#define ESI_VC_PENDING 2 /*
|
||||
* There is a valid ATM address associated with
|
||||
* this 48-bit address but there is no VC set
|
||||
* up to that ATM address. The signaling
|
||||
* protocol is in process.
|
||||
*/
|
||||
#define ESI_FLUSH_PENDING 4 /*
|
||||
* The LEC has been notified of the FLUSH_START
|
||||
* status and it is assumed that the flush
|
||||
* protocol is in process.
|
||||
*/
|
||||
#define ESI_FORWARD_DIRECT 5 /*
|
||||
* Either the Path Switching Delay (C22) has
|
||||
* elapsed or the LEC has notified the Mapping
|
||||
* that the flush protocol has completed. In
|
||||
* either case, it is safe to forward packets
|
||||
* to this address via the data direct VC.
|
||||
*/
|
||||
|
||||
/* Flag values */
|
||||
#define LEC_REMOTE_FLAG 0x0001
|
||||
#define LEC_PERMANENT_FLAG 0x0002
|
||||
|
||||
#endif /* _LEC_ARP_H_ */
|
||||
1538
net/atm/mpc.c
1538
net/atm/mpc.c
File diff suppressed because it is too large
Load Diff
@@ -1,65 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _MPC_H_
|
||||
#define _MPC_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmmpc.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include "mpoa_caches.h"
|
||||
|
||||
/* kernel -> mpc-daemon */
|
||||
int msg_to_mpoad(struct k_message *msg, struct mpoa_client *mpc);
|
||||
|
||||
struct mpoa_client {
|
||||
struct mpoa_client *next;
|
||||
struct net_device *dev; /* lec in question */
|
||||
int dev_num; /* e.g. 2 for lec2 */
|
||||
|
||||
struct atm_vcc *mpoad_vcc; /* control channel to mpoad */
|
||||
uint8_t mps_ctrl_addr[ATM_ESA_LEN]; /* MPS control ATM address */
|
||||
uint8_t our_ctrl_addr[ATM_ESA_LEN]; /* MPC's control ATM address */
|
||||
|
||||
rwlock_t ingress_lock;
|
||||
const struct in_cache_ops *in_ops; /* ingress cache operations */
|
||||
in_cache_entry *in_cache; /* the ingress cache of this MPC */
|
||||
|
||||
rwlock_t egress_lock;
|
||||
const struct eg_cache_ops *eg_ops; /* egress cache operations */
|
||||
eg_cache_entry *eg_cache; /* the egress cache of this MPC */
|
||||
|
||||
uint8_t *mps_macs; /* array of MPS MAC addresses, >=1 */
|
||||
int number_of_mps_macs; /* number of the above MAC addresses */
|
||||
struct mpc_parameters parameters; /* parameters for this client */
|
||||
|
||||
const struct net_device_ops *old_ops;
|
||||
struct net_device_ops new_ops;
|
||||
};
|
||||
|
||||
|
||||
struct atm_mpoa_qos {
|
||||
struct atm_mpoa_qos *next;
|
||||
__be32 ipaddr;
|
||||
struct atm_qos qos;
|
||||
};
|
||||
|
||||
|
||||
/* MPOA QoS operations */
|
||||
struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos);
|
||||
struct atm_mpoa_qos *atm_mpoa_search_qos(__be32 dst_ip);
|
||||
int atm_mpoa_delete_qos(struct atm_mpoa_qos *qos);
|
||||
|
||||
/* Display QoS entries. This is for the procfs */
|
||||
struct seq_file;
|
||||
void atm_mpoa_disp_qos(struct seq_file *m);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
int mpc_proc_init(void);
|
||||
void mpc_proc_clean(void);
|
||||
#else
|
||||
#define mpc_proc_init() (0)
|
||||
#define mpc_proc_clean() do { } while(0)
|
||||
#endif
|
||||
|
||||
#endif /* _MPC_H_ */
|
||||
@@ -1,565 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/types.h>
|
||||
#include <linux/atmmpc.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include "mpoa_caches.h"
|
||||
#include "mpc.h"
|
||||
|
||||
/*
|
||||
* mpoa_caches.c: Implementation of ingress and egress cache
|
||||
* handling functions
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#define dprintk(format, args...) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args) /* debug */
|
||||
#else
|
||||
#define dprintk(format, args...) \
|
||||
do { if (0) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define ddprintk(format, args...) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args) /* debug */
|
||||
#else
|
||||
#define ddprintk(format, args...) \
|
||||
do { if (0) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static in_cache_entry *in_cache_get(__be32 dst_ip,
|
||||
struct mpoa_client *client)
|
||||
{
|
||||
in_cache_entry *entry;
|
||||
|
||||
read_lock_bh(&client->ingress_lock);
|
||||
entry = client->in_cache;
|
||||
while (entry != NULL) {
|
||||
if (entry->ctrl_info.in_dst_ip == dst_ip) {
|
||||
refcount_inc(&entry->use);
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
return entry;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip,
|
||||
struct mpoa_client *client,
|
||||
__be32 mask)
|
||||
{
|
||||
in_cache_entry *entry;
|
||||
|
||||
read_lock_bh(&client->ingress_lock);
|
||||
entry = client->in_cache;
|
||||
while (entry != NULL) {
|
||||
if ((entry->ctrl_info.in_dst_ip & mask) == (dst_ip & mask)) {
|
||||
refcount_inc(&entry->use);
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
return entry;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
|
||||
struct mpoa_client *client)
|
||||
{
|
||||
in_cache_entry *entry;
|
||||
|
||||
read_lock_bh(&client->ingress_lock);
|
||||
entry = client->in_cache;
|
||||
while (entry != NULL) {
|
||||
if (entry->shortcut == vcc) {
|
||||
refcount_inc(&entry->use);
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
return entry;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
|
||||
struct mpoa_client *client)
|
||||
{
|
||||
in_cache_entry *entry = kzalloc_obj(in_cache_entry);
|
||||
|
||||
if (entry == NULL) {
|
||||
pr_info("mpoa: mpoa_caches.c: new_in_cache_entry: out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dprintk("adding an ingress entry, ip = %pI4\n", &dst_ip);
|
||||
|
||||
refcount_set(&entry->use, 1);
|
||||
dprintk("new_in_cache_entry: about to lock\n");
|
||||
write_lock_bh(&client->ingress_lock);
|
||||
entry->next = client->in_cache;
|
||||
entry->prev = NULL;
|
||||
if (client->in_cache != NULL)
|
||||
client->in_cache->prev = entry;
|
||||
client->in_cache = entry;
|
||||
|
||||
memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);
|
||||
entry->ctrl_info.in_dst_ip = dst_ip;
|
||||
entry->time = ktime_get_seconds();
|
||||
entry->retry_time = client->parameters.mpc_p4;
|
||||
entry->count = 1;
|
||||
entry->entry_state = INGRESS_INVALID;
|
||||
entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT;
|
||||
refcount_inc(&entry->use);
|
||||
|
||||
write_unlock_bh(&client->ingress_lock);
|
||||
dprintk("new_in_cache_entry: unlocked\n");
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
|
||||
{
|
||||
struct atm_mpoa_qos *qos;
|
||||
struct k_message msg;
|
||||
|
||||
entry->count++;
|
||||
if (entry->entry_state == INGRESS_RESOLVED && entry->shortcut != NULL)
|
||||
return OPEN;
|
||||
|
||||
if (entry->entry_state == INGRESS_REFRESHING) {
|
||||
if (entry->count > mpc->parameters.mpc_p1) {
|
||||
msg.type = SND_MPOA_RES_RQST;
|
||||
msg.content.in_info = entry->ctrl_info;
|
||||
memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
|
||||
qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
|
||||
if (qos != NULL)
|
||||
msg.qos = qos->qos;
|
||||
msg_to_mpoad(&msg, mpc);
|
||||
entry->reply_wait = ktime_get_seconds();
|
||||
entry->entry_state = INGRESS_RESOLVING;
|
||||
}
|
||||
if (entry->shortcut != NULL)
|
||||
return OPEN;
|
||||
return CLOSED;
|
||||
}
|
||||
|
||||
if (entry->entry_state == INGRESS_RESOLVING && entry->shortcut != NULL)
|
||||
return OPEN;
|
||||
|
||||
if (entry->count > mpc->parameters.mpc_p1 &&
|
||||
entry->entry_state == INGRESS_INVALID) {
|
||||
dprintk("(%s) threshold exceeded for ip %pI4, sending MPOA res req\n",
|
||||
mpc->dev->name, &entry->ctrl_info.in_dst_ip);
|
||||
entry->entry_state = INGRESS_RESOLVING;
|
||||
msg.type = SND_MPOA_RES_RQST;
|
||||
memcpy(msg.MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN);
|
||||
msg.content.in_info = entry->ctrl_info;
|
||||
qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
|
||||
if (qos != NULL)
|
||||
msg.qos = qos->qos;
|
||||
msg_to_mpoad(&msg, mpc);
|
||||
entry->reply_wait = ktime_get_seconds();
|
||||
}
|
||||
|
||||
return CLOSED;
|
||||
}
|
||||
|
||||
static void in_cache_put(in_cache_entry *entry)
|
||||
{
|
||||
if (refcount_dec_and_test(&entry->use)) {
|
||||
kfree_sensitive(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be called with write lock on
|
||||
*/
|
||||
static void in_cache_remove_entry(in_cache_entry *entry,
|
||||
struct mpoa_client *client)
|
||||
{
|
||||
struct atm_vcc *vcc;
|
||||
struct k_message msg;
|
||||
|
||||
vcc = entry->shortcut;
|
||||
dprintk("removing an ingress entry, ip = %pI4\n",
|
||||
&entry->ctrl_info.in_dst_ip);
|
||||
|
||||
if (entry->prev != NULL)
|
||||
entry->prev->next = entry->next;
|
||||
else
|
||||
client->in_cache = entry->next;
|
||||
if (entry->next != NULL)
|
||||
entry->next->prev = entry->prev;
|
||||
client->in_ops->put(entry);
|
||||
if (client->in_cache == NULL && client->eg_cache == NULL) {
|
||||
msg.type = STOP_KEEP_ALIVE_SM;
|
||||
msg_to_mpoad(&msg, client);
|
||||
}
|
||||
|
||||
/* Check if the egress side still uses this VCC */
|
||||
if (vcc != NULL) {
|
||||
eg_cache_entry *eg_entry = client->eg_ops->get_by_vcc(vcc,
|
||||
client);
|
||||
if (eg_entry != NULL) {
|
||||
client->eg_ops->put(eg_entry);
|
||||
return;
|
||||
}
|
||||
vcc_release_async(vcc, -EPIPE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Call this every MPC-p2 seconds... Not exactly correct solution,
|
||||
but an easy one... */
|
||||
static void clear_count_and_expired(struct mpoa_client *client)
|
||||
{
|
||||
in_cache_entry *entry, *next_entry;
|
||||
time64_t now;
|
||||
|
||||
now = ktime_get_seconds();
|
||||
|
||||
write_lock_bh(&client->ingress_lock);
|
||||
entry = client->in_cache;
|
||||
while (entry != NULL) {
|
||||
entry->count = 0;
|
||||
next_entry = entry->next;
|
||||
if ((now - entry->time) > entry->ctrl_info.holding_time) {
|
||||
dprintk("holding time expired, ip = %pI4\n",
|
||||
&entry->ctrl_info.in_dst_ip);
|
||||
client->in_ops->remove_entry(entry, client);
|
||||
}
|
||||
entry = next_entry;
|
||||
}
|
||||
write_unlock_bh(&client->ingress_lock);
|
||||
}
|
||||
|
||||
/* Call this every MPC-p4 seconds. */
|
||||
static void check_resolving_entries(struct mpoa_client *client)
|
||||
{
|
||||
|
||||
struct atm_mpoa_qos *qos;
|
||||
in_cache_entry *entry;
|
||||
time64_t now;
|
||||
struct k_message msg;
|
||||
|
||||
now = ktime_get_seconds();
|
||||
|
||||
read_lock_bh(&client->ingress_lock);
|
||||
entry = client->in_cache;
|
||||
while (entry != NULL) {
|
||||
if (entry->entry_state == INGRESS_RESOLVING) {
|
||||
|
||||
if ((now - entry->hold_down)
|
||||
< client->parameters.mpc_p6) {
|
||||
entry = entry->next; /* Entry in hold down */
|
||||
continue;
|
||||
}
|
||||
if ((now - entry->reply_wait) > entry->retry_time) {
|
||||
entry->retry_time = MPC_C1 * (entry->retry_time);
|
||||
/*
|
||||
* Retry time maximum exceeded,
|
||||
* put entry in hold down.
|
||||
*/
|
||||
if (entry->retry_time > client->parameters.mpc_p5) {
|
||||
entry->hold_down = ktime_get_seconds();
|
||||
entry->retry_time = client->parameters.mpc_p4;
|
||||
entry = entry->next;
|
||||
continue;
|
||||
}
|
||||
/* Ask daemon to send a resolution request. */
|
||||
memset(&entry->hold_down, 0, sizeof(time64_t));
|
||||
msg.type = SND_MPOA_RES_RTRY;
|
||||
memcpy(msg.MPS_ctrl, client->mps_ctrl_addr, ATM_ESA_LEN);
|
||||
msg.content.in_info = entry->ctrl_info;
|
||||
qos = atm_mpoa_search_qos(entry->ctrl_info.in_dst_ip);
|
||||
if (qos != NULL)
|
||||
msg.qos = qos->qos;
|
||||
msg_to_mpoad(&msg, client);
|
||||
entry->reply_wait = ktime_get_seconds();
|
||||
}
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
}
|
||||
|
||||
/* Call this every MPC-p5 seconds. */
|
||||
static void refresh_entries(struct mpoa_client *client)
|
||||
{
|
||||
time64_t now;
|
||||
struct in_cache_entry *entry = client->in_cache;
|
||||
|
||||
ddprintk("refresh_entries\n");
|
||||
now = ktime_get_seconds();
|
||||
|
||||
read_lock_bh(&client->ingress_lock);
|
||||
while (entry != NULL) {
|
||||
if (entry->entry_state == INGRESS_RESOLVED) {
|
||||
if (!(entry->refresh_time))
|
||||
entry->refresh_time = (2 * (entry->ctrl_info.holding_time))/3;
|
||||
if ((now - entry->reply_wait) >
|
||||
entry->refresh_time) {
|
||||
dprintk("refreshing an entry.\n");
|
||||
entry->entry_state = INGRESS_REFRESHING;
|
||||
|
||||
}
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_bh(&client->ingress_lock);
|
||||
}
|
||||
|
||||
static void in_destroy_cache(struct mpoa_client *mpc)
|
||||
{
|
||||
write_lock_irq(&mpc->ingress_lock);
|
||||
while (mpc->in_cache != NULL)
|
||||
mpc->in_ops->remove_entry(mpc->in_cache, mpc);
|
||||
write_unlock_irq(&mpc->ingress_lock);
|
||||
}
|
||||
|
||||
static eg_cache_entry *eg_cache_get_by_cache_id(__be32 cache_id,
|
||||
struct mpoa_client *mpc)
|
||||
{
|
||||
eg_cache_entry *entry;
|
||||
|
||||
read_lock_irq(&mpc->egress_lock);
|
||||
entry = mpc->eg_cache;
|
||||
while (entry != NULL) {
|
||||
if (entry->ctrl_info.cache_id == cache_id) {
|
||||
refcount_inc(&entry->use);
|
||||
read_unlock_irq(&mpc->egress_lock);
|
||||
return entry;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_irq(&mpc->egress_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This can be called from any context since it saves CPU flags */
|
||||
static eg_cache_entry *eg_cache_get_by_tag(__be32 tag, struct mpoa_client *mpc)
|
||||
{
|
||||
unsigned long flags;
|
||||
eg_cache_entry *entry;
|
||||
|
||||
read_lock_irqsave(&mpc->egress_lock, flags);
|
||||
entry = mpc->eg_cache;
|
||||
while (entry != NULL) {
|
||||
if (entry->ctrl_info.tag == tag) {
|
||||
refcount_inc(&entry->use);
|
||||
read_unlock_irqrestore(&mpc->egress_lock, flags);
|
||||
return entry;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_irqrestore(&mpc->egress_lock, flags);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This can be called from any context since it saves CPU flags */
|
||||
static eg_cache_entry *eg_cache_get_by_vcc(struct atm_vcc *vcc,
|
||||
struct mpoa_client *mpc)
|
||||
{
|
||||
unsigned long flags;
|
||||
eg_cache_entry *entry;
|
||||
|
||||
read_lock_irqsave(&mpc->egress_lock, flags);
|
||||
entry = mpc->eg_cache;
|
||||
while (entry != NULL) {
|
||||
if (entry->shortcut == vcc) {
|
||||
refcount_inc(&entry->use);
|
||||
read_unlock_irqrestore(&mpc->egress_lock, flags);
|
||||
return entry;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_irqrestore(&mpc->egress_lock, flags);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static eg_cache_entry *eg_cache_get_by_src_ip(__be32 ipaddr,
|
||||
struct mpoa_client *mpc)
|
||||
{
|
||||
eg_cache_entry *entry;
|
||||
|
||||
read_lock_irq(&mpc->egress_lock);
|
||||
entry = mpc->eg_cache;
|
||||
while (entry != NULL) {
|
||||
if (entry->latest_ip_addr == ipaddr) {
|
||||
refcount_inc(&entry->use);
|
||||
read_unlock_irq(&mpc->egress_lock);
|
||||
return entry;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
read_unlock_irq(&mpc->egress_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void eg_cache_put(eg_cache_entry *entry)
|
||||
{
|
||||
if (refcount_dec_and_test(&entry->use)) {
|
||||
kfree_sensitive(entry);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This should be called with write lock on
|
||||
*/
|
||||
static void eg_cache_remove_entry(eg_cache_entry *entry,
|
||||
struct mpoa_client *client)
|
||||
{
|
||||
struct atm_vcc *vcc;
|
||||
struct k_message msg;
|
||||
|
||||
vcc = entry->shortcut;
|
||||
dprintk("removing an egress entry.\n");
|
||||
if (entry->prev != NULL)
|
||||
entry->prev->next = entry->next;
|
||||
else
|
||||
client->eg_cache = entry->next;
|
||||
if (entry->next != NULL)
|
||||
entry->next->prev = entry->prev;
|
||||
client->eg_ops->put(entry);
|
||||
if (client->in_cache == NULL && client->eg_cache == NULL) {
|
||||
msg.type = STOP_KEEP_ALIVE_SM;
|
||||
msg_to_mpoad(&msg, client);
|
||||
}
|
||||
|
||||
/* Check if the ingress side still uses this VCC */
|
||||
if (vcc != NULL) {
|
||||
in_cache_entry *in_entry = client->in_ops->get_by_vcc(vcc, client);
|
||||
if (in_entry != NULL) {
|
||||
client->in_ops->put(in_entry);
|
||||
return;
|
||||
}
|
||||
vcc_release_async(vcc, -EPIPE);
|
||||
}
|
||||
}
|
||||
|
||||
static eg_cache_entry *eg_cache_add_entry(struct k_message *msg,
|
||||
struct mpoa_client *client)
|
||||
{
|
||||
eg_cache_entry *entry = kzalloc_obj(eg_cache_entry);
|
||||
|
||||
if (entry == NULL) {
|
||||
pr_info("out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dprintk("adding an egress entry, ip = %pI4, this should be our IP\n",
|
||||
&msg->content.eg_info.eg_dst_ip);
|
||||
|
||||
refcount_set(&entry->use, 1);
|
||||
dprintk("new_eg_cache_entry: about to lock\n");
|
||||
write_lock_irq(&client->egress_lock);
|
||||
entry->next = client->eg_cache;
|
||||
entry->prev = NULL;
|
||||
if (client->eg_cache != NULL)
|
||||
client->eg_cache->prev = entry;
|
||||
client->eg_cache = entry;
|
||||
|
||||
memcpy(entry->MPS_ctrl_ATM_addr, client->mps_ctrl_addr, ATM_ESA_LEN);
|
||||
entry->ctrl_info = msg->content.eg_info;
|
||||
entry->time = ktime_get_seconds();
|
||||
entry->entry_state = EGRESS_RESOLVED;
|
||||
dprintk("new_eg_cache_entry cache_id %u\n",
|
||||
ntohl(entry->ctrl_info.cache_id));
|
||||
dprintk("mps_ip = %pI4\n", &entry->ctrl_info.mps_ip);
|
||||
refcount_inc(&entry->use);
|
||||
|
||||
write_unlock_irq(&client->egress_lock);
|
||||
dprintk("new_eg_cache_entry: unlocked\n");
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
static void update_eg_cache_entry(eg_cache_entry *entry, uint16_t holding_time)
|
||||
{
|
||||
entry->time = ktime_get_seconds();
|
||||
entry->entry_state = EGRESS_RESOLVED;
|
||||
entry->ctrl_info.holding_time = holding_time;
|
||||
}
|
||||
|
||||
static void clear_expired(struct mpoa_client *client)
|
||||
{
|
||||
eg_cache_entry *entry, *next_entry;
|
||||
time64_t now;
|
||||
struct k_message msg;
|
||||
|
||||
now = ktime_get_seconds();
|
||||
|
||||
write_lock_irq(&client->egress_lock);
|
||||
entry = client->eg_cache;
|
||||
while (entry != NULL) {
|
||||
next_entry = entry->next;
|
||||
if ((now - entry->time) > entry->ctrl_info.holding_time) {
|
||||
msg.type = SND_EGRESS_PURGE;
|
||||
msg.content.eg_info = entry->ctrl_info;
|
||||
dprintk("egress_cache: holding time expired, cache_id = %u.\n",
|
||||
ntohl(entry->ctrl_info.cache_id));
|
||||
msg_to_mpoad(&msg, client);
|
||||
client->eg_ops->remove_entry(entry, client);
|
||||
}
|
||||
entry = next_entry;
|
||||
}
|
||||
write_unlock_irq(&client->egress_lock);
|
||||
}
|
||||
|
||||
static void eg_destroy_cache(struct mpoa_client *mpc)
|
||||
{
|
||||
write_lock_irq(&mpc->egress_lock);
|
||||
while (mpc->eg_cache != NULL)
|
||||
mpc->eg_ops->remove_entry(mpc->eg_cache, mpc);
|
||||
write_unlock_irq(&mpc->egress_lock);
|
||||
}
|
||||
|
||||
|
||||
static const struct in_cache_ops ingress_ops = {
|
||||
.add_entry = in_cache_add_entry,
|
||||
.get = in_cache_get,
|
||||
.get_with_mask = in_cache_get_with_mask,
|
||||
.get_by_vcc = in_cache_get_by_vcc,
|
||||
.put = in_cache_put,
|
||||
.remove_entry = in_cache_remove_entry,
|
||||
.cache_hit = cache_hit,
|
||||
.clear_count = clear_count_and_expired,
|
||||
.check_resolving = check_resolving_entries,
|
||||
.refresh = refresh_entries,
|
||||
.destroy_cache = in_destroy_cache
|
||||
};
|
||||
|
||||
static const struct eg_cache_ops egress_ops = {
|
||||
.add_entry = eg_cache_add_entry,
|
||||
.get_by_cache_id = eg_cache_get_by_cache_id,
|
||||
.get_by_tag = eg_cache_get_by_tag,
|
||||
.get_by_vcc = eg_cache_get_by_vcc,
|
||||
.get_by_src_ip = eg_cache_get_by_src_ip,
|
||||
.put = eg_cache_put,
|
||||
.remove_entry = eg_cache_remove_entry,
|
||||
.update = update_eg_cache_entry,
|
||||
.clear_expired = clear_expired,
|
||||
.destroy_cache = eg_destroy_cache
|
||||
};
|
||||
|
||||
void atm_mpoa_init_cache(struct mpoa_client *mpc)
|
||||
{
|
||||
mpc->in_ops = &ingress_ops;
|
||||
mpc->eg_ops = &egress_ops;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef MPOA_CACHES_H
|
||||
#define MPOA_CACHES_H
|
||||
|
||||
#include <linux/time64.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/atmmpc.h>
|
||||
#include <linux/refcount.h>
|
||||
|
||||
struct mpoa_client;
|
||||
|
||||
void atm_mpoa_init_cache(struct mpoa_client *mpc);
|
||||
|
||||
typedef struct in_cache_entry {
|
||||
struct in_cache_entry *next;
|
||||
struct in_cache_entry *prev;
|
||||
time64_t time;
|
||||
time64_t reply_wait;
|
||||
time64_t hold_down;
|
||||
uint32_t packets_fwded;
|
||||
uint16_t entry_state;
|
||||
uint32_t retry_time;
|
||||
uint32_t refresh_time;
|
||||
uint32_t count;
|
||||
struct atm_vcc *shortcut;
|
||||
uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
|
||||
struct in_ctrl_info ctrl_info;
|
||||
refcount_t use;
|
||||
} in_cache_entry;
|
||||
|
||||
struct in_cache_ops{
|
||||
in_cache_entry *(*add_entry)(__be32 dst_ip,
|
||||
struct mpoa_client *client);
|
||||
in_cache_entry *(*get)(__be32 dst_ip, struct mpoa_client *client);
|
||||
in_cache_entry *(*get_with_mask)(__be32 dst_ip,
|
||||
struct mpoa_client *client,
|
||||
__be32 mask);
|
||||
in_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc,
|
||||
struct mpoa_client *client);
|
||||
void (*put)(in_cache_entry *entry);
|
||||
void (*remove_entry)(in_cache_entry *delEntry,
|
||||
struct mpoa_client *client );
|
||||
int (*cache_hit)(in_cache_entry *entry,
|
||||
struct mpoa_client *client);
|
||||
void (*clear_count)(struct mpoa_client *client);
|
||||
void (*check_resolving)(struct mpoa_client *client);
|
||||
void (*refresh)(struct mpoa_client *client);
|
||||
void (*destroy_cache)(struct mpoa_client *mpc);
|
||||
};
|
||||
|
||||
typedef struct eg_cache_entry{
|
||||
struct eg_cache_entry *next;
|
||||
struct eg_cache_entry *prev;
|
||||
time64_t time;
|
||||
uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
|
||||
struct atm_vcc *shortcut;
|
||||
uint32_t packets_rcvd;
|
||||
uint16_t entry_state;
|
||||
__be32 latest_ip_addr; /* The src IP address of the last packet */
|
||||
struct eg_ctrl_info ctrl_info;
|
||||
refcount_t use;
|
||||
} eg_cache_entry;
|
||||
|
||||
struct eg_cache_ops{
|
||||
eg_cache_entry *(*add_entry)(struct k_message *msg, struct mpoa_client *client);
|
||||
eg_cache_entry *(*get_by_cache_id)(__be32 cache_id, struct mpoa_client *client);
|
||||
eg_cache_entry *(*get_by_tag)(__be32 cache_id, struct mpoa_client *client);
|
||||
eg_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc, struct mpoa_client *client);
|
||||
eg_cache_entry *(*get_by_src_ip)(__be32 ipaddr, struct mpoa_client *client);
|
||||
void (*put)(eg_cache_entry *entry);
|
||||
void (*remove_entry)(eg_cache_entry *entry, struct mpoa_client *client);
|
||||
void (*update)(eg_cache_entry *entry, uint16_t holding_time);
|
||||
void (*clear_expired)(struct mpoa_client *client);
|
||||
void (*destroy_cache)(struct mpoa_client *mpc);
|
||||
};
|
||||
|
||||
|
||||
/* Ingress cache entry states */
|
||||
|
||||
#define INGRESS_REFRESHING 3
|
||||
#define INGRESS_RESOLVED 2
|
||||
#define INGRESS_RESOLVING 1
|
||||
#define INGRESS_INVALID 0
|
||||
|
||||
/* VCC states */
|
||||
|
||||
#define OPEN 1
|
||||
#define CLOSED 0
|
||||
|
||||
/* Egress cache entry states */
|
||||
|
||||
#define EGRESS_RESOLVED 2
|
||||
#define EGRESS_PURGE 1
|
||||
#define EGRESS_INVALID 0
|
||||
|
||||
#endif
|
||||
@@ -1,307 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/atmmpc.h>
|
||||
#include <linux/atm.h>
|
||||
#include <linux/gfp.h>
|
||||
#include "mpc.h"
|
||||
#include "mpoa_caches.h"
|
||||
|
||||
/*
|
||||
* mpoa_proc.c: Implementation MPOA client's proc
|
||||
* file system statistics
|
||||
*/
|
||||
|
||||
#if 1
|
||||
#define dprintk(format, args...) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args) /* debug */
|
||||
#else
|
||||
#define dprintk(format, args...) \
|
||||
do { if (0) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define ddprintk(format, args...) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args) /* debug */
|
||||
#else
|
||||
#define ddprintk(format, args...) \
|
||||
do { if (0) \
|
||||
printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define STAT_FILE_NAME "mpc" /* Our statistic file's name */
|
||||
|
||||
extern struct mpoa_client *mpcs;
|
||||
extern struct proc_dir_entry *atm_proc_root; /* from proc.c. */
|
||||
|
||||
static int proc_mpc_open(struct inode *inode, struct file *file);
|
||||
static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
|
||||
size_t nbytes, loff_t *ppos);
|
||||
|
||||
static int parse_qos(const char *buff);
|
||||
|
||||
static const struct proc_ops mpc_proc_ops = {
|
||||
.proc_open = proc_mpc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_write = proc_mpc_write,
|
||||
.proc_release = seq_release,
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns the state of an ingress cache entry as a string
|
||||
*/
|
||||
static const char *ingress_state_string(int state)
|
||||
{
|
||||
switch (state) {
|
||||
case INGRESS_RESOLVING:
|
||||
return "resolving ";
|
||||
case INGRESS_RESOLVED:
|
||||
return "resolved ";
|
||||
case INGRESS_INVALID:
|
||||
return "invalid ";
|
||||
case INGRESS_REFRESHING:
|
||||
return "refreshing ";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the state of an egress cache entry as a string
|
||||
*/
|
||||
static const char *egress_state_string(int state)
|
||||
{
|
||||
switch (state) {
|
||||
case EGRESS_RESOLVED:
|
||||
return "resolved ";
|
||||
case EGRESS_PURGE:
|
||||
return "purge ";
|
||||
case EGRESS_INVALID:
|
||||
return "invalid ";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: mpcs (and per-mpc lists) have no locking whatsoever.
|
||||
*/
|
||||
|
||||
static void *mpc_start(struct seq_file *m, loff_t *pos)
|
||||
{
|
||||
loff_t l = *pos;
|
||||
struct mpoa_client *mpc;
|
||||
|
||||
if (!l--)
|
||||
return SEQ_START_TOKEN;
|
||||
for (mpc = mpcs; mpc; mpc = mpc->next)
|
||||
if (!l--)
|
||||
return mpc;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *mpc_next(struct seq_file *m, void *v, loff_t *pos)
|
||||
{
|
||||
struct mpoa_client *p = v;
|
||||
(*pos)++;
|
||||
return v == SEQ_START_TOKEN ? mpcs : p->next;
|
||||
}
|
||||
|
||||
static void mpc_stop(struct seq_file *m, void *v)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* READING function - called when the /proc/atm/mpoa file is read from.
|
||||
*/
|
||||
static int mpc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
struct mpoa_client *mpc = v;
|
||||
int i;
|
||||
in_cache_entry *in_entry;
|
||||
eg_cache_entry *eg_entry;
|
||||
time64_t now;
|
||||
unsigned char ip_string[16];
|
||||
|
||||
if (v == SEQ_START_TOKEN) {
|
||||
atm_mpoa_disp_qos(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
seq_printf(m, "\nInterface %d:\n\n", mpc->dev_num);
|
||||
seq_printf(m, "Ingress Entries:\nIP address State Holding time Packets fwded VPI VCI\n");
|
||||
now = ktime_get_seconds();
|
||||
|
||||
for (in_entry = mpc->in_cache; in_entry; in_entry = in_entry->next) {
|
||||
unsigned long seconds_delta = now - in_entry->time;
|
||||
|
||||
sprintf(ip_string, "%pI4", &in_entry->ctrl_info.in_dst_ip);
|
||||
seq_printf(m, "%-16s%s%-14lu%-12u",
|
||||
ip_string,
|
||||
ingress_state_string(in_entry->entry_state),
|
||||
in_entry->ctrl_info.holding_time -
|
||||
seconds_delta,
|
||||
in_entry->packets_fwded);
|
||||
if (in_entry->shortcut)
|
||||
seq_printf(m, " %-3d %-3d",
|
||||
in_entry->shortcut->vpi,
|
||||
in_entry->shortcut->vci);
|
||||
seq_printf(m, "\n");
|
||||
}
|
||||
|
||||
seq_printf(m, "\n");
|
||||
seq_printf(m, "Egress Entries:\nIngress MPC ATM addr\nCache-id State Holding time Packets recvd Latest IP addr VPI VCI\n");
|
||||
for (eg_entry = mpc->eg_cache; eg_entry; eg_entry = eg_entry->next) {
|
||||
unsigned char *p = eg_entry->ctrl_info.in_MPC_data_ATM_addr;
|
||||
unsigned long seconds_delta = now - eg_entry->time;
|
||||
|
||||
for (i = 0; i < ATM_ESA_LEN; i++)
|
||||
seq_printf(m, "%02x", p[i]);
|
||||
seq_printf(m, "\n%-16lu%s%-14lu%-15u",
|
||||
(unsigned long)ntohl(eg_entry->ctrl_info.cache_id),
|
||||
egress_state_string(eg_entry->entry_state),
|
||||
(eg_entry->ctrl_info.holding_time - seconds_delta),
|
||||
eg_entry->packets_rcvd);
|
||||
|
||||
/* latest IP address */
|
||||
sprintf(ip_string, "%pI4", &eg_entry->latest_ip_addr);
|
||||
seq_printf(m, "%-16s", ip_string);
|
||||
|
||||
if (eg_entry->shortcut)
|
||||
seq_printf(m, " %-3d %-3d",
|
||||
eg_entry->shortcut->vpi,
|
||||
eg_entry->shortcut->vci);
|
||||
seq_printf(m, "\n");
|
||||
}
|
||||
seq_printf(m, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations mpc_op = {
|
||||
.start = mpc_start,
|
||||
.next = mpc_next,
|
||||
.stop = mpc_stop,
|
||||
.show = mpc_show
|
||||
};
|
||||
|
||||
static int proc_mpc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &mpc_op);
|
||||
}
|
||||
|
||||
static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
|
||||
size_t nbytes, loff_t *ppos)
|
||||
{
|
||||
char *page, *p;
|
||||
unsigned int len;
|
||||
|
||||
if (nbytes == 0)
|
||||
return 0;
|
||||
|
||||
if (nbytes >= PAGE_SIZE)
|
||||
nbytes = PAGE_SIZE-1;
|
||||
|
||||
page = (char *)__get_free_page(GFP_KERNEL);
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
for (p = page, len = 0; len < nbytes; p++) {
|
||||
if (get_user(*p, buff++)) {
|
||||
free_page((unsigned long)page);
|
||||
return -EFAULT;
|
||||
}
|
||||
len += 1;
|
||||
if (*p == '\0' || *p == '\n')
|
||||
break;
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
|
||||
if (!parse_qos(page))
|
||||
printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
|
||||
|
||||
free_page((unsigned long)page);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int parse_qos(const char *buff)
|
||||
{
|
||||
/* possible lines look like this
|
||||
* add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
|
||||
*/
|
||||
unsigned char ip[4];
|
||||
int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
|
||||
__be32 ipaddr;
|
||||
struct atm_qos qos;
|
||||
|
||||
memset(&qos, 0, sizeof(struct atm_qos));
|
||||
|
||||
if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
|
||||
ip, ip+1, ip+2, ip+3) == 4) {
|
||||
ipaddr = *(__be32 *)ip;
|
||||
return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
|
||||
}
|
||||
|
||||
if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=tx",
|
||||
ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu) == 6) {
|
||||
rx_pcr = tx_pcr;
|
||||
rx_sdu = tx_sdu;
|
||||
} else if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=%d,%d",
|
||||
ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8)
|
||||
return 0;
|
||||
|
||||
ipaddr = *(__be32 *)ip;
|
||||
qos.txtp.traffic_class = ATM_CBR;
|
||||
qos.txtp.max_pcr = tx_pcr;
|
||||
qos.txtp.max_sdu = tx_sdu;
|
||||
qos.rxtp.traffic_class = ATM_CBR;
|
||||
qos.rxtp.max_pcr = rx_pcr;
|
||||
qos.rxtp.max_sdu = rx_sdu;
|
||||
qos.aal = ATM_AAL5;
|
||||
dprintk("parse_qos(): setting qos parameters to tx=%d,%d rx=%d,%d\n",
|
||||
qos.txtp.max_pcr, qos.txtp.max_sdu,
|
||||
qos.rxtp.max_pcr, qos.rxtp.max_sdu);
|
||||
|
||||
atm_mpoa_add_qos(ipaddr, &qos);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* INITIALIZATION function - called when module is initialized/loaded.
|
||||
*/
|
||||
int mpc_proc_init(void)
|
||||
{
|
||||
struct proc_dir_entry *p;
|
||||
|
||||
p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_proc_ops);
|
||||
if (!p) {
|
||||
pr_err("Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* DELETING function - called when module is removed.
|
||||
*/
|
||||
void mpc_proc_clean(void)
|
||||
{
|
||||
remove_proc_entry(STAT_FILE_NAME, atm_proc_root);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
@@ -21,11 +21,9 @@
|
||||
#include <linux/atm.h>
|
||||
#include <linux/atmdev.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/atmclip.h>
|
||||
#include <linux/init.h> /* for __init */
|
||||
#include <linux/slab.h>
|
||||
#include <net/net_namespace.h>
|
||||
#include <net/atmclip.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/param.h> /* for HZ */
|
||||
#include <linux/atomic.h>
|
||||
@@ -155,15 +153,6 @@ static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
|
||||
class_name[vcc->qos.rxtp.traffic_class],
|
||||
vcc->qos.txtp.min_pcr,
|
||||
class_name[vcc->qos.txtp.traffic_class]);
|
||||
if (test_bit(ATM_VF_IS_CLIP, &vcc->flags)) {
|
||||
struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
|
||||
struct net_device *dev;
|
||||
|
||||
dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
|
||||
seq_printf(seq, "CLIP, Itf:%s, Encap:",
|
||||
dev ? dev->name : "none?");
|
||||
seq_printf(seq, "%s", clip_vcc->encap ? "LLC/SNAP" : "None");
|
||||
}
|
||||
seq_putc(seq, '\n');
|
||||
}
|
||||
|
||||
|
||||
@@ -464,10 +464,6 @@ static int __init br_init(void)
|
||||
|
||||
brioctl_set(br_ioctl_stub);
|
||||
|
||||
#if IS_ENABLED(CONFIG_ATM_LANE)
|
||||
br_fdb_test_addr_hook = br_fdb_test_addr;
|
||||
#endif
|
||||
|
||||
#if IS_MODULE(CONFIG_BRIDGE_NETFILTER)
|
||||
pr_info("bridge: filtering via arp/ip/ip6tables is no longer available "
|
||||
"by default. Update your scripts to load br_netfilter if you "
|
||||
@@ -506,9 +502,6 @@ static void __exit br_deinit(void)
|
||||
rcu_barrier(); /* Wait for completion of call_rcu()'s */
|
||||
|
||||
br_nf_core_fini();
|
||||
#if IS_ENABLED(CONFIG_ATM_LANE)
|
||||
br_fdb_test_addr_hook = NULL;
|
||||
#endif
|
||||
br_fdb_fini();
|
||||
}
|
||||
|
||||
|
||||
@@ -892,35 +892,6 @@ void br_fdb_delete_by_port(struct net_bridge *br,
|
||||
spin_unlock_bh(&br->hash_lock);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_ATM_LANE)
|
||||
/* Interface used by ATM LANE hook to test
|
||||
* if an addr is on some other bridge port */
|
||||
int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
|
||||
{
|
||||
struct net_bridge_fdb_entry *fdb;
|
||||
struct net_bridge_port *port;
|
||||
int ret;
|
||||
|
||||
rcu_read_lock();
|
||||
port = br_port_get_rcu(dev);
|
||||
if (!port)
|
||||
ret = 0;
|
||||
else {
|
||||
const struct net_bridge_port *dst = NULL;
|
||||
|
||||
fdb = br_fdb_find_rcu(port->br, addr, 0);
|
||||
if (fdb)
|
||||
dst = READ_ONCE(fdb->dst);
|
||||
|
||||
ret = dst && dst->dev != dev &&
|
||||
dst->state == BR_STATE_FORWARDING;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_ATM_LANE */
|
||||
|
||||
/*
|
||||
* Fill buffer with forwarding table records in
|
||||
* the API format.
|
||||
|
||||
@@ -855,7 +855,6 @@ void br_fdb_delete_by_port(struct net_bridge *br,
|
||||
struct net_bridge_fdb_entry *br_fdb_find_rcu(struct net_bridge *br,
|
||||
const unsigned char *addr,
|
||||
__u16 vid);
|
||||
int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
|
||||
int br_fdb_fillbuf(struct net_bridge *br, void *buf, unsigned long count,
|
||||
unsigned long off);
|
||||
int br_fdb_add_local(struct net_bridge *br, struct net_bridge_port *source,
|
||||
@@ -2065,9 +2064,6 @@ void br_stp_port_timer_init(struct net_bridge_port *p);
|
||||
unsigned long br_timer_value(const struct timer_list *timer);
|
||||
|
||||
/* br.c */
|
||||
#if IS_ENABLED(CONFIG_ATM_LANE)
|
||||
extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
|
||||
#endif
|
||||
|
||||
/* br_mrp.c */
|
||||
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
|
||||
|
||||
@@ -5862,13 +5862,6 @@ static __latent_entropy void net_tx_action(void)
|
||||
xfrm_dev_backlog(sd);
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_ATM_LANE)
|
||||
/* This hook is defined here for ATM LANE */
|
||||
int (*br_fdb_test_addr_hook)(struct net_device *dev,
|
||||
unsigned char *addr) __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(br_fdb_test_addr_hook);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* netdev_is_rx_handler_busy - check if receive handler is registered
|
||||
* @dev: device to check
|
||||
|
||||
Reference in New Issue
Block a user