[PATCHv2,6/7] cec-pin-error-inj.rst: document CEC Pin Error Injection

Submitted by Hans Verkuil on March 5, 2018, 1:51 p.m.

Details

Message ID 20180305135139.95652-7-hverkuil@xs4all.nl
State New
Headers show
Series "cec: add error injection support" ( rev: 3 2 ) in DRI devel

Not browsing as part of any series.

Commit Message

Hans Verkuil March 5, 2018, 1:51 p.m.
From: Hans Verkuil <hans.verkuil@cisco.com>

The CEC Pin framework adds support for Error Injection.

Document all the error injections commands and how to use it.

Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
---
 .../media/cec-drivers/cec-pin-error-inj.rst        | 322 +++++++++++++++++++++
 Documentation/media/cec-drivers/index.rst          |   1 +
 MAINTAINERS                                        |   1 +
 3 files changed, 324 insertions(+)
 create mode 100644 Documentation/media/cec-drivers/cec-pin-error-inj.rst

Patch hide | download patch | download mbox

diff --git a/Documentation/media/cec-drivers/cec-pin-error-inj.rst b/Documentation/media/cec-drivers/cec-pin-error-inj.rst
new file mode 100644
index 000000000000..21bda831d3fb
--- /dev/null
+++ b/Documentation/media/cec-drivers/cec-pin-error-inj.rst
@@ -0,0 +1,322 @@ 
+CEC Pin Framework Error Injection
+=================================
+
+The CEC Pin Framework is a core CEC framework for CEC hardware that only
+has low-level support for the CEC bus. Most hardware today will have
+high-level CEC support where the hardware deals with driving the CEC bus,
+but some older devices aren't that fancy. However, this framework also
+allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and
+you can become an instant CEC adapter.
+
+What makes doing this so interesting is that since we have full control
+over the bus it is easy to support error injection. This is ideal to
+test how well CEC adapters can handle error conditions.
+
+Currently only the cec-gpio driver (when the CEC line is directly
+connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver
+support this framework.
+
+If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available
+through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is
+now an ``error-inj`` file.
+
+With ``cat error-inj`` you can see both the possible commands and the current
+error injection status:
+
+.. code-block:: none
+
+	$ cat /sys/kernel/debug/cec/cec0/error-inj
+	# Clear error injections:
+	#   clear          clear all rx and tx error injections
+	#   rx-clear       clear all rx error injections
+	#   tx-clear       clear all tx error injections
+	#   <op> clear     clear all rx and tx error injections for <op>
+	#   <op> rx-clear  clear all rx error injections for <op>
+	#   <op> tx-clear  clear all tx error injections for <op>
+	#
+	# RX error injection:
+	#   <op>[,<mode>] rx-nack              NACK the message instead of sending an ACK
+	#   <op>[,<mode>] rx-low-drive <bit>   force a low-drive condition at this bit position
+	#   <op>[,<mode>] rx-add-byte          add a spurious byte to the received CEC message
+	#   <op>[,<mode>] rx-remove-byte       remove the last byte from the received CEC message
+	#   <op>[,<mode>] rx-arb-lost <poll>   generate a POLL message to trigger an arbitration lost
+	#
+	# TX error injection settings:
+	#   tx-ignore-nack-until-eom           ignore early NACKs until EOM
+	#   tx-custom-low-usecs <usecs>        define the 'low' time for the custom pulse
+	#   tx-custom-high-usecs <usecs>       define the 'high' time for the custom pulse
+	#   tx-custom-pulse                    transmit the custom pulse once the bus is idle
+	#
+	# TX error injection:
+	#   <op>[,<mode>] tx-no-eom            don't set the EOM bit
+	#   <op>[,<mode>] tx-early-eom         set the EOM bit one byte too soon
+	#   <op>[,<mode>] tx-add-bytes <num>   append <num> (1-255) spurious bytes to the message
+	#   <op>[,<mode>] tx-remove-byte       drop the last byte from the message
+	#   <op>[,<mode>] tx-short-bit <bit>   make this bit shorter than allowed
+	#   <op>[,<mode>] tx-long-bit <bit>    make this bit longer than allowed
+	#   <op>[,<mode>] tx-custom-bit <bit>  send the custom pulse instead of this bit
+	#   <op>[,<mode>] tx-short-start       send a start pulse that's too short
+	#   <op>[,<mode>] tx-long-start        send a start pulse that's too long
+	#   <op>[,<mode>] tx-custom-start      send the custom pulse instead of the start pulse
+	#   <op>[,<mode>] tx-last-bit <bit>    stop sending after this bit
+	#   <op>[,<mode>] tx-low-drive <bit>   force a low-drive condition at this bit position
+	#
+	# <op>       CEC message opcode (0-255) or 'any'
+	# <mode>     'once' (default), 'always', 'toggle' or 'off'
+	# <bit>      CEC message bit (0-159)
+	#            10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK
+	# <poll>     CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)
+	# <usecs>    microseconds (0-10000000, default 1000)
+
+	clear
+
+You can write error injection commands to ``error-inj`` using ``echo 'cmd' >error-inj``
+or ``cat cmd.txt >error-inj``. The ``cat error-inj`` output contains the current
+error commands. You can save the output to a file and use it as an input to
+``error-inj`` later.
+
+Basic Syntax
+------------
+
+Leading spaces/tabs are ignored. If the next character is a ``#`` or the end of the
+line was reached, then the whole line is ignored. Otherwise a command is expected.
+
+The error injection commands fall in two main groups: those relating to receiving
+CEC messages and those relating to transmitting CEC messages. In addition, there
+are commands to clear existing error injection commands and to create custom
+pulses on the CEC bus.
+
+Most error injection commands can be executed for specific CEC opcodes or for all
+opcodes (``any``). Each command also has a 'mode' which can be ``off`` (can be used
+to turn off an existing error injection command), ``once`` (the default) which will
+trigger the error injection only once for the next received or transmitted message,
+``always`` to always trigger the error injection and ``toggle`` to toggle the error
+injection on or off for every transmit or receive.
+
+So '``any rx-nack``' will NACK the next received CEC message, '``any,always rx-nack``' will
+NACK all received CEC messages and '``0x82,toggle rx-nack``' will only NACK if an Active
+Source message was received and do that only for every other received message.
+
+After an error was injected with mode ``once`` the error injection command is cleared
+automatically, so ``once`` is a one-time deal.
+
+All combinations of ``<op>`` and error injection commands can co-exist. So
+this is fine:
+
+.. code-block:: none
+
+	0x9e tx-add-bytes 1
+	0x9e tx-early-eom
+	0x9f tx-add-bytes 2
+	any rx-nack
+
+All four error injection commands will be active simultaneously.
+
+However, if the same ``<op>`` and command combination is specified,
+but with different arguments:
+
+.. code-block:: none
+
+	0x9e tx-add-bytes 1
+	0x9e tx-add-bytes 2
+
+Then the second will overwrite the first.
+
+Clear Error Injections
+----------------------
+
+``clear``
+    Clear all error injections.
+
+``rx-clear``
+    Clear all receive error injections
+
+``tx-clear``
+    Clear all transmit error injections
+
+``<op> clear``
+    Clear all error injections for the given opcode.
+
+``<op> rx-clear``
+    Clear all receive error injections for the given opcode.
+
+``<op> tx-clear``
+    Clear all transmit error injections for the given opcode.
+
+Receive Messages
+----------------
+
+``<op>[,<mode>] rx-nack``
+    NACK broadcast messages and messages directed to this CEC adapter.
+    Every byte of the message will be NACKed in case the transmitter
+    keeps transmitting after the first byte was NACKed.
+
+``<op>[,<mode>] rx-low-drive <bit>``
+    Force a Low Drive condition at this bit position. If <op> specifies
+    a specific CEC opcode then the bit position must be at least 18,
+    otherwise the opcode hasn't been received yet. This tests if the transmitter
+    can handle the Low Drive condition correctly and reports the error
+    correctly. Note that a Low Drive in the first 4 bits can also be
+    interpreted as an Arbitration Lost condition by the transmitter.
+    This is implementation dependent.
+
+``<op>[,<mode>] rx-add-byte``
+    Add a spurious 0x55 byte to the received CEC message, provided
+    the message was 15 bytes long or less. This is useful to test
+    the high-level protocol since spurious bytes should be ignored.
+
+``<op>[,<mode>] rx-remove-byte``
+    Remove the last byte from the received CEC message, provided it
+    was at least 2 bytes long. This is useful to test the high-level
+    protocol since messages that are too short should be ignored.
+
+``<op>[,<mode>] rx-arb-lost <poll>``
+    Generate a POLL message to trigger an Arbitration Lost condition.
+    This command is only allowed for ``<op>`` values of ``next`` or ``all``.
+    As soon as a start bit has been received the CEC adapter will switch
+    to transmit mode and it will transmit a POLL message. By default this is
+    0x0f, but it can also be specified explicitly via the ``<poll>`` argument.
+
+    This command can be used to test the Arbitration Lost condition in
+    the remote CEC transmitter. Arbitration happens when two CEC adapters
+    start sending a message at the same time. In that case the initiator
+    with the most leading zeroes wins and the other transmitter has to
+    stop transmitting ('Arbitration Lost'). This is very hard to test,
+    except by using this error injection command.
+
+    This does not work if the remote CEC transmitter has logical address
+    0 ('TV') since that will always win.
+
+Transmit Messages
+-----------------
+
+``tx-ignore-nack-until-eom``
+    This setting changes the behavior of transmitting CEC messages. Normally
+    as soon as the receiver NACKs a byte the transmit will stop, but the
+    specification also allows that the full message is transmitted and only
+    at the end will the transmitter look at the ACK bit. This is not recommended
+    behavior since there is no point in keeping the CEC bus busy for longer than
+    is strictly needed. Especially given how slow the bus is.
+
+    This setting can be used to test how well a receiver deals with transmitters
+    that ignore NACKs until the very end of the message.
+
+``<op>[,<mode>] tx-no-eom``
+    Don't set the EOM bit. Normally the last byte of the message has the EOM
+    (End-Of-Message) bit set. With this command the transmit will just stop
+    without ever sending an EOM. This can be used to test how a receiver
+    handles this case. Normally receivers have a time-out after which
+    they will go back to the Idle state.
+
+``<op>[,<mode>] tx-early-eom``
+    Set the EOM bit one byte too soon. This obviously only works for messages
+    of two bytes or more. The EOM bit will be set for the second-to-last byte
+    and not for the final byte. The receiver should ignore the last byte in this
+    case. Since the resulting message is likely to be too short for this same
+    reason the whole message is typically ignored. The receiver should be in
+    Idle state after the last byte was transmitted.
+
+``<op>[,<mode>] tx-add-bytes <num>``
+    Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes
+    have the value of the byte position in the message. So if you transmit a
+    two byte message (e.g. a Get CEC Version message) and add 2 bytes, then
+    the full message received by the remote CEC adapter is ``0x40 0x9f 0x02 0x03``.
+
+    This command can be used to test buffer overflows in the receiver. E.g.
+    what does it do when it receives more than the maximum message size of 16
+    bytes.
+
+``<op>[,<mode>] tx-remove-byte``
+    Drop the last byte from the message, provided the message is at least
+    two bytes long. The receiver should ignore messages that are too short.
+
+``<op>[,<mode>] tx-short-bit <bit>``
+    Make this bit period shorter than allowed. The bit position cannot be
+    an Ack bit.  If <op> specifies a specific CEC opcode then the bit position
+    must be at least 18, otherwise the opcode hasn't been received yet. Normally the
+    period of a data bit is between 2.05 and 2.75 milliseconds. With this
+    command the period of this bit is 1.8 milliseconds, this is done by
+    reducing the time the CEC bus is high. This bit period is less than
+    is allowed and the receiver should respond with a Low Drive
+    condition.
+
+    This command is ignored for 0 bits in bit positions 0 to 3. This is
+    because the receiver also looks for an Arbitration Lost condition in
+    those first four bits and it is undefined what will happen if it
+    sees a too-short 0 bit.
+
+``<op>[,<mode>] tx-long-bit <bit>``
+    Make this bit period longer than is valid. The bit position cannot be
+    an Ack bit.  If <op> specifies a specific CEC opcode then the bit position
+    must be at least 18, otherwise the opcode hasn't been received yet. Normally the
+    period of a data bit is between 2.05 and 2.75 milliseconds. With this
+    command the period of this bit is 2.9 milliseconds, this is done by
+    increasing the time the CEC bus is high.
+
+    Even though this bit period is longer than is valid it is undefined what
+    a receiver will do. It might just accept it, or it might time out and
+    return to Idle state. Unfortunately the CEC specification is silent about
+    this.
+
+    This command is ignored for 0 bits in bit positions 0 to 3. This is
+    because the receiver also looks for an Arbitration Lost condition in
+    those first four bits and it is undefined what will happen if it
+    sees a too-long 0 bit.
+
+``<op>[,<mode>] tx-short-start``
+    Make this start bit period shorter than allowed. Normally the period of a start bit is
+    between 4.3 and 4.7 milliseconds. With this command the period of the
+    start bit is 4.1 milliseconds, this is done by reducing the time the
+    CEC bus is high. This start bit period is less than is allowed
+    and the receiver should return to Idle state when this is detected.
+
+``<op>[,<mode>] tx-long-start``
+    Make this start bit period longer than is valid. Normally the period of a start bit is
+    between 4.3 and 4.7 milliseconds. With this command the period of the
+    start bit is 5 milliseconds, this is done by increasing the time the
+    CEC bus is high. This start bit period is more than is valid
+    and the receiver should return to Idle state when this is detected.
+
+    Even though this start bit period is longer than is valid it is undefined what
+    a receiver will do. It might just accept it, or it might time out and
+    return to Idle state. Unfortunately the CEC specification is silent about
+    this.
+
+``<op>[,<mode>] tx-last-bit <bit>``
+    Just stop transmitting after this bit.  If <op> specifies a specific CEC
+    opcode then the bit position must be at least 18, otherwise the opcode
+    hasn't been received yet. This command can be used to test how the receiver reacts
+    when a message just suddenly stops. It should time out and go back to Idle
+    state.
+
+``<op>[,<mode>] tx-low-drive <bit>``
+    Force a Low Drive condition at this bit position. If <op> specifies a specific
+    CEC opcode then the bit position must be at least 18, otherwise the opcode
+    hasn't been received yet. This can be used to test how the receiver handles Low Drive
+    conditions. Note that if this happens at bit positions 0-3 the receiver
+    can interpret this as an Arbitration Lost condition. This is implementation
+    dependent.
+
+Custom Pulses
+-------------
+
+``tx-custom-low-usecs <usecs>``
+    This defines the duration in microseconds that the custom pulse pulls the CEC line low.
+    The default is 1000 microseconds.
+
+``tx-custom-high-usecs <usecs>``
+    This defines the duration in microseconds that the custom pulse keeps the
+    CEC line high (unless another CEC adapter pulls it low in that time).
+    The default is 1000 microseconds. The total period of the custom pulse is
+    ``tx-custom-low-usecs + tx-custom-high-usecs``.
+
+``<op>[,<mode>] tx-custom-bit <bit>``
+    Send the custom bit instead of a regular data bit. The bit position cannot be
+    an Ack bit.  If <op> specifies a specific CEC opcode then the bit position
+    must be at least 18, otherwise the opcode hasn't been received yet.
+
+``<op>[,<mode>] tx-custom-start``
+    Send the custom bit instead of a regular start bit.
+
+``tx-custom-pulse``
+    Transmit a single custom pulse as soon as the CEC bus is idle.
diff --git a/Documentation/media/cec-drivers/index.rst b/Documentation/media/cec-drivers/index.rst
index 7ef204823422..3580bdb790bc 100644
--- a/Documentation/media/cec-drivers/index.rst
+++ b/Documentation/media/cec-drivers/index.rst
@@ -31,4 +31,5 @@  For more details see the file COPYING in the source distribution of Linux.
 	:maxdepth: 5
 	:numbered:
 
+	cec-pin-error-inj
 	pulse8-cec
diff --git a/MAINTAINERS b/MAINTAINERS
index 91ed6adfa4a6..085b40adbe4d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3305,6 +3305,7 @@  F:	include/media/cec-notifier.h
 F:	include/uapi/linux/cec.h
 F:	include/uapi/linux/cec-funcs.h
 F:	Documentation/devicetree/bindings/media/cec.txt
+F:	Documentation/media/cec-drivers/cec-pin-error-inj.rst
 
 CEC GPIO DRIVER
 M:	Hans Verkuil <hans.verkuil@cisco.com>

Comments

Em Mon,  5 Mar 2018 14:51:38 +0100
Hans Verkuil <hverkuil@xs4all.nl> escreveu:

> From: Hans Verkuil <hans.verkuil@cisco.com>
> 
> The CEC Pin framework adds support for Error Injection.
> 
> Document all the error injections commands and how to use it.

Please notice that all debugfs/sysfs entries should *also* be
documented at the standard way, e. g. by adding the corresponding
documentation at Documentation/ABI.

Please see Documentation/ABI/README.

Additionally, there are a few minor nitpicks on this patch.
See below.

The remaining patches looked ok on my eyes.

I'll wait for a v3 with the debugfs ABI documentation in order to merge
it. Feel free to put it on a separate patch.

Regards,
Mauro

> 
> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
> ---
>  .../media/cec-drivers/cec-pin-error-inj.rst        | 322 +++++++++++++++++++++
>  Documentation/media/cec-drivers/index.rst          |   1 +
>  MAINTAINERS                                        |   1 +
>  3 files changed, 324 insertions(+)
>  create mode 100644 Documentation/media/cec-drivers/cec-pin-error-inj.rst
> 
> diff --git a/Documentation/media/cec-drivers/cec-pin-error-inj.rst b/Documentation/media/cec-drivers/cec-pin-error-inj.rst
> new file mode 100644
> index 000000000000..21bda831d3fb
> --- /dev/null
> +++ b/Documentation/media/cec-drivers/cec-pin-error-inj.rst
> @@ -0,0 +1,322 @@
> +CEC Pin Framework Error Injection
> +=================================
> +
> +The CEC Pin Framework is a core CEC framework for CEC hardware that only
> +has low-level support for the CEC bus. Most hardware today will have
> +high-level CEC support where the hardware deals with driving the CEC bus,
> +but some older devices aren't that fancy. However, this framework also
> +allows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and
> +you can become an instant CEC adapter.
> +
> +What makes doing this so interesting is that since we have full control
> +over the bus it is easy to support error injection. This is ideal to
> +test how well CEC adapters can handle error conditions.
> +
> +Currently only the cec-gpio driver (when the CEC line is directly
> +connected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver
> +support this framework.
> +
> +If ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available
> +through debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is
> +now an ``error-inj`` file.
> +
> +With ``cat error-inj`` you can see both the possible commands and the current
> +error injection status:
> +
> +.. code-block:: none

It is usually better to use "::" instead of ".. code-block".

> +
> +	$ cat /sys/kernel/debug/cec/cec0/error-inj
> +	# Clear error injections:
> +	#   clear          clear all rx and tx error injections
> +	#   rx-clear       clear all rx error injections
> +	#   tx-clear       clear all tx error injections
> +	#   <op> clear     clear all rx and tx error injections for <op>
> +	#   <op> rx-clear  clear all rx error injections for <op>
> +	#   <op> tx-clear  clear all tx error injections for <op>
> +	#
> +	# RX error injection:
> +	#   <op>[,<mode>] rx-nack              NACK the message instead of sending an ACK
> +	#   <op>[,<mode>] rx-low-drive <bit>   force a low-drive condition at this bit position
> +	#   <op>[,<mode>] rx-add-byte          add a spurious byte to the received CEC message
> +	#   <op>[,<mode>] rx-remove-byte       remove the last byte from the received CEC message
> +	#   <op>[,<mode>] rx-arb-lost <poll>   generate a POLL message to trigger an arbitration lost
> +	#
> +	# TX error injection settings:
> +	#   tx-ignore-nack-until-eom           ignore early NACKs until EOM
> +	#   tx-custom-low-usecs <usecs>        define the 'low' time for the custom pulse
> +	#   tx-custom-high-usecs <usecs>       define the 'high' time for the custom pulse
> +	#   tx-custom-pulse                    transmit the custom pulse once the bus is idle
> +	#
> +	# TX error injection:
> +	#   <op>[,<mode>] tx-no-eom            don't set the EOM bit
> +	#   <op>[,<mode>] tx-early-eom         set the EOM bit one byte too soon
> +	#   <op>[,<mode>] tx-add-bytes <num>   append <num> (1-255) spurious bytes to the message
> +	#   <op>[,<mode>] tx-remove-byte       drop the last byte from the message
> +	#   <op>[,<mode>] tx-short-bit <bit>   make this bit shorter than allowed
> +	#   <op>[,<mode>] tx-long-bit <bit>    make this bit longer than allowed
> +	#   <op>[,<mode>] tx-custom-bit <bit>  send the custom pulse instead of this bit
> +	#   <op>[,<mode>] tx-short-start       send a start pulse that's too short
> +	#   <op>[,<mode>] tx-long-start        send a start pulse that's too long
> +	#   <op>[,<mode>] tx-custom-start      send the custom pulse instead of the start pulse
> +	#   <op>[,<mode>] tx-last-bit <bit>    stop sending after this bit
> +	#   <op>[,<mode>] tx-low-drive <bit>   force a low-drive condition at this bit position
> +	#
> +	# <op>       CEC message opcode (0-255) or 'any'
> +	# <mode>     'once' (default), 'always', 'toggle' or 'off'
> +	# <bit>      CEC message bit (0-159)
> +	#            10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK
> +	# <poll>     CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f)
> +	# <usecs>    microseconds (0-10000000, default 1000)
> +
> +	clear
> +
> +You can write error injection commands to ``error-inj`` using ``echo 'cmd' >error-inj``
> +or ``cat cmd.txt >error-inj``. The ``cat error-inj`` output contains the current
> +error commands. You can save the output to a file and use it as an input to
> +``error-inj`` later.

Please word-wrap it to fit into 80 columns (actually, it is better to use
something lower than that, like 72, as it makes easier to do small
adjustments without needing to change an entire text block.

(Same applies to other parts of this patch)



Thanks,
Mauro
On Wed, 21 Mar 2018, Mauro Carvalho Chehab <mchehab@s-opensource.com> wrote:
> Please notice that all debugfs/sysfs entries should *also* be
> documented at the standard way, e. g. by adding the corresponding
> documentation at Documentation/ABI.
>
> Please see Documentation/ABI/README.
>
> Additionally, there are a few minor nitpicks on this patch.
> See below.
>
> The remaining patches looked ok on my eyes.
>
> I'll wait for a v3 with the debugfs ABI documentation in order to merge
> it. Feel free to put it on a separate patch.

debugfs ABI? Sounds like an oxymoron to me.

BR,
Jani.
> > I'll wait for a v3 with the debugfs ABI documentation in order to merge
> > it. Feel free to put it on a separate patch.
> 
> debugfs ABI? Sounds like an oxymoron to me.

Heh, thought the same :)