code:
.. SPDX-License-Identifier: GPL-2.0

=============
DCCP protocol
=============

.. Contents
   - Introduction
   - Missing features
   - Socket options
   - Sysctl variables
   - IOCTLs
   - Other tunables
   - Notes

Introduction
============
Datagram Congestion Control Protocol (DCCP) is an unreliable, connection
oriented protocol designed to solve issues present in UDP and TCP, particularly
for real-time and multimedia (streaming) traffic.
It divides into a base protocol (RFC 4340) and pluggable congestion control
modules called CCIDs. Like pluggable TCP congestion control, at least one CCID
needs to be enabled in order for the protocol to function properly. In the Linux
implementation, this is the TCP-like CCID2 (RFC 4341). Additional CCIDs, such as
the TCP-friendly CCID3 (RFC 4342), are optional.
For a brief introduction to CCIDs and suggestions for choosing a CCID to match
given applications, see section 10 of RFC 4340.

It has a base protocol and pluggable congestion control IDs (CCIDs).

DCCP is a Proposed Standard (RFC 2026), and the homepage for DCCP as a protocol
is at http://www.ietf.org/html.charters/dccp-charter.html

Missing features
================
The Linux DCCP implementation does not currently support all the features that are
specified in RFCs 4340...42.

The known bugs are at:

	http://www.linuxfoundation.org/collaborate/workgroups/networking/todo#DCCP

For more up-to-date versions of the DCCP implementation, please consider using
the experimental DCCP test tree; instructions for checking this out are on:
http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp_testing#Experimental_DCCP_source_tree

Socket options
==============
DCCP_SOCKOPT_QPOLICY_ID sets the dequeuing policy for outgoing packets. It takes
a policy ID as argument and can only be set before the connection (i.e. changes
during an established connection are not supported). Currently, two policies are
defined: the "simple" policy (DCCPQ_POLICY_SIMPLE), which does nothing special,
and a priority-based variant (DCCPQ_POLICY_PRIO). The latter allows to pass an
u32 priority value as ancillary data to sendmsg(), where higher numbers indicate
a higher packet priority (similar to SO_PRIORITY). This ancillary data needs to
be formatted using a cmsg(3) message header filled in as follows::

	cmsg->cmsg_level = SOL_DCCP;
	cmsg->cmsg_type	 = DCCP_SCM_PRIORITY;
	cmsg->cmsg_len	 = CMSG_LEN(sizeof(uint32_t));	/* or CMSG_LEN(4) */

DCCP_SOCKOPT_QPOLICY_TXQLEN sets the maximum length of the output queue. A zero
value is always interpreted as unbounded queue length. If different from zero,
the interpretation of this parameter depends on the current dequeuing policy
(see above): the "simple" policy will enforce a fixed queue size by returning
EAGAIN, whereas the "prio" policy enforces a fixed queue length by dropping the
lowest-priority packet first. The default value for this parameter is
initialised from /proc/sys/net/dccp/default/tx_qlen.

DCCP_SOCKOPT_SERVICE sets the service. The specification mandates use of
service codes (RFC 4340, sec. 8.1.2); if this socket option is not set,
the socket will fall back to 0 (which means that no meaningful service code
is present). On active sockets this is set before connect(); specifying more
than one code has no effect (all subsequent service codes are ignored). The
case is different for passive sockets, where multiple service codes (up to 32)
can be set before calling bind().

DCCP_SOCKOPT_GET_CUR_MPS is read-only and retrieves the current maximum packet
size (application payload size) in bytes, see RFC 4340, section 14.

DCCP_SOCKOPT_AVAILABLE_CCIDS is also read-only and returns the list of CCIDs
supported by the endpoint. The option value is an array of type uint8_t whose
size is passed as option length. The minimum array size is 4 elements, the
value returned in the optlen argument always reflects the true number of
built-in CCIDs.

DCCP_SOCKOPT_CCID is write-only and sets both the TX and RX CCIDs at the same
time, combining the operation of the next two socket options. This option is
preferable over the latter two, since often applications will use the same
type of CCID for both directions; and mixed use of CCIDs is not currently well
understood. This socket option takes as argument at least one uint8_t value, or
an array of uint8_t values, which must match available CCIDS (see above). CCIDs
must be registered on the socket before calling connect() or listen().

DCCP_SOCKOPT_TX_CCID is read/write. It returns the current CCID (if set) or sets
the preference list for the TX CCID, using the same format as DCCP_SOCKOPT_CCID.
Please note that the getsockopt argument type here is ``int``, not uint8_t.

DCCP_SOCKOPT_RX_CCID is analogous to DCCP_SOCKOPT_TX_CCID, but for the RX CCID.

DCCP_SOCKOPT_SERVER_TIMEWAIT enables the server (listening socket) to hold
timewait state when closing the connection (RFC 4340, 8.3). The usual case is
that the closing server sends a CloseReq, whereupon the client holds timewait
state. When this boolean socket option is on, the server sends a Close instead
and will enter TIMEWAIT. This option must be set after accept() returns.

DCCP_SOCKOPT_SEND_CSCOV and DCCP_SOCKOPT_RECV_CSCOV are used for setting the
partial checksum coverage (RFC 4340, sec. 9.2). The default is that checksums
always cover the entire packet and that only fully covered application data is
accepted by the receiver. Hence, when using this feature on the sender, it must
be enabled at the receiver, too with suitable choice of CsCov.

DCCP_SOCKOPT_SEND_CSCOV sets the sender checksum coverage. Values in the
	range 0..15 are acceptable. The default setting is 0 (full coverage),
	values between 1..15 indicate partial coverage.

DCCP_SOCKOPT_RECV_CSCOV is for the receiver and has a different meaning: it
	sets a threshold, where again values 0..15 are acceptable. The default
	of 0 means that all packets with a partial coverage will be discarded.
	Values in the range 1..15 indicate that packets with minimally such a
	coverage value are also acceptable. The higher the number, the more
	restrictive this setting (see [RFC 4340, sec. 9.2.1]). Partial coverage
	settings are inherited to the child socket after accept().

The following two options apply to CCID 3 exclusively and are getsockopt()-only.
In either case, a TFRC info struct (defined in <linux/tfrc.h>) is returned.

DCCP_SOCKOPT_CCID_RX_INFO
	Returns a ``struct tfrc_rx_info`` in optval; the buffer for optval and
	optlen must be set to at least sizeof(struct tfrc_rx_info).

DCCP_SOCKOPT_CCID_TX_INFO
	Returns a ``struct tfrc_tx_info`` in optval; the buffer for optval and
	optlen must be set to at least sizeof(struct tfrc_tx_info).

On unidirectional connections it is useful to close the unused half-connection
via shutdown (SHUT_WR or SHUT_RD): this will reduce per-packet processing costs.

Sysctl variables
================
Several DCCP default parameters can be managed by the following sysctls
(sysctl net.dccp.default or /proc/sys/net/dccp/default):

request_retries
	The number of active connection initiation retries (the number of
	Requests minus one) before timing out. In addition, it also governs
	the behaviour of the other, passive side: this variable also sets
	the number of times DCCP repeats sending a Response when the initial
	handshake does not progress from RESPOND to OPEN (i.e. when no Ack
	is received after the initial Request).  This value should be greater
	than 0, suggested is less than 10. Analogue of tcp_syn_retries.

retries1
	How often a DCCP Response is retransmitted until the listening DCCP
	side considers its connecting peer dead. Analogue of tcp_retries1.

retries2
	The number of times a general DCCP packet is retransmitted. This has
	importance for retransmitted acknowledgments and feature negotiation,
	data packets are never retransmitted. Analogue of tcp_retries2.

tx_ccid = 2
	Default CCID for the sender-receiver half-connection. Depending on the
	choice of CCID, the Send Ack Vector feature is enabled automatically.

rx_ccid = 2
	Default CCID for the receiver-sender half-connection; see tx_ccid.

seq_window = 100
	The initial sequence window (sec. 7.5.2) of the sender. This influences
	the local ackno validity and the remote seqno validity windows (7.5.1).
	Values in the range Wmin = 32 (RFC 4340, 7.5.2) up to 2^32-1 can be set.

tx_qlen = 5
	The size of the transmit buffer in packets. A value of 0 corresponds
	to an unbounded transmit buffer.

sync_ratelimit = 125 ms
	The timeout between subsequent DCCP-Sync packets sent in response to
	sequence-invalid packets on the same socket (RFC 4340, 7.5.4). The unit
	of this parameter is milliseconds; a value of 0 disables rate-limiting.

IOCTLS
======
FIONREAD
	Works as in udp(7): returns in the ``int`` argument pointer the size of
	the next pending datagram in bytes, or 0 when no datagram is pending.

SIOCOUTQ
	Returns the number of unsent data bytes in the socket send queue as ``int``
	into the buffer specified by the argument pointer.

Other tunables
==============
Per-route rto_min support
	CCID-2 supports the RTAX_RTO_MIN per-route setting for the minimum value
	of the RTO timer. This setting can be modified via the 'rto_min' option
	of iproute2; for example::

		> ip route change 10.0.0.0/24   rto_min 250j dev wlan0
		> ip route add    10.0.0.254/32 rto_min 800j dev wlan0
		> ip route show dev wlan0

	CCID-3 also supports the rto_min setting: it is used to define the lower
	bound for the expiry of the nofeedback timer. This can be useful on LANs
	with very low RTTs (e.g., loopback, Gbit ethernet).

Notes
=====
DCCP does not travel through NAT successfully at present on many boxes. This is
because the checksum covers the pseudo-header as per TCP and UDP. Linux NAT
support for DCCP has been added.


code:
.. SPDX-License-Identifier: GPL-2.0

======================
DCTCP (DataCenter TCP)
======================

DCTCP is an enhancement to the TCP congestion control algorithm for data
center networks and leverages Explicit Congestion Notification (ECN) in
the data center network to provide multi-bit feedback to the end hosts.

To enable it on end hosts::

  sysctl -w net.ipv4.tcp_congestion_control=dctcp
  sysctl -w net.ipv4.tcp_ecn_fallback=0 (optional)

All switches in the data center network running DCTCP must support ECN
marking and be configured for marking when reaching defined switch buffer
thresholds. The default ECN marking threshold heuristic for DCTCP on
switches is 20 packets (30KB) at 1Gbps, and 65 packets (~100KB) at 10Gbps,
but might need further careful tweaking.

For more details, see below documents:

Paper:

The algorithm is further described in detail in the following two
SIGCOMM/SIGMETRICS papers:

 i) Mohammad Alizadeh, Albert Greenberg, David A. Maltz, Jitendra Padhye,
    Parveen Patel, Balaji Prabhakar, Sudipta Sengupta, and Murari Sridharan:

      "Data Center TCP (DCTCP)", Data Center Networks session"

      Proc. ACM SIGCOMM, New Delhi, 2010.

    http://simula.stanford.edu/~alizade/Site/DCTCP_files/dctcp-final.pdf
    http://www.sigcomm.org/ccr/papers/2010/October/1851275.1851192

ii) Mohammad Alizadeh, Adel Javanmard, and Balaji Prabhakar:

      "Analysis of DCTCP: Stability, Convergence, and Fairness"
      Proc. ACM SIGMETRICS, San Jose, 2011.

    http://simula.stanford.edu/~alizade/Site/DCTCP_files/dctcp_analysis-full.pdf

IETF informational draft:

  http://tools.ietf.org/html/draft-bensley-tcpm-dctcp-00

DCTCP site:

  http://simula.stanford.edu/~alizade/Site/DCTCP.html

repo_name: angery/linux


code:
.. SPDX-License-Identifier: GPL-2.0

========================================
The COPS LocalTalk Linux driver (cops.c)
========================================

By Jay Schulist <jschlst@samba.org>

This driver has two modes and they are: Dayna mode and Tangent mode.
Each mode corresponds with the type of card. It has been found
that there are 2 main types of cards and all other cards are
the same and just have different names or only have minor differences
such as more IO ports. As this driver is tested it will
become more clear exactly what cards are supported.

Right now these cards are known to work with the COPS driver. The
LT-200 cards work in a somewhat more limited capacity than the
DL200 cards, which work very well and are in use by many people.

TANGENT driver mode:
	- Tangent ATB-II, Novell NL-1000, Daystar Digital LT-200

DAYNA driver mode:
	- Dayna DL2000/DaynaTalk PC (Half Length), COPS LT-95,
	- Farallon PhoneNET PC III, Farallon PhoneNET PC II

Other cards possibly supported mode unknown though:
	- Dayna DL2000 (Full length)

The COPS driver defaults to using Dayna mode. To change the driver's
mode if you built a driver with dual support use board_type=1 or
board_type=2 for Dayna or Tangent with insmod.

Operation/loading of the driver
===============================

Use modprobe like this:	/sbin/modprobe cops.o (IO #) (IRQ #)
If you do not specify any options the driver will try and use the IO = 0x240,
IRQ = 5. As of right now I would only use IRQ 5 for the card, if autoprobing.

To load multiple COPS driver Localtalk cards you can do one of the following::

	insmod cops io=0x240 irq=5
	insmod -o cops2 cops io=0x260 irq=3

Or in lilo.conf put something like this::

	append="ether=5,0x240,lt0 ether=3,0x260,lt1"

Then bring up the interface with ifconfig. It will look something like this::

  lt0       Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-F7-00-00-00-00-00-00-00-00
	    inet addr:192.168.1.2  Bcast:192.168.1.255  Mask:255.255.255.0
	    UP BROADCAST RUNNING NOARP MULTICAST  MTU:600  Metric:1
	    RX packets:0 errors:0 dropped:0 overruns:0 frame:0
	    TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 coll:0

Netatalk Configuration
======================

You will need to configure atalkd with something like the following to make
it work with the cops.c driver.

* For single LTalk card use::

    dummy -seed -phase 2 -net 2000 -addr 2000.10 -zone "1033"
    lt0 -seed -phase 1 -net 1000 -addr 1000.50 -zone "1033"

* For multiple cards, Ethernet and LocalTalk::

    eth0 -seed -phase 2 -net 3000 -addr 3000.20 -zone "1033"
    lt0 -seed -phase 1 -net 1000 -addr 1000.50 -zone "1033"

* For multiple LocalTalk cards, and an Ethernet card.

* Order seems to matter here, Ethernet last::

    lt0 -seed -phase 1 -net 1000 -addr 1000.10 -zone "LocalTalk1"
    lt1 -seed -phase 1 -net 2000 -addr 2000.20 -zone "LocalTalk2"
    eth0 -seed -phase 2 -net 3000 -addr 3000.30 -zone "EtherTalk"


code:
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

AppleTalk Device Drivers
========================

Contents:

.. toctree::
   :maxdepth: 2

   cops

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
#!/usr/bin/env python
# Copyright 2009 Simon Arlott
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# Usage: cxacru-cf.py < cxacru-cf.bin
# Output: values string suitable for the sysfs adsl_config attribute
#
# Warning: cxacru-cf.bin with MD5 hash cdbac2689969d5ed5d4850f117702110
# contains mis-aligned values which will stop the modem from being able
# to make a connection. If the first and last two bytes are removed then
# the values become valid, but the modulation will be forced to ANSI
# T1.413 only which may not be appropriate.
#
# The original binary format is a packed list of le32 values.

import sys
import struct

i = 0
while True:
	buf = sys.stdin.read(4)

	if len(buf) == 0:
		break
	elif len(buf) != 4:
		sys.stdout.write("\n")
		sys.stderr.write("Error: read {0} not 4 bytes\n".format(len(buf)))
		sys.exit(1)

	if i > 0:
		sys.stdout.write(" ")
	sys.stdout.write("{0:x}={1}".format(i, struct.unpack("<I", buf)[0]))
	i += 1

sys.stdout.write("\n")


code:
.. SPDX-License-Identifier: GPL-2.0

========================
ATM cxacru device driver
========================

Firmware is required for this device: http://accessrunner.sourceforge.net/

While it is capable of managing/maintaining the ADSL connection without the
module loaded, the device will sometimes stop responding after unloading the
driver and it is necessary to unplug/remove power to the device to fix this.

Note: support for cxacru-cf.bin has been removed. It was not loaded correctly
so it had no effect on the device configuration. Fixing it could have stopped
existing devices working when an invalid configuration is supplied.

There is a script cxacru-cf.py to convert an existing file to the sysfs form.

Detected devices will appear as ATM devices named "cxacru". In /sys/class/atm/
these are directories named cxacruN where N is the device number. A symlink
named device points to the USB interface device's directory which contains
several sysfs attribute files for retrieving device statistics:

* adsl_controller_version

* adsl_headend
* adsl_headend_environment

	- Information about the remote headend.

* adsl_config

	- Configuration writing interface.
	- Write parameters in hexadecimal format <index>=<value>,
	  separated by whitespace, e.g.:

		"1=0 a=5"

	- Up to 7 parameters at a time will be sent and the modem will restart
	  the ADSL connection when any value is set. These are logged for future
	  reference.

* downstream_attenuation (dB)
* downstream_bits_per_frame
* downstream_rate (kbps)
* downstream_snr_margin (dB)

	- Downstream stats.

* upstream_attenuation (dB)
* upstream_bits_per_frame
* upstream_rate (kbps)
* upstream_snr_margin (dB)
* transmitter_power (dBm/Hz)

	- Upstream stats.

* downstream_crc_errors
* downstream_fec_errors
* downstream_hec_errors
* upstream_crc_errors
* upstream_fec_errors
* upstream_hec_errors

	- Error counts.

* line_startable

	- Indicates that ADSL support on the device
	  is/can be enabled, see adsl_start.

* line_status

	 - "initialising"
	 - "down"
	 - "attempting to activate"
	 - "training"
	 - "channel analysis"
	 - "exchange"
	 - "waiting"
	 - "up"

	Changes between "down" and "attempting to activate"
	if there is no signal.

* link_status

	 - "not connected"
	 - "connected"
	 - "lost"

* mac_address

* modulation

	 - "" (when not connected)
	 - "ANSI T1.413"
	 - "ITU-T G.992.1 (G.DMT)"
	 - "ITU-T G.992.2 (G.LITE)"

* startup_attempts

	- Count of total attempts to initialise ADSL.

To enable/disable ADSL, the following can be written to the adsl_state file:

	 - "start"
	 - "stop
	 - "restart" (stops, waits 1.5s, then starts)
	 - "poll" (used to resume status polling if it was disabled due to failure)

Changes in adsl/line state are reported via kernel log messages::

	[4942145.150704] ATM dev 0: ADSL state: running
	[4942243.663766] ATM dev 0: ADSL line: down
	[4942249.665075] ATM dev 0: ADSL line: attempting to activate
	[4942253.654954] ATM dev 0: ADSL line: training
	[4942255.666387] ATM dev 0: ADSL line: channel analysis
	[4942259.656262] ATM dev 0: ADSL line: exchange
	[2635357.696901] ATM dev 0: ADSL line: up (8128 kb/s down | 832 kb/s up)


code:
.. 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>.


code:
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

Asynchronous Transfer Mode (ATM) Device Drivers
===============================================

Contents:

.. toctree::
   :maxdepth: 2

   cxacru
   fore200e
   iphase

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
.. SPDX-License-Identifier: GPL-2.0

==================================
ATM (i)Chip IA Linux Driver Source
==================================

			      READ ME FISRT

--------------------------------------------------------------------------------

		     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


code:
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

Cable Modem Device Drivers
==========================

Contents:

.. toctree::
   :maxdepth: 2

   sb1000

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
.. SPDX-License-Identifier: GPL-2.0

===================
SB100 device driver
===================

sb1000 is a module network device driver for the General Instrument (also known
as NextLevel) SURFboard1000 internal cable modem board.  This is an ISA card
which is used by a number of cable TV companies to provide cable modem access.
It's a one-way downstream-only cable modem, meaning that your upstream net link
is provided by your regular phone modem.

This driver was written by Franco Venturi <fventuri@mediaone.net>.  He deserves
a great deal of thanks for this wonderful piece of code!

Needed tools
============

Support for this device is now a part of the standard Linux kernel.  The
driver source code file is drivers/net/sb1000.c.  In addition to this
you will need:

1. The "cmconfig" program.  This is a utility which supplements "ifconfig"
   to configure the cable modem and network interface (usually called "cm0");

2. Several PPP scripts which live in /etc/ppp to make connecting via your
   cable modem easy.

   These utilities can be obtained from:

      http://www.jacksonville.net/~fventuri/

   in Franco's original source code distribution .tar.gz file.  Support for
   the sb1000 driver can be found at:

      - http://web.archive.org/web/%2E/http://home.adelphia.net/~siglercm/sb1000.html
      - http://web.archive.org/web/%2E/http://linuxpower.cx/~cable/

   along with these utilities.

3. The standard isapnp tools.  These are necessary to configure your SB1000
   card at boot time (or afterwards by hand) since it's a PnP card.

   If you don't have these installed as a standard part of your Linux
   distribution, you can find them at:

      http://www.roestock.demon.co.uk/isapnptools/

   or check your Linux distribution binary CD or their web site.  For help with
   isapnp, pnpdump, or /etc/isapnp.conf, go to:

      http://www.roestock.demon.co.uk/isapnptools/isapnpfaq.html

Using the driver
================

To make the SB1000 card work, follow these steps:

1. Run ``make config``, or ``make menuconfig``, or ``make xconfig``, whichever
   you prefer, in the top kernel tree directory to set up your kernel
   configuration.  Make sure to say "Y" to "Prompt for development drivers"
   and to say "M" to the sb1000 driver.  Also say "Y" or "M" to all the standard
   networking questions to get TCP/IP and PPP networking support.

2. **BEFORE** you build the kernel, edit drivers/net/sb1000.c.  Make sure
   to redefine the value of READ_DATA_PORT to match the I/O address used
   by isapnp to access your PnP cards.  This is the value of READPORT in
   /etc/isapnp.conf or given by the output of pnpdump.

3. Build and install the kernel and modules as usual.

4. Boot your new kernel following the usual procedures.

5. Set up to configure the new SB1000 PnP card by capturing the output
   of "pnpdump" to a file and editing this file to set the correct I/O ports,
   IRQ, and DMA settings for all your PnP cards.  Make sure none of the settings
   conflict with one another.  Then test this configuration by running the
   "isapnp" command with your new config file as the input.  Check for
   errors and fix as necessary.  (As an aside, I use I/O ports 0x110 and
   0x310 and IRQ 11 for my SB1000 card and these work well for me.  YMMV.)
   Then save the finished config file as /etc/isapnp.conf for proper
   configuration on subsequent reboots.

6. Download the original file sb1000-1.1.2.tar.gz from Franco's site or one of
   the others referenced above.  As root, unpack it into a temporary directory
   and do a ``make cmconfig`` and then ``install -c cmconfig /usr/local/sbin``.
   Don't do ``make install`` because it expects to find all the utilities built
   and ready for installation, not just cmconfig.

7. As root, copy all the files under the ppp/ subdirectory in Franco's
   tar file into /etc/ppp, being careful not to overwrite any files that are
   already in there.  Then modify ppp@gi-on to set the correct login name,
   phone number, and frequency for the cable modem.  Also edit pap-secrets
   to specify your login name and password and any site-specific information
   you need.

8. Be sure to modify /etc/ppp/firewall to use ipchains instead of
   the older ipfwadm commands from the 2.0.x kernels.  There's a neat utility to
   convert ipfwadm commands to ipchains commands:

	http://users.dhp.com/~whisper/ipfwadm2ipchains/

   You may also wish to modify the firewall script to implement a different
   firewalling scheme.

9. Start the PPP connection via the script /etc/ppp/ppp@gi-on.  You must be
   root to do this.  It's better to use a utility like sudo to execute
   frequently used commands like this with root permissions if possible.  If you
   connect successfully the cable modem interface will come up and you'll see a
   driver message like this at the console::

	 cm0: sb1000 at (0x110,0x310), csn 1, S/N 0x2a0d16d8, IRQ 11.
	 sb1000.c:v1.1.2 6/01/98 (fventuri@mediaone.net)

   The "ifconfig" command should show two new interfaces, ppp0 and cm0.

   The command "cmconfig cm0" will give you information about the cable modem
   interface.

10. Try pinging a site via ``ping -c 5 www.yahoo.com``, for example.  You should
    see packets received.

11. If you can't get site names (like www.yahoo.com) to resolve into
    IP addresses (like 204.71.200.67), be sure your /etc/resolv.conf file
    has no syntax errors and has the right nameserver IP addresses in it.
    If this doesn't help, try something like ``ping -c 5 204.71.200.67`` to
    see if the networking is running but the DNS resolution is where the
    problem lies.

12. If you still have problems, go to the support web sites mentioned above
    and read the information and documentation there.

Common problems
===============

1. Packets go out on the ppp0 interface but don't come back on the cm0
   interface.  It looks like I'm connected but I can't even ping any
   numerical IP addresses.  (This happens predominantly on Debian systems due
   to a default boot-time configuration script.)

Solution
   As root ``echo 0 > /proc/sys/net/ipv4/conf/cm0/rp_filter`` so it
   can share the same IP address as the ppp0 interface.  Note that this
   command should probably be added to the /etc/ppp/cablemodem script
   *right*between* the "/sbin/ifconfig" and "/sbin/cmconfig" commands.
   You may need to do this to /proc/sys/net/ipv4/conf/ppp0/rp_filter as well.
   If you do this to /proc/sys/net/ipv4/conf/default/rp_filter on each reboot
   (in rc.local or some such) then any interfaces can share the same IP
   addresses.

2. I get "unresolved symbol" error messages on executing ``insmod sb1000.o``.

Solution
   You probably have a non-matching kernel source tree and
   /usr/include/linux and /usr/include/asm header files.  Make sure you
   install the correct versions of the header files in these two directories.
   Then rebuild and reinstall the kernel.

3. When isapnp runs it reports an error, and my SB1000 card isn't working.

Solution
   There's a problem with later versions of isapnp using the "(CHECK)"
   option in the lines that allocate the two I/O addresses for the SB1000 card.
   This first popped up on RH 6.0.  Delete "(CHECK)" for the SB1000 I/O addresses.
   Make sure they don't conflict with any other pieces of hardware first!  Then
   rerun isapnp and go from there.

4. I can't execute the /etc/ppp/ppp@gi-on file.

Solution
   As root do ``chmod ug+x /etc/ppp/ppp@gi-on``.

5. The firewall script isn't working (with 2.2.x and higher kernels).

Solution
   Use the ipfwadm2ipchains script referenced above to convert the
   /etc/ppp/firewall script from the deprecated ipfwadm commands to ipchains.

6. I'm getting *tons* of firewall deny messages in the /var/kern.log,
   /var/messages, and/or /var/syslog files, and they're filling up my /var
   partition!!!

Solution
   First, tell your ISP that you're receiving DoS (Denial of Service)
   and/or portscanning (UDP connection attempts) attacks!  Look over the deny
   messages to figure out what the attack is and where it's coming from.  Next,
   edit /etc/ppp/cablemodem and make sure the ",nobroadcast" option is turned on
   to the "cmconfig" command (uncomment that line).  If you're not receiving these
   denied packets on your broadcast interface (IP address xxx.yyy.zzz.255
   typically), then someone is attacking your machine in particular.  Be careful
   out there....

7. Everything seems to work fine but my computer locks up after a while
   (and typically during a lengthy download through the cable modem)!

Solution
   You may need to add a short delay in the driver to 'slow down' the
   SURFboard because your PC might not be able to keep up with the transfer rate
   of the SB1000. To do this, it's probably best to download Franco's
   sb1000-1.1.2.tar.gz archive and build and install sb1000.o manually.  You'll
   want to edit the 'Makefile' and look for the 'SB1000_DELAY'
   define.  Uncomment those 'CFLAGS' lines (and comment out the default ones)
   and try setting the delay to something like 60 microseconds with:
   '-DSB1000_DELAY=60'.  Then do ``make`` and as root ``make install`` and try
   it out.  If it still doesn't work or you like playing with the driver, you may
   try other numbers.  Remember though that the higher the delay, the slower the
   driver (which slows down the rest of the PC too when it is actively
   used). Thanks to Ed Daiga for this tip!

Credits
=======

This README came from Franco Venturi's original README file which is
still supplied with his driver .tar.gz archive.  I and all other sb1000 users
owe Franco a tremendous "Thank you!"  Additional thanks goes to Carl Patten
and Ralph Bonnell who are now managing the Linux SB1000 web site, and to
the SB1000 users who reported and helped debug the common problems listed
above.

					Clemmitt Sigler
					csigler@vt.edu


code:
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)

can327: ELM327 driver for Linux SocketCAN
==========================================

Authors
--------

Max Staudt <max@enpas.org>

Motivation
-----------

This driver aims to lower the initial cost for hackers interested in
working with CAN buses.

CAN adapters are expensive, few, and far between.
ELM327 interfaces are cheap and plentiful.
Let's use ELM327s as CAN adapters.

Introduction
-------------

This driver is an effort to turn abundant ELM327 based OBD interfaces
into full fledged (as far as possible) CAN interfaces.

Since the ELM327 was never meant to be a stand alone CAN controller,
the driver has to switch between its modes as quickly as possible in
order to fake full-duplex operation.

As such, can327 is a best effort driver. However, this is more than
enough to implement simple request-response protocols (such as OBD II),
and to monitor broadcast messages on a bus (such as in a vehicle).

Most ELM327s come as nondescript serial devices, attached via USB or
Bluetooth. The driver cannot recognize them by itself, and as such it
is up to the user to attach it in form of a TTY line discipline
(similar to PPP, SLIP, slcan, ...).

This driver is meant for ELM327 versions 1.4b and up, see below for
known limitations in older controllers and clones.

Data sheet
-----------

The official data sheets can be found at ELM electronics' home page:

  https://www.elmelectronics.com/

How to attach the line discipline
----------------------------------

Every ELM327 chip is factory programmed to operate at a serial setting
of 38400 baud/s, 8 data bits, no parity, 1 stopbit.

If you have kept this default configuration, the line discipline can
be attached on a command prompt as follows::

    sudo ldattach \
           --debug \
           --speed 38400 \
           --eightbits \
           --noparity \
           --onestopbit \
           --iflag -ICRNL,INLCR,-IXOFF \
           30 \
           /dev/ttyUSB0

To change the ELM327's serial settings, please refer to its data
sheet. This needs to be done before attaching the line discipline.

Once the ldisc is attached, the CAN interface starts out unconfigured.
Set the speed before starting it::

    # The interface needs to be down to change parameters
    sudo ip link set can0 down
    sudo ip link set can0 type can bitrate 500000
    sudo ip link set can0 up

500000 bit/s is a common rate for OBD-II diagnostics.
If you're connecting straight to a car's OBD port, this is the speed
that most cars (but not all!) expect.

After this, you can set out as usual with candump, cansniffer, etc.

How to check the controller version
------------------------------------

Use a terminal program to attach to the controller.

After issuing the "``AT WS``" command, the controller will respond with
its version::

    >AT WS

    ELM327 v1.4b

    >

Note that clones may claim to be any version they like.
It is not indicative of their actual feature set.

Communication example
----------------------

This is a short and incomplete introduction on how to talk to an ELM327.
It is here to guide understanding of the controller's and the driver's
limitation (listed below) as well as manual testing.

The ELM327 has two modes:

- Command mode
- Reception mode

In command mode, it expects one command per line, terminated by CR.
By default, the prompt is a "``>``", after which a command can be
entered::

    >ATE1
    OK
    >

The init script in the driver switches off several configuration options
that are only meaningful in the original OBD scenario the chip is meant
for, and are actually a hindrance for can327.

When a command is not recognized, such as by an older version of the
ELM327, a question mark is printed as a response instead of OK::

    >ATUNKNOWN
    ?
    >

At present, can327 does not evaluate this response. See the section
below on known limitations for details.

When a CAN frame is to be sent, the target address is configured, after
which the frame is sent as a command that consists of the data's hex
dump::

    >ATSH123
    OK
    >DEADBEEF12345678
    OK
    >

The above interaction sends the SFF frame "``DE AD BE EF 12 34 56 78``"
with (11 bit) CAN ID ``0x123``.
For this to function, the controller must be configured for SFF sending
mode (using "``AT PB``", see code or datasheet).

Once a frame has been sent and wait-for-reply mode is on (``ATR1``,
configured on ``listen-only=off``), or when the reply timeout expires
and the driver sets the controller into monitoring mode (``ATMA``),
the ELM327 will send one line for each received CAN frame, consisting
of CAN ID, DLC, and data::

    123 8 DEADBEEF12345678

For EFF (29 bit) CAN frames, the address format is slightly different,
which can327 uses to tell the two apart::

    12 34 56 78 8 DEADBEEF12345678

The ELM327 will receive both SFF and EFF frames - the current CAN
config (``ATPB``) does not matter.

If the ELM327's internal UART sending buffer runs full, it will abort
the monitoring mode, print "BUFFER FULL" and drop back into command
mode. Note that in this case, unlike with other error messages, the
error message may appear on the same line as the last (usually
incomplete) data frame::

    12 34 56 78 8 DEADBEEF123 BUFFER FULL

Known limitations of the controller
------------------------------------

- Clone devices ("v1.5" and others)

  Sending RTR frames is not supported and will be dropped silently.

  Receiving RTR with DLC 8 will appear to be a regular frame with
  the last received frame's DLC and payload.

  "``AT CSM``" (CAN Silent Monitoring, i.e. don't send CAN ACKs) is
  not supported, and is hard coded to ON. Thus, frames are not ACKed
  while listening: "``AT MA``" (Monitor All) will always be "silent".
  However, immediately after sending a frame, the ELM327 will be in
  "receive reply" mode, in which it *does* ACK any received frames.
  Once the bus goes silent, or an error occurs (such as BUFFER FULL),
  or the receive reply timeout runs out, the ELM327 will end reply
  reception mode on its own and can327 will fall back to "``AT MA``"
  in order to keep monitoring the bus.

  Other limitations may apply, depending on the clone and the quality
  of its firmware.

- All versions

  No full duplex operation is supported. The driver will switch
  between input/output mode as quickly as possible.

  The length of outgoing RTR frames cannot be set. In fact, some
  clones (tested with one identifying as "``v1.5``") are unable to
  send RTR frames at all.

  We don't have a way to get real-time notifications on CAN errors.
  While there is a command (``AT CS``) to retrieve some basic stats,
  we don't poll it as it would force us to interrupt reception mode.

- Versions prior to 1.4b

  These versions do not send CAN ACKs when in monitoring mode (AT MA).
  However, they do send ACKs while waiting for a reply immediately
  after sending a frame. The driver maximizes this time to make the
  controller as useful as possible.

  Starting with version 1.4b, the ELM327 supports the "``AT CSM``"
  command, and the "listen-only" CAN option will take effect.

- Versions prior to 1.4

  These chips do not support the "``AT PB``" command, and thus cannot
  change bitrate or SFF/EFF mode on-the-fly. This will have to be
  programmed by the user before attaching the line discipline. See the
  data sheet for details.

- Versions prior to 1.3

  These chips cannot be used at all with can327. They do not support
  the "``AT D1``" command, which is necessary to avoid parsing conflicts
  on incoming data, as well as distinction of RTR frame lengths.

  Specifically, this allows for easy distinction of SFF and EFF
  frames, and to check whether frames are complete. While it is possible
  to deduce the type and length from the length of the line the ELM327
  sends us, this method fails when the ELM327's UART output buffer
  overruns. It may abort sending in the middle of the line, which will
  then be mistaken for something else.

Known limitations of the driver
--------------------------------

- No 8/7 timing.

  ELM327 can only set CAN bitrates that are of the form 500000/n, where
  n is an integer divisor.
  However there is an exception: With a separate flag, it may set the
  speed to be 8/7 of the speed indicated by the divisor.
  This mode is not currently implemented.

- No evaluation of command responses.

  The ELM327 will reply with OK when a command is understood, and with ?
  when it is not. The driver does not currently check this, and simply
  assumes that the chip understands every command.
  The driver is built such that functionality degrades gracefully
  nevertheless. See the section on known limitations of the controller.

- No use of hardware CAN ID filtering

  An ELM327's UART sending buffer will easily overflow on heavy CAN bus
  load, resulting in the "``BUFFER FULL``" message. Using the hardware
  filters available through "``AT CF xxx``" and "``AT CM xxx``" would be
  helpful here, however SocketCAN does not currently provide a facility
  to make use of such hardware features.

Rationale behind the chosen configuration
------------------------------------------

``AT E1``
  Echo on

  We need this to be able to get a prompt reliably.

``AT S1``
  Spaces on

  We need this to distinguish 11/29 bit CAN addresses received.

  Note:
  We can usually do this using the line length (odd/even),
  but this fails if the line is not transmitted fully to
  the host (BUFFER FULL).

``AT D1``
  DLC on

  We need this to tell the "length" of RTR frames.

A note on CAN bus termination
------------------------------

Your adapter may have resistors soldered in which are meant to terminate
the bus. This is correct when it is plugged into a OBD-II socket, but
not helpful when trying to tap into the middle of an existing CAN bus.

If communications don't work with the adapter connected, check for the
termination resistors on its PCB and try removing them.


code:
.. SPDX-License-Identifier: GPL-2.0-or-later

CTU CAN FD Driver
=================

Author: Martin Jerabek <martin.jerabek01@gmail.com>

About CTU CAN FD IP Core
------------------------

`CTU CAN FD <https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core>`_
is an open source soft core written in VHDL.
It originated in 2015 as Ondrej Ille's project
at the `Department of Measurement <https://meas.fel.cvut.cz/>`_
of `FEE <http://www.fel.cvut.cz/en/>`_ at `CTU <https://www.cvut.cz/en>`_.

The SocketCAN driver for Xilinx Zynq SoC based MicroZed board
`Vivado integration <https://gitlab.fel.cvut.cz/canbus/zynq/zynq-can-sja1000-top>`_
and Intel Cyclone V 5CSEMA4U23C6 based DE0-Nano-SoC Terasic board
`QSys integration <https://gitlab.fel.cvut.cz/canbus/intel-soc-ctucanfd>`_
has been developed as well as support for
`PCIe integration <https://gitlab.fel.cvut.cz/canbus/pcie-ctucanfd>`_ of the core.

In the case of Zynq, the core is connected via the APB system bus, which does
not have enumeration support, and the device must be specified in Device Tree.
This kind of devices is called platform device in the kernel and is
handled by a platform device driver.

The basic functional model of the CTU CAN FD peripheral has been
accepted into QEMU mainline. See QEMU `CAN emulation support <https://www.qemu.org/docs/master/system/devices/can.html>`_
for CAN FD buses, host connection and CTU CAN FD core emulation. The development
version of emulation support can be cloned from ctu-canfd branch of QEMU local
development `repository <https://gitlab.fel.cvut.cz/canbus/qemu-canbus>`_.

About SocketCAN
---------------

SocketCAN is a standard common interface for CAN devices in the Linux
kernel. As the name suggests, the bus is accessed via sockets, similarly
to common network devices. The reasoning behind this is in depth
described in `Linux SocketCAN <https://www.kernel.org/doc/html/latest/networking/can.html>`_.
In short, it offers a
natural way to implement and work with higher layer protocols over CAN,
in the same way as, e.g., UDP/IP over Ethernet.

Device probe
~~~~~~~~~~~~

Before going into detail about the structure of a CAN bus device driver,
let's reiterate how the kernel gets to know about the device at all.
Some buses, like PCI or PCIe, support device enumeration. That is, when
the system boots, it discovers all the devices on the bus and reads
their configuration. The kernel identifies the device via its vendor ID
and device ID, and if there is a driver registered for this identifier
combination, its probe method is invoked to populate the driver's
instance for the given hardware. A similar situation goes with USB, only
it allows for device hot-plug.

The situation is different for peripherals which are directly embedded
in the SoC and connected to an internal system bus (AXI, APB, Avalon,
and others). These buses do not support enumeration, and thus the kernel
has to learn about the devices from elsewhere. This is exactly what the
Device Tree was made for.

Device tree
~~~~~~~~~~~

An entry in device tree states that a device exists in the system, how
it is reachable (on which bus it resides) and its configuration –
registers address, interrupts and so on. An example of such a device
tree is given in .

::

           / {
               /* ... */
               amba: amba {
                   #address-cells = <1>;
                   #size-cells = <1>;
                   compatible = "simple-bus";

                   CTU_CAN_FD_0: CTU_CAN_FD@43c30000 {
                       compatible = "ctu,ctucanfd";
                       interrupt-parent = <&intc>;
                       interrupts = <0 30 4>;
                       clocks = <&clkc 15>;
                       reg = <0x43c30000 0x10000>;
                   };
               };
           };

.. _sec:socketcan:drv:

Driver structure
~~~~~~~~~~~~~~~~

The driver can be divided into two parts – platform-dependent device
discovery and set up, and platform-independent CAN network device
implementation.

.. _sec:socketcan:platdev:

Platform device driver
^^^^^^^^^^^^^^^^^^^^^^

In the case of Zynq, the core is connected via the AXI system bus, which
does not have enumeration support, and the device must be specified in
Device Tree. This kind of devices is called *platform device* in the
kernel and is handled by a *platform device driver*\  [1]_.

A platform device driver provides the following things:

-  A *probe* function

-  A *remove* function

-  A table of *compatible* devices that the driver can handle

The *probe* function is called exactly once when the device appears (or
the driver is loaded, whichever happens later). If there are more
devices handled by the same driver, the *probe* function is called for
each one of them. Its role is to allocate and initialize resources
required for handling the device, as well as set up low-level functions
for the platform-independent layer, e.g., *read_reg* and *write_reg*.
After that, the driver registers the device to a higher layer, in our
case as a *network device*.

The *remove* function is called when the device disappears, or the
driver is about to be unloaded. It serves to free the resources
allocated in *probe* and to unregister the device from higher layers.

Finally, the table of *compatible* devices states which devices the
driver can handle. The Device Tree entry ``compatible`` is matched
against the tables of all *platform drivers*.

.. code:: c

           /* Match table for OF platform binding */
           static const struct of_device_id ctucan_of_match[] = {
               { .compatible = "ctu,canfd-2", },
               { .compatible = "ctu,ctucanfd", },
               { /* end of list */ },
           };
           MODULE_DEVICE_TABLE(of, ctucan_of_match);

           static int ctucan_probe(struct platform_device *pdev);
           static int ctucan_remove(struct platform_device *pdev);

           static struct platform_driver ctucanfd_driver = {
               .probe  = ctucan_probe,
               .remove = ctucan_remove,
               .driver = {
                   .name = DRIVER_NAME,
                   .of_match_table = ctucan_of_match,
               },
           };
           module_platform_driver(ctucanfd_driver);

.. _sec:socketcan:netdev:

Network device driver
^^^^^^^^^^^^^^^^^^^^^

Each network device must support at least these operations:

-  Bring the device up: ``ndo_open``

-  Bring the device down: ``ndo_close``

-  Submit TX frames to the device: ``ndo_start_xmit``

-  Signal TX completion and errors to the network subsystem: ISR

-  Submit RX frames to the network subsystem: ISR and NAPI

There are two possible event sources: the device and the network
subsystem. Device events are usually signaled via an interrupt, handled
in an Interrupt Service Routine (ISR). Handlers for the events
originating in the network subsystem are then specified in
``struct net_device_ops``.

When the device is brought up, e.g., by calling ``ip link set can0 up``,
the driver’s function ``ndo_open`` is called. It should validate the
interface configuration and configure and enable the device. The
analogous opposite is ``ndo_close``, called when the device is being
brought down, be it explicitly or implicitly.

When the system should transmit a frame, it does so by calling
``ndo_start_xmit``, which enqueues the frame into the device. If the
device HW queue (FIFO, mailboxes or whatever the implementation is)
becomes full, the ``ndo_start_xmit`` implementation informs the network
subsystem that it should stop the TX queue (via ``netif_stop_queue``).
It is then re-enabled later in ISR when the device has some space
available again and is able to enqueue another frame.

All the device events are handled in ISR, namely:

#. **TX completion**. When the device successfully finishes transmitting
   a frame, the frame is echoed locally. On error, an informative error
   frame [2]_ is sent to the network subsystem instead. In both cases,
   the software TX queue is resumed so that more frames may be sent.

#. **Error condition**. If something goes wrong (e.g., the device goes
   bus-off or RX overrun happens), error counters are updated, and
   informative error frames are enqueued to SW RX queue.

#. **RX buffer not empty**. In this case, read the RX frames and enqueue
   them to SW RX queue. Usually NAPI is used as a middle layer (see ).

.. _sec:socketcan:napi:

NAPI
~~~~

The frequency of incoming frames can be high and the overhead to invoke
the interrupt service routine for each frame can cause significant
system load. There are multiple mechanisms in the Linux kernel to deal
with this situation. They evolved over the years of Linux kernel
development and enhancements. For network devices, the current standard
is NAPI – *the New API*. It is similar to classical top-half/bottom-half
interrupt handling in that it only acknowledges the interrupt in the ISR
and signals that the rest of the processing should be done in softirq
context. On top of that, it offers the possibility to *poll* for new
frames for a while. This has a potential to avoid the costly round of
enabling interrupts, handling an incoming IRQ in ISR, re-enabling the
softirq and switching context back to softirq.

More detailed documentation of NAPI may be found on the pages of Linux
Foundation `<https://wiki.linuxfoundation.org/networking/napi>`_.

Integrating the core to Xilinx Zynq
-----------------------------------

The core interfaces a simple subset of the Avalon
(search for Intel **Avalon Interface Specifications**)
bus as it was originally used on
Alterra FPGA chips, yet Xilinx natively interfaces with AXI
(search for ARM **AMBA AXI and ACE Protocol Specification AXI3,
AXI4, and AXI4-Lite, ACE and ACE-Lite**).
The most obvious solution would be to use
an Avalon/AXI bridge or implement some simple conversion entity.
However, the core’s interface is half-duplex with no handshake
signaling, whereas AXI is full duplex with two-way signaling. Moreover,
even AXI-Lite slave interface is quite resource-intensive, and the
flexibility and speed of AXI are not required for a CAN core.

Thus a much simpler bus was chosen – APB (Advanced Peripheral Bus)
(search for ARM **AMBA APB Protocol Specification**).
APB-AXI bridge is directly available in
Xilinx Vivado, and the interface adaptor entity is just a few simple
combinatorial assignments.

Finally, to be able to include the core in a block diagram as a custom
IP, the core, together with the APB interface, has been packaged as a
Vivado component.

CTU CAN FD Driver design
------------------------

The general structure of a CAN device driver has already been examined
in . The next paragraphs provide a more detailed description of the CTU
CAN FD core driver in particular.

Low-level driver
~~~~~~~~~~~~~~~~

The core is not intended to be used solely with SocketCAN, and thus it
is desirable to have an OS-independent low-level driver. This low-level
driver can then be used in implementations of OS driver or directly
either on bare metal or in a user-space application. Another advantage
is that if the hardware slightly changes, only the low-level driver
needs to be modified.

The code [3]_ is in part automatically generated and in part written
manually by the core author, with contributions of the thesis’ author.
The low-level driver supports operations such as: set bit timing, set
controller mode, enable/disable, read RX frame, write TX frame, and so
on.

Configuring bit timing
~~~~~~~~~~~~~~~~~~~~~~

On CAN, each bit is divided into four segments: SYNC, PROP, PHASE1, and
PHASE2. Their duration is expressed in multiples of a Time Quantum
(details in `CAN Specification, Version 2.0 <http://esd.cs.ucr.edu/webres/can20.pdf>`_, chapter 8).
When configuring
bitrate, the durations of all the segments (and time quantum) must be
computed from the bitrate and Sample Point. This is performed
independently for both the Nominal bitrate and Data bitrate for CAN FD.

SocketCAN is fairly flexible and offers either highly customized
configuration by setting all the segment durations manually, or a
convenient configuration by setting just the bitrate and sample point
(and even that is chosen automatically per Bosch recommendation if not
specified). However, each CAN controller may have different base clock
frequency and different width of segment duration registers. The
algorithm thus needs the minimum and maximum values for the durations
(and clock prescaler) and tries to optimize the numbers to fit both the
constraints and the requested parameters.

.. code:: c

           struct can_bittiming_const {
               char name[16];      /* Name of the CAN controller hardware */
               __u32 tseg1_min;    /* Time segment 1 = prop_seg + phase_seg1 */
               __u32 tseg1_max;
               __u32 tseg2_min;    /* Time segment 2 = phase_seg2 */
               __u32 tseg2_max;
               __u32 sjw_max;      /* Synchronisation jump width */
               __u32 brp_min;      /* Bit-rate prescaler */
               __u32 brp_max;
               __u32 brp_inc;
           };

[lst:can_bittiming_const]

A curious reader will notice that the durations of the segments PROP_SEG
and PHASE_SEG1 are not determined separately but rather combined and
then, by default, the resulting TSEG1 is evenly divided between PROP_SEG
and PHASE_SEG1. In practice, this has virtually no consequences as the
sample point is between PHASE_SEG1 and PHASE_SEG2. In CTU CAN FD,
however, the duration registers ``PROP`` and ``PH1`` have different
widths (6 and 7 bits, respectively), so the auto-computed values might
overflow the shorter register and must thus be redistributed among the
two [4]_.

Handling RX
~~~~~~~~~~~

Frame reception is handled in NAPI queue, which is enabled from ISR when
the RXNE (RX FIFO Not Empty) bit is set. Frames are read one by one
until either no frame is left in the RX FIFO or the maximum work quota
has been reached for the NAPI poll run (see ). Each frame is then passed
to the network interface RX queue.

An incoming frame may be either a CAN 2.0 frame or a CAN FD frame. The
way to distinguish between these two in the kernel is to allocate either
``struct can_frame`` or ``struct canfd_frame``, the two having different
sizes. In the controller, the information about the frame type is stored
in the first word of RX FIFO.

This brings us a chicken-egg problem: we want to allocate the ``skb``
for the frame, and only if it succeeds, fetch the frame from FIFO;
otherwise keep it there for later. But to be able to allocate the
correct ``skb``, we have to fetch the first work of FIFO. There are
several possible solutions:

#. Read the word, then allocate. If it fails, discard the rest of the
   frame. When the system is low on memory, the situation is bad anyway.

#. Always allocate ``skb`` big enough for an FD frame beforehand. Then
   tweak the ``skb`` internals to look like it has been allocated for
   the smaller CAN 2.0 frame.

#. Add option to peek into the FIFO instead of consuming the word.

#. If the allocation fails, store the read word into driver’s data. On
   the next try, use the stored word instead of reading it again.

Option 1 is simple enough, but not very satisfying if we could do
better. Option 2 is not acceptable, as it would require modifying the
private state of an integral kernel structure. The slightly higher
memory consumption is just a virtual cherry on top of the “cake”. Option
3 requires non-trivial HW changes and is not ideal from the HW point of
view.

Option 4 seems like a good compromise, with its disadvantage being that
a partial frame may stay in the FIFO for a prolonged time. Nonetheless,
there may be just one owner of the RX FIFO, and thus no one else should
see the partial frame (disregarding some exotic debugging scenarios).
Basides, the driver resets the core on its initialization, so the
partial frame cannot be “adopted” either. In the end, option 4 was
selected [5]_.

.. _subsec:ctucanfd:rxtimestamp:

Timestamping RX frames
^^^^^^^^^^^^^^^^^^^^^^

The CTU CAN FD core reports the exact timestamp when the frame has been
received. The timestamp is by default captured at the sample point of
the last bit of EOF but is configurable to be captured at the SOF bit.
The timestamp source is external to the core and may be up to 64 bits
wide. At the time of writing, passing the timestamp from kernel to
userspace is not yet implemented, but is planned in the future.

Handling TX
~~~~~~~~~~~

The CTU CAN FD core has 4 independent TX buffers, each with its own
state and priority. When the core wants to transmit, a TX buffer in
Ready state with the highest priority is selected.

The priorities are 3bit numbers in register TX_PRIORITY
(nibble-aligned). This should be flexible enough for most use cases.
SocketCAN, however, supports only one FIFO queue for outgoing
frames [6]_. The buffer priorities may be used to simulate the FIFO
behavior by assigning each buffer a distinct priority and *rotating* the
priorities after a frame transmission is completed.

In addition to priority rotation, the SW must maintain head and tail
pointers into the FIFO formed by the TX buffers to be able to determine
which buffer should be used for next frame (``txb_head``) and which
should be the first completed one (``txb_tail``). The actual buffer
indices are (obviously) modulo 4 (number of TX buffers), but the
pointers must be at least one bit wider to be able to distinguish
between FIFO full and FIFO empty – in this situation,
:math:`txb\_head \equiv txb\_tail\ (\textrm{mod}\ 4)`. An example of how
the FIFO is maintained, together with priority rotation, is depicted in

|

+------+---+---+---+---+
| TXB# | 0 | 1 | 2 | 3 |
+======+===+===+===+===+
| Seq  | A | B | C |   |
+------+---+---+---+---+
| Prio | 7 | 6 | 5 | 4 |
+------+---+---+---+---+
|      |   | T |   | H |
+------+---+---+---+---+

|

+------+---+---+---+---+
| TXB# | 0 | 1 | 2 | 3 |
+======+===+===+===+===+
| Seq  |   | B | C |   |
+------+---+---+---+---+
| Prio | 4 | 7 | 6 | 5 |
+------+---+---+---+---+
|      |   | T |   | H |
+------+---+---+---+---+

|

+------+---+---+---+---+----+
| TXB# | 0 | 1 | 2 | 3 | 0’ |
+======+===+===+===+===+====+
| Seq  | E | B | C | D |    |
+------+---+---+---+---+----+
| Prio | 4 | 7 | 6 | 5 |    |
+------+---+---+---+---+----+
|      |   | T |   |   | H  |
+------+---+---+---+---+----+

|

.. kernel-figure:: fsm_txt_buffer_user.svg

   TX Buffer states with possible transitions

.. _subsec:ctucanfd:txtimestamp:

Timestamping TX frames
^^^^^^^^^^^^^^^^^^^^^^

When submitting a frame to a TX buffer, one may specify the timestamp at
which the frame should be transmitted. The frame transmission may start
later, but not sooner. Note that the timestamp does not participate in
buffer prioritization – that is decided solely by the mechanism
described above.

Support for time-based packet transmission was recently merged to Linux
v4.19 `Time-based packet transmission <https://lwn.net/Articles/748879/>`_,
but it remains yet to be researched
whether this functionality will be practical for CAN.

Also similarly to retrieving the timestamp of RX frames, the core
supports retrieving the timestamp of TX frames – that is the time when
the frame was successfully delivered. The particulars are very similar
to timestamping RX frames and are described in .

Handling RX buffer overrun
~~~~~~~~~~~~~~~~~~~~~~~~~~

When a received frame does no more fit into the hardware RX FIFO in its
entirety, RX FIFO overrun flag (STATUS[DOR]) is set and Data Overrun
Interrupt (DOI) is triggered. When servicing the interrupt, care must be
taken first to clear the DOR flag (via COMMAND[CDO]) and after that
clear the DOI interrupt flag. Otherwise, the interrupt would be
immediately [7]_ rearmed.

**Note**: During development, it was discussed whether the internal HW
pipelining cannot disrupt this clear sequence and whether an additional
dummy cycle is necessary between clearing the flag and the interrupt. On
the Avalon interface, it indeed proved to be the case, but APB being
safe because it uses 2-cycle transactions. Essentially, the DOR flag
would be cleared, but DOI register’s Preset input would still be high
the cycle when the DOI clear request would also be applied (by setting
the register’s Reset input high). As Set had higher priority than Reset,
the DOI flag would not be reset. This has been already fixed by swapping
the Set/Reset priority (see issue #187).

Reporting Error Passive and Bus Off conditions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

It may be desirable to report when the node reaches *Error Passive*,
*Error Warning*, and *Bus Off* conditions. The driver is notified about
error state change by an interrupt (EPI, EWLI), and then proceeds to
determine the core’s error state by reading its error counters.

There is, however, a slight race condition here – there is a delay
between the time when the state transition occurs (and the interrupt is
triggered) and when the error counters are read. When EPI is received,
the node may be either *Error Passive* or *Bus Off*. If the node goes
*Bus Off*, it obviously remains in the state until it is reset.
Otherwise, the node is *or was* *Error Passive*. However, it may happen
that the read state is *Error Warning* or even *Error Active*. It may be
unclear whether and what exactly to report in that case, but I
personally entertain the idea that the past error condition should still
be reported. Similarly, when EWLI is received but the state is later
detected to be *Error Passive*, *Error Passive* should be reported.

CTU CAN FD Driver Sources Reference
-----------------------------------

.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd.h
   :internal:

.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd_base.c
   :internal:

.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd_pci.c
   :internal:

.. kernel-doc:: drivers/net/can/ctucanfd/ctucanfd_platform.c
   :internal:

CTU CAN FD IP Core and Driver Development Acknowledgment
---------------------------------------------------------

* Odrej Ille <ondrej.ille@gmail.com>

  * started the project as student at Department of Measurement, FEE, CTU
  * invested great amount of personal time and enthusiasm to the project over years
  * worked on more funded tasks

* `Department of Measurement <https://meas.fel.cvut.cz/>`_,
  `Faculty of Electrical Engineering <http://www.fel.cvut.cz/en/>`_,
  `Czech Technical University <https://www.cvut.cz/en>`_

  * is the main investor into the project over many years
  * uses project in their CAN/CAN FD diagnostics framework for `Skoda Auto <https://www.skoda-auto.cz/>`_

* `Digiteq Automotive <https://www.digiteqautomotive.com/en>`_

  * funding of the project CAN FD Open Cores Support Linux Kernel Based Systems
  * negotiated and paid CTU to allow public access to the project
  * provided additional funding of the work

* `Department of Control Engineering <https://control.fel.cvut.cz/en>`_,
  `Faculty of Electrical Engineering <http://www.fel.cvut.cz/en/>`_,
  `Czech Technical University <https://www.cvut.cz/en>`_

  * solving the project CAN FD Open Cores Support Linux Kernel Based Systems
  * providing GitLab management
  * virtual servers and computational power for continuous integration
  * providing hardware for HIL continuous integration tests

* `PiKRON Ltd. <http://pikron.com/>`_

  * minor funding to initiate preparation of the project open-sourcing

* Petr Porazil <porazil@pikron.com>

  * design of PCIe transceiver addon board and assembly of boards
  * design and assembly of MZ_APO baseboard for MicroZed/Zynq based system

* Martin Jerabek <martin.jerabek01@gmail.com>

  * Linux driver development
  * continuous integration platform architect and GHDL updates
  * theses `Open-source and Open-hardware CAN FD Protocol Support <https://dspace.cvut.cz/bitstream/handle/10467/80366/F3-DP-2019-Jerabek-Martin-Jerabek-thesis-2019-canfd.pdf>`_

* Jiri Novak <jnovak@fel.cvut.cz>

  * project initiation, management and use at Department of Measurement, FEE, CTU

* Pavel Pisa <pisa@cmp.felk.cvut.cz>

  * initiate open-sourcing, project coordination, management at Department of Control Engineering, FEE, CTU

* Jaroslav Beran<jara.beran@gmail.com>

 * system integration for Intel SoC, core and driver testing and updates

* Carsten Emde (`OSADL <https://www.osadl.org/>`_)

 * provided OSADL expertise to discuss IP core licensing
 * pointed to possible deadlock for LGPL and CAN bus possible patent case which lead to relicense IP core design to BSD like license

* Reiner Zitzmann and Holger Zeltwanger (`CAN in Automation <https://www.can-cia.org/>`_)

 * provided suggestions and help to inform community about the project and invited us to events focused on CAN bus future development directions

* Jan Charvat

 * implemented CTU CAN FD functional model for QEMU which has been integrated into QEMU mainline (`docs/system/devices/can.rst <https://www.qemu.org/docs/master/system/devices/can.html>`_)
 * Bachelor theses Model of CAN FD Communication Controller for QEMU Emulator

Notes
-----

.. [1]
   Other buses have their own specific driver interface to set up the
   device.

.. [2]
   Not to be mistaken with CAN Error Frame. This is a ``can_frame`` with
   ``CAN_ERR_FLAG`` set and some error info in its ``data`` field.

.. [3]
   Available in CTU CAN FD repository
   `<https://gitlab.fel.cvut.cz/canbus/ctucanfd_ip_core>`_

.. [4]
   As is done in the low-level driver functions
   ``ctucan_hw_set_nom_bittiming`` and
   ``ctucan_hw_set_data_bittiming``.

.. [5]
   At the time of writing this thesis, option 1 is still being used and
   the modification is queued in gitlab issue #222

.. [6]
   Strictly speaking, multiple CAN TX queues are supported since v4.19
   `can: enable multi-queue for SocketCAN devices <https://lore.kernel.org/patchwork/patch/913526/>`_ but no mainline driver is using
   them yet.

.. [7]
   Or rather in the next clock cycle


code:
.. SPDX-License-Identifier: GPL-2.0+

=============================
Flexcan CAN Controller driver
=============================

Authors: Marc Kleine-Budde <mkl@pengutronix.de>,
Dario Binacchi <dario.binacchi@amarulasolutions.com>

On/off RTR frames reception
===========================

For most flexcan IP cores the driver supports 2 RX modes:

- FIFO
- mailbox

The older flexcan cores (integrated into the i.MX25, i.MX28, i.MX35
and i.MX53 SOCs) only receive RTR frames if the controller is
configured for RX-FIFO mode.

The RX FIFO mode uses a hardware FIFO with a depth of 6 CAN frames,
while the mailbox mode uses a software FIFO with a depth of up to 62
CAN frames. With the help of the bigger buffer, the mailbox mode
performs better under high system load situations.

As reception of RTR frames is part of the CAN standard, all flexcan
cores come up in a mode where RTR reception is possible.

With the "rx-rtr" private flag the ability to receive RTR frames can
be waived at the expense of losing the ability to receive RTR
messages. This trade off is beneficial in certain use cases.

"rx-rtr" on
  Receive RTR frames. (default)

  The CAN controller can and will receive RTR frames.

  On some IP cores the controller cannot receive RTR frames in the
  more performant "RX mailbox" mode and will use "RX FIFO" mode
  instead.

"rx-rtr" off

  Waive ability to receive RTR frames. (not supported on all IP cores)

  This mode activates the "RX mailbox mode" for better performance, on
  some IP cores RTR frames cannot be received anymore.

The setting can only be changed if the interface is down::

    ip link set dev can0 down
    ethtool --set-priv-flags can0 rx-rtr {off|on}
    ip link set dev can0 up


code:
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

Controller Area Network (CAN) Device Drivers
============================================

Device drivers for CAN devices.

Contents:

.. toctree::
   :maxdepth: 2

   can327
   ctu/ctucanfd-driver
   freescale/flexcan

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
.. SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)

Cellular Modem Device Drivers
=============================

Contents:

.. toctree::
   :maxdepth: 2

   qualcomm/rmnet

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
.. SPDX-License-Identifier: GPL-2.0

============
Rmnet Driver
============

1. Introduction
===============

rmnet driver is used for supporting the Multiplexing and aggregation
Protocol (MAP). This protocol is used by all recent chipsets using Qualcomm
Technologies, Inc. modems.

This driver can be used to register onto any physical network device in
IP mode. Physical transports include USB, HSIC, PCIe and IP accelerator.

Multiplexing allows for creation of logical netdevices (rmnet devices) to
handle multiple private data networks (PDN) like a default internet, tethering,
multimedia messaging service (MMS) or IP media subsystem (IMS). Hardware sends
packets with MAP headers to rmnet. Based on the multiplexer id, rmnet
routes to the appropriate PDN after removing the MAP header.

Aggregation is required to achieve high data rates. This involves hardware
sending aggregated bunch of MAP frames. rmnet driver will de-aggregate
these MAP frames and send them to appropriate PDN's.

2. Packet format
================

a. MAP packet v1 (data / control)

MAP header fields are in big endian format.

Packet format::

  Bit             0             1           2-7      8-15           16-31
  Function   Command / Data   Reserved     Pad   Multiplexer ID    Payload length

  Bit            32-x
  Function      Raw bytes

Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
or data packet. Command packet is used for transport level flow control. Data
packets are standard IP packets.

Reserved bits must be zero when sent and ignored when received.

Padding is the number of bytes to be appended to the payload to
ensure 4 byte alignment.

Multiplexer ID is to indicate the PDN on which data has to be sent.

Payload length includes the padding length but does not include MAP header
length.

b. Map packet v4 (data / control)

MAP header fields are in big endian format.

Packet format::

  Bit             0             1           2-7      8-15           16-31
  Function   Command / Data   Reserved     Pad   Multiplexer ID    Payload length

  Bit            32-(x-33)      (x-32)-x
  Function      Raw bytes      Checksum offload header

Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
or data packet. Command packet is used for transport level flow control. Data
packets are standard IP packets.

Reserved bits must be zero when sent and ignored when received.

Padding is the number of bytes to be appended to the payload to
ensure 4 byte alignment.

Multiplexer ID is to indicate the PDN on which data has to be sent.

Payload length includes the padding length but does not include MAP header
length.

Checksum offload header, has the information about the checksum processing done
by the hardware.Checksum offload header fields are in big endian format.

Packet format::

  Bit             0-14        15              16-31
  Function      Reserved   Valid     Checksum start offset

  Bit                31-47                    48-64
  Function      Checksum length           Checksum value

Reserved bits must be zero when sent and ignored when received.

Valid bit indicates whether the partial checksum is calculated and is valid.
Set to 1, if its is valid. Set to 0 otherwise.

Padding is the number of bytes to be appended to the payload to
ensure 4 byte alignment.

Checksum start offset, Indicates the offset in bytes from the beginning of the
IP header, from which modem computed checksum.

Checksum length is the Length in bytes starting from CKSUM_START_OFFSET,
over which checksum is computed.

Checksum value, indicates the checksum computed.

c. MAP packet v5 (data / control)

MAP header fields are in big endian format.

Packet format::

  Bit             0             1         2-7      8-15           16-31
  Function   Command / Data  Next header  Pad   Multiplexer ID   Payload length

  Bit            32-x
  Function      Raw bytes

Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
or data packet. Command packet is used for transport level flow control. Data
packets are standard IP packets.

Next header is used to indicate the presence of another header, currently is
limited to checksum header.

Padding is the number of bytes to be appended to the payload to
ensure 4 byte alignment.

Multiplexer ID is to indicate the PDN on which data has to be sent.

Payload length includes the padding length but does not include MAP header
length.

d. Checksum offload header v5

Checksum offload header fields are in big endian format.

  Bit            0 - 6          7               8-15              16-31
  Function     Header Type    Next Header     Checksum Valid    Reserved

Header Type is to indicate the type of header, this usually is set to CHECKSUM

Header types
= ==========================================
0 Reserved
1 Reserved
2 checksum header

Checksum Valid is to indicate whether the header checksum is valid. Value of 1
implies that checksum is calculated on this packet and is valid, value of 0
indicates that the calculated packet checksum is invalid.

Reserved bits must be zero when sent and ignored when received.

e. MAP packet v1/v5 (command specific)::

    Bit             0             1         2-7      8 - 15           16 - 31
    Function   Command         Reserved     Pad   Multiplexer ID    Payload length
    Bit          32 - 39        40 - 45    46 - 47       48 - 63
    Function   Command name    Reserved   Command Type   Reserved
    Bit          64 - 95
    Function   Transaction ID
    Bit          96 - 127
    Function   Command data

Command 1 indicates disabling flow while 2 is enabling flow

Command types

= ==========================================
0 for MAP command request
1 is to acknowledge the receipt of a command
2 is for unsupported commands
3 is for error during processing of commands
= ==========================================

f. Aggregation

Aggregation is multiple MAP packets (can be data or command) delivered to
rmnet in a single linear skb. rmnet will process the individual
packets and either ACK the MAP command or deliver the IP packet to the
network stack as needed

MAP header|IP Packet|Optional padding|MAP header|IP Packet|Optional padding....

MAP header|IP Packet|Optional padding|MAP header|Command Packet|Optional pad...

3. Userspace configuration
==========================

rmnet userspace configuration is done through netlink library librmnetctl
and command line utility rmnetcli. Utility is hosted in codeaurora forum git.
The driver uses rtnl_link_ops for communication.

https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/dataservices/tree/rmnetctl


code:
.. SPDX-License-Identifier: GPL-2.0

=============================================================================
Linux and the 3Com EtherLink III Series Ethercards (driver v1.18c and higher)
=============================================================================

This file contains the instructions and caveats for v1.18c and higher versions
of the 3c509 driver. You should not use the driver without reading this file.

release 1.0

28 February 2002

Current maintainer (corrections to):
  David Ruggiero <jdr@farfalle.com>

Introduction
============

The following are notes and information on using the 3Com EtherLink III series
ethercards in Linux. These cards are commonly known by the most widely-used
card's 3Com model number, 3c509. They are all 10mb/s ISA-bus cards and shouldn't
be (but sometimes are) confused with the similarly-numbered PCI-bus "3c905"
(aka "Vortex" or "Boomerang") series.  Kernel support for the 3c509 family is
provided by the module 3c509.c, which has code to support all of the following
models:

 - 3c509 (original ISA card)
 - 3c509B (later revision of the ISA card; supports full-duplex)
 - 3c589 (PCMCIA)
 - 3c589B (later revision of the 3c589; supports full-duplex)
 - 3c579 (EISA)

Large portions of this documentation were heavily borrowed from the guide
written the original author of the 3c509 driver, Donald Becker. The master
copy of that document, which contains notes on older versions of the driver,
currently resides on Scyld web server: http://www.scyld.com/.

Special Driver Features
=======================

Overriding card settings

The driver allows boot- or load-time overriding of the card's detected IOADDR,
IRQ, and transceiver settings, although this capability shouldn't generally be
needed except to enable full-duplex mode (see below). An example of the syntax
for LILO parameters for doing this::

    ether=10,0x310,3,0x3c509,eth0

This configures the first found 3c509 card for IRQ 10, base I/O 0x310, and
transceiver type 3 (10base2). The flag "0x3c509" must be set to avoid conflicts
with other card types when overriding the I/O address. When the driver is
loaded as a module, only the IRQ may be overridden. For example,
setting two cards to IRQ10 and IRQ11 is done by using the irq module
option::

   options 3c509 irq=10,11

Full-duplex mode
================

The v1.18c driver added support for the 3c509B's full-duplex capabilities.
In order to enable and successfully use full-duplex mode, three conditions
must be met:

(a) You must have a Etherlink III card model whose hardware supports full-
duplex operations. Currently, the only members of the 3c509 family that are
positively known to support full-duplex are the 3c509B (ISA bus) and 3c589B
(PCMCIA) cards. Cards without the "B" model designation do *not* support
full-duplex mode; these include the original 3c509 (no "B"), the original
3c589, the 3c529 (MCA bus), and the 3c579 (EISA bus).

(b) You must be using your card's 10baseT transceiver (i.e., the RJ-45
connector), not its AUI (thick-net) or 10base2 (thin-net/coax) interfaces.
AUI and 10base2 network cabling is physically incapable of full-duplex
operation.

(c) Most importantly, your 3c509B must be connected to a link partner that is
itself full-duplex capable. This is almost certainly one of two things: a full-
duplex-capable  Ethernet switch (*not* a hub), or a full-duplex-capable NIC on
another system that's connected directly to the 3c509B via a crossover cable.

Full-duplex mode can be enabled using 'ethtool'.

.. warning::

  Extremely important caution concerning full-duplex mode

  Understand that the 3c509B's hardware's full-duplex support is much more
  limited than that provide by more modern network interface cards. Although
  at the physical layer of the network it fully supports full-duplex operation,
  the card was designed before the current Ethernet auto-negotiation (N-way)
  spec was written. This means that the 3c509B family ***cannot and will not
  auto-negotiate a full-duplex connection with its link partner under any
  circumstances, no matter how it is initialized***. If the full-duplex mode
  of the 3c509B is enabled, its link partner will very likely need to be
  independently _forced_ into full-duplex mode as well; otherwise various nasty
  failures will occur - at the very least, you'll see massive numbers of packet
  collisions. This is one of very rare circumstances where disabling auto-
  negotiation and forcing the duplex mode of a network interface card or switch
  would ever be necessary or desirable.

Available Transceiver Types
===========================

For versions of the driver v1.18c and above, the available transceiver types are:

== =========================================================================
0  transceiver type from EEPROM config (normally 10baseT); force half-duplex
1  AUI (thick-net / DB15 connector)
2  (undefined)
3  10base2 (thin-net == coax / BNC connector)
4  10baseT (RJ-45 connector); force half-duplex mode
8  transceiver type and duplex mode taken from card's EEPROM config settings
12 10baseT (RJ-45 connector); force full-duplex mode
== =========================================================================

Prior to driver version 1.18c, only transceiver codes 0-4 were supported. Note
that the new transceiver codes 8 and 12 are the *only* ones that will enable
full-duplex mode, no matter what the card's detected EEPROM settings might be.
This insured that merely upgrading the driver from an earlier version would
never automatically enable full-duplex mode in an existing installation;
it must always be explicitly enabled via one of these code in order to be
activated.

The transceiver type can be changed using 'ethtool'.

Interpretation of error messages and common problems
----------------------------------------------------

Error Messages
^^^^^^^^^^^^^^

eth0: Infinite loop in interrupt, status 2011.
These are "mostly harmless" message indicating that the driver had too much
work during that interrupt cycle. With a status of 0x2011 you are receiving
packets faster than they can be removed from the card. This should be rare
or impossible in normal operation. Possible causes of this error report are:

   - a "green" mode enabled that slows the processor down when there is no
     keyboard activity.

   - some other device or device driver hogging the bus or disabling interrupts.
     Check /proc/interrupts for excessive interrupt counts. The timer tick
     interrupt should always be incrementing faster than the others.

No received packets
^^^^^^^^^^^^^^^^^^^

If a 3c509, 3c562 or 3c589 can successfully transmit packets, but never
receives packets (as reported by /proc/net/dev or 'ifconfig') you likely
have an interrupt line problem. Check /proc/interrupts to verify that the
card is actually generating interrupts. If the interrupt count is not
increasing you likely have a physical conflict with two devices trying to
use the same ISA IRQ line. The common conflict is with a sound card on IRQ10
or IRQ5, and the easiest solution is to move the 3c509 to a different
interrupt line. If the device is receiving packets but 'ping' doesn't work,
you have a routing problem.

Tx Carrier Errors Reported in /proc/net/dev
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If an EtherLink III appears to transmit packets, but the "Tx carrier errors"
field in /proc/net/dev increments as quickly as the Tx packet count, you
likely have an unterminated network or the incorrect media transceiver selected.

3c509B card is not detected on machines with an ISA PnP BIOS.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

While the updated driver works with most PnP BIOS programs, it does not work
with all. This can be fixed by disabling PnP support using the 3Com-supplied
setup program.

3c509 card is not detected on overclocked machines
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Increase the delay time in id_read_eeprom() from the current value, 500,
to an absurdly high value, such as 5000.

Decoding Status and Error Messages
----------------------------------

The bits in the main status register are:

=====	======================================
value 	description
=====	======================================
0x01 	Interrupt latch
0x02 	Tx overrun, or Rx underrun
0x04 	Tx complete
0x08 	Tx FIFO room available
0x10 	A complete Rx packet has arrived
0x20 	A Rx packet has started to arrive
0x40 	The driver has requested an interrupt
0x80 	Statistics counter nearly full
=====	======================================

The bits in the transmit (Tx) status word are:

=====	============================================
value	description
=====	============================================
0x02	Out-of-window collision.
0x04	Status stack overflow (normally impossible).
0x08	16 collisions.
0x10	Tx underrun (not enough PCI bus bandwidth).
0x20	Tx jabber.
0x40	Tx interrupt requested.
0x80	Status is valid (this should always be set).
=====	============================================

When a transmit error occurs the driver produces a status message such as::

   eth0: Transmit error, Tx status register 82

The two values typically seen here are:

0x82
^^^^

Out of window collision. This typically occurs when some other Ethernet
host is incorrectly set to full duplex on a half duplex network.

0x88
^^^^

16 collisions. This typically occurs when the network is exceptionally busy
or when another host doesn't correctly back off after a collision. If this
error is mixed with 0x82 errors it is the result of a host incorrectly set
to full duplex (see above).

Both of these errors are the result of network problems that should be
corrected. They do not represent driver malfunction.

Revision history (this file)
============================

28Feb02 v1.0  DR   New; major portions based on Becker original 3c509 docs