1*4882a593Smuzhiyun.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later 2*4882a593Smuzhiyun 3*4882a593SmuzhiyunCEC Pin Framework Error Injection 4*4882a593Smuzhiyun================================= 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunThe CEC Pin Framework is a core CEC framework for CEC hardware that only 7*4882a593Smuzhiyunhas low-level support for the CEC bus. Most hardware today will have 8*4882a593Smuzhiyunhigh-level CEC support where the hardware deals with driving the CEC bus, 9*4882a593Smuzhiyunbut some older devices aren't that fancy. However, this framework also 10*4882a593Smuzhiyunallows you to connect the CEC pin to a GPIO on e.g. a Raspberry Pi and 11*4882a593Smuzhiyunyou have now made a CEC adapter. 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunWhat makes doing this so interesting is that since we have full control 14*4882a593Smuzhiyunover the bus it is easy to support error injection. This is ideal to 15*4882a593Smuzhiyuntest how well CEC adapters can handle error conditions. 16*4882a593Smuzhiyun 17*4882a593SmuzhiyunCurrently only the cec-gpio driver (when the CEC line is directly 18*4882a593Smuzhiyunconnected to a pull-up GPIO line) and the AllWinner A10/A20 drm driver 19*4882a593Smuzhiyunsupport this framework. 20*4882a593Smuzhiyun 21*4882a593SmuzhiyunIf ``CONFIG_CEC_PIN_ERROR_INJ`` is enabled, then error injection is available 22*4882a593Smuzhiyunthrough debugfs. Specifically, in ``/sys/kernel/debug/cec/cecX/`` there is 23*4882a593Smuzhiyunnow an ``error-inj`` file. 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun.. note:: 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun The error injection commands are not a stable ABI and may change in the 28*4882a593Smuzhiyun future. 29*4882a593Smuzhiyun 30*4882a593SmuzhiyunWith ``cat error-inj`` you can see both the possible commands and the current 31*4882a593Smuzhiyunerror injection status:: 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun $ cat /sys/kernel/debug/cec/cec0/error-inj 34*4882a593Smuzhiyun # Clear error injections: 35*4882a593Smuzhiyun # clear clear all rx and tx error injections 36*4882a593Smuzhiyun # rx-clear clear all rx error injections 37*4882a593Smuzhiyun # tx-clear clear all tx error injections 38*4882a593Smuzhiyun # <op> clear clear all rx and tx error injections for <op> 39*4882a593Smuzhiyun # <op> rx-clear clear all rx error injections for <op> 40*4882a593Smuzhiyun # <op> tx-clear clear all tx error injections for <op> 41*4882a593Smuzhiyun # 42*4882a593Smuzhiyun # RX error injection: 43*4882a593Smuzhiyun # <op>[,<mode>] rx-nack NACK the message instead of sending an ACK 44*4882a593Smuzhiyun # <op>[,<mode>] rx-low-drive <bit> force a low-drive condition at this bit position 45*4882a593Smuzhiyun # <op>[,<mode>] rx-add-byte add a spurious byte to the received CEC message 46*4882a593Smuzhiyun # <op>[,<mode>] rx-remove-byte remove the last byte from the received CEC message 47*4882a593Smuzhiyun # <op>[,<mode>] rx-arb-lost <poll> generate a POLL message to trigger an arbitration lost 48*4882a593Smuzhiyun # 49*4882a593Smuzhiyun # TX error injection settings: 50*4882a593Smuzhiyun # tx-ignore-nack-until-eom ignore early NACKs until EOM 51*4882a593Smuzhiyun # tx-custom-low-usecs <usecs> define the 'low' time for the custom pulse 52*4882a593Smuzhiyun # tx-custom-high-usecs <usecs> define the 'high' time for the custom pulse 53*4882a593Smuzhiyun # tx-custom-pulse transmit the custom pulse once the bus is idle 54*4882a593Smuzhiyun # 55*4882a593Smuzhiyun # TX error injection: 56*4882a593Smuzhiyun # <op>[,<mode>] tx-no-eom don't set the EOM bit 57*4882a593Smuzhiyun # <op>[,<mode>] tx-early-eom set the EOM bit one byte too soon 58*4882a593Smuzhiyun # <op>[,<mode>] tx-add-bytes <num> append <num> (1-255) spurious bytes to the message 59*4882a593Smuzhiyun # <op>[,<mode>] tx-remove-byte drop the last byte from the message 60*4882a593Smuzhiyun # <op>[,<mode>] tx-short-bit <bit> make this bit shorter than allowed 61*4882a593Smuzhiyun # <op>[,<mode>] tx-long-bit <bit> make this bit longer than allowed 62*4882a593Smuzhiyun # <op>[,<mode>] tx-custom-bit <bit> send the custom pulse instead of this bit 63*4882a593Smuzhiyun # <op>[,<mode>] tx-short-start send a start pulse that's too short 64*4882a593Smuzhiyun # <op>[,<mode>] tx-long-start send a start pulse that's too long 65*4882a593Smuzhiyun # <op>[,<mode>] tx-custom-start send the custom pulse instead of the start pulse 66*4882a593Smuzhiyun # <op>[,<mode>] tx-last-bit <bit> stop sending after this bit 67*4882a593Smuzhiyun # <op>[,<mode>] tx-low-drive <bit> force a low-drive condition at this bit position 68*4882a593Smuzhiyun # 69*4882a593Smuzhiyun # <op> CEC message opcode (0-255) or 'any' 70*4882a593Smuzhiyun # <mode> 'once' (default), 'always', 'toggle' or 'off' 71*4882a593Smuzhiyun # <bit> CEC message bit (0-159) 72*4882a593Smuzhiyun # 10 bits per 'byte': bits 0-7: data, bit 8: EOM, bit 9: ACK 73*4882a593Smuzhiyun # <poll> CEC poll message used to test arbitration lost (0x00-0xff, default 0x0f) 74*4882a593Smuzhiyun # <usecs> microseconds (0-10000000, default 1000) 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun clear 77*4882a593Smuzhiyun 78*4882a593SmuzhiyunYou can write error injection commands to ``error-inj`` using 79*4882a593Smuzhiyun``echo 'cmd' >error-inj`` or ``cat cmd.txt >error-inj``. The ``cat error-inj`` 80*4882a593Smuzhiyunoutput contains the current error commands. You can save the output to a file 81*4882a593Smuzhiyunand use it as an input to ``error-inj`` later. 82*4882a593Smuzhiyun 83*4882a593SmuzhiyunBasic Syntax 84*4882a593Smuzhiyun------------ 85*4882a593Smuzhiyun 86*4882a593SmuzhiyunLeading spaces/tabs are ignored. If the next character is a ``#`` or the end 87*4882a593Smuzhiyunof the line was reached, then the whole line is ignored. Otherwise a command 88*4882a593Smuzhiyunis expected. 89*4882a593Smuzhiyun 90*4882a593SmuzhiyunThe error injection commands fall in two main groups: those relating to 91*4882a593Smuzhiyunreceiving CEC messages and those relating to transmitting CEC messages. In 92*4882a593Smuzhiyunaddition, there are commands to clear existing error injection commands and 93*4882a593Smuzhiyunto create custom pulses on the CEC bus. 94*4882a593Smuzhiyun 95*4882a593SmuzhiyunMost error injection commands can be executed for specific CEC opcodes or for 96*4882a593Smuzhiyunall opcodes (``any``). Each command also has a 'mode' which can be ``off`` 97*4882a593Smuzhiyun(can be used to turn off an existing error injection command), ``once`` 98*4882a593Smuzhiyun(the default) which will trigger the error injection only once for the next 99*4882a593Smuzhiyunreceived or transmitted message, ``always`` to always trigger the error 100*4882a593Smuzhiyuninjection and ``toggle`` to toggle the error injection on or off for every 101*4882a593Smuzhiyuntransmit or receive. 102*4882a593Smuzhiyun 103*4882a593SmuzhiyunSo '``any rx-nack``' will NACK the next received CEC message, 104*4882a593Smuzhiyun'``any,always rx-nack``' will NACK all received CEC messages and 105*4882a593Smuzhiyun'``0x82,toggle rx-nack``' will only NACK if an Active Source message was 106*4882a593Smuzhiyunreceived and do that only for every other received message. 107*4882a593Smuzhiyun 108*4882a593SmuzhiyunAfter an error was injected with mode ``once`` the error injection command 109*4882a593Smuzhiyunis cleared automatically, so ``once`` is a one-time deal. 110*4882a593Smuzhiyun 111*4882a593SmuzhiyunAll combinations of ``<op>`` and error injection commands can co-exist. So 112*4882a593Smuzhiyunthis is fine:: 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun 0x9e tx-add-bytes 1 115*4882a593Smuzhiyun 0x9e tx-early-eom 116*4882a593Smuzhiyun 0x9f tx-add-bytes 2 117*4882a593Smuzhiyun any rx-nack 118*4882a593Smuzhiyun 119*4882a593SmuzhiyunAll four error injection commands will be active simultaneously. 120*4882a593Smuzhiyun 121*4882a593SmuzhiyunHowever, if the same ``<op>`` and command combination is specified, 122*4882a593Smuzhiyunbut with different arguments:: 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun 0x9e tx-add-bytes 1 125*4882a593Smuzhiyun 0x9e tx-add-bytes 2 126*4882a593Smuzhiyun 127*4882a593SmuzhiyunThen the second will overwrite the first. 128*4882a593Smuzhiyun 129*4882a593SmuzhiyunClear Error Injections 130*4882a593Smuzhiyun---------------------- 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun``clear`` 133*4882a593Smuzhiyun Clear all error injections. 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun``rx-clear`` 136*4882a593Smuzhiyun Clear all receive error injections 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun``tx-clear`` 139*4882a593Smuzhiyun Clear all transmit error injections 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun``<op> clear`` 142*4882a593Smuzhiyun Clear all error injections for the given opcode. 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun``<op> rx-clear`` 145*4882a593Smuzhiyun Clear all receive error injections for the given opcode. 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun``<op> tx-clear`` 148*4882a593Smuzhiyun Clear all transmit error injections for the given opcode. 149*4882a593Smuzhiyun 150*4882a593SmuzhiyunReceive Messages 151*4882a593Smuzhiyun---------------- 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun``<op>[,<mode>] rx-nack`` 154*4882a593Smuzhiyun NACK broadcast messages and messages directed to this CEC adapter. 155*4882a593Smuzhiyun Every byte of the message will be NACKed in case the transmitter 156*4882a593Smuzhiyun keeps transmitting after the first byte was NACKed. 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun``<op>[,<mode>] rx-low-drive <bit>`` 159*4882a593Smuzhiyun Force a Low Drive condition at this bit position. If <op> specifies 160*4882a593Smuzhiyun a specific CEC opcode then the bit position must be at least 18, 161*4882a593Smuzhiyun otherwise the opcode hasn't been received yet. This tests if the 162*4882a593Smuzhiyun transmitter can handle the Low Drive condition correctly and reports 163*4882a593Smuzhiyun the error correctly. Note that a Low Drive in the first 4 bits can also 164*4882a593Smuzhiyun be interpreted as an Arbitration Lost condition by the transmitter. 165*4882a593Smuzhiyun This is implementation dependent. 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun``<op>[,<mode>] rx-add-byte`` 168*4882a593Smuzhiyun Add a spurious 0x55 byte to the received CEC message, provided 169*4882a593Smuzhiyun the message was 15 bytes long or less. This is useful to test 170*4882a593Smuzhiyun the high-level protocol since spurious bytes should be ignored. 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun``<op>[,<mode>] rx-remove-byte`` 173*4882a593Smuzhiyun Remove the last byte from the received CEC message, provided it 174*4882a593Smuzhiyun was at least 2 bytes long. This is useful to test the high-level 175*4882a593Smuzhiyun protocol since messages that are too short should be ignored. 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun``<op>[,<mode>] rx-arb-lost <poll>`` 178*4882a593Smuzhiyun Generate a POLL message to trigger an Arbitration Lost condition. 179*4882a593Smuzhiyun This command is only allowed for ``<op>`` values of ``next`` or ``all``. 180*4882a593Smuzhiyun As soon as a start bit has been received the CEC adapter will switch 181*4882a593Smuzhiyun to transmit mode and it will transmit a POLL message. By default this is 182*4882a593Smuzhiyun 0x0f, but it can also be specified explicitly via the ``<poll>`` argument. 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun This command can be used to test the Arbitration Lost condition in 185*4882a593Smuzhiyun the remote CEC transmitter. Arbitration happens when two CEC adapters 186*4882a593Smuzhiyun start sending a message at the same time. In that case the initiator 187*4882a593Smuzhiyun with the most leading zeroes wins and the other transmitter has to 188*4882a593Smuzhiyun stop transmitting ('Arbitration Lost'). This is very hard to test, 189*4882a593Smuzhiyun except by using this error injection command. 190*4882a593Smuzhiyun 191*4882a593Smuzhiyun This does not work if the remote CEC transmitter has logical address 192*4882a593Smuzhiyun 0 ('TV') since that will always win. 193*4882a593Smuzhiyun 194*4882a593SmuzhiyunTransmit Messages 195*4882a593Smuzhiyun----------------- 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun``tx-ignore-nack-until-eom`` 198*4882a593Smuzhiyun This setting changes the behavior of transmitting CEC messages. Normally 199*4882a593Smuzhiyun as soon as the receiver NACKs a byte the transmit will stop, but the 200*4882a593Smuzhiyun specification also allows that the full message is transmitted and only 201*4882a593Smuzhiyun at the end will the transmitter look at the ACK bit. This is not 202*4882a593Smuzhiyun recommended behavior since there is no point in keeping the CEC bus busy 203*4882a593Smuzhiyun for longer than is strictly needed. Especially given how slow the bus is. 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun This setting can be used to test how well a receiver deals with 206*4882a593Smuzhiyun transmitters that ignore NACKs until the very end of the message. 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun``<op>[,<mode>] tx-no-eom`` 209*4882a593Smuzhiyun Don't set the EOM bit. Normally the last byte of the message has the EOM 210*4882a593Smuzhiyun (End-Of-Message) bit set. With this command the transmit will just stop 211*4882a593Smuzhiyun without ever sending an EOM. This can be used to test how a receiver 212*4882a593Smuzhiyun handles this case. Normally receivers have a time-out after which 213*4882a593Smuzhiyun they will go back to the Idle state. 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun``<op>[,<mode>] tx-early-eom`` 216*4882a593Smuzhiyun Set the EOM bit one byte too soon. This obviously only works for messages 217*4882a593Smuzhiyun of two bytes or more. The EOM bit will be set for the second-to-last byte 218*4882a593Smuzhiyun and not for the final byte. The receiver should ignore the last byte in 219*4882a593Smuzhiyun this case. Since the resulting message is likely to be too short for this 220*4882a593Smuzhiyun same reason the whole message is typically ignored. The receiver should be 221*4882a593Smuzhiyun in Idle state after the last byte was transmitted. 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun``<op>[,<mode>] tx-add-bytes <num>`` 224*4882a593Smuzhiyun Append ``<num>`` (1-255) spurious bytes to the message. The extra bytes 225*4882a593Smuzhiyun have the value of the byte position in the message. So if you transmit a 226*4882a593Smuzhiyun two byte message (e.g. a Get CEC Version message) and add 2 bytes, then 227*4882a593Smuzhiyun the full message received by the remote CEC adapter is 228*4882a593Smuzhiyun ``0x40 0x9f 0x02 0x03``. 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun This command can be used to test buffer overflows in the receiver. E.g. 231*4882a593Smuzhiyun what does it do when it receives more than the maximum message size of 16 232*4882a593Smuzhiyun bytes. 233*4882a593Smuzhiyun 234*4882a593Smuzhiyun``<op>[,<mode>] tx-remove-byte`` 235*4882a593Smuzhiyun Drop the last byte from the message, provided the message is at least 236*4882a593Smuzhiyun two bytes long. The receiver should ignore messages that are too short. 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun``<op>[,<mode>] tx-short-bit <bit>`` 239*4882a593Smuzhiyun Make this bit period shorter than allowed. The bit position cannot be 240*4882a593Smuzhiyun an Ack bit. If <op> specifies a specific CEC opcode then the bit position 241*4882a593Smuzhiyun must be at least 18, otherwise the opcode hasn't been received yet. 242*4882a593Smuzhiyun Normally the period of a data bit is between 2.05 and 2.75 milliseconds. 243*4882a593Smuzhiyun With this command the period of this bit is 1.8 milliseconds, this is 244*4882a593Smuzhiyun done by reducing the time the CEC bus is high. This bit period is less 245*4882a593Smuzhiyun than is allowed and the receiver should respond with a Low Drive 246*4882a593Smuzhiyun condition. 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun This command is ignored for 0 bits in bit positions 0 to 3. This is 249*4882a593Smuzhiyun because the receiver also looks for an Arbitration Lost condition in 250*4882a593Smuzhiyun those first four bits and it is undefined what will happen if it 251*4882a593Smuzhiyun sees a too-short 0 bit. 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun``<op>[,<mode>] tx-long-bit <bit>`` 254*4882a593Smuzhiyun Make this bit period longer than is valid. The bit position cannot be 255*4882a593Smuzhiyun an Ack bit. If <op> specifies a specific CEC opcode then the bit position 256*4882a593Smuzhiyun must be at least 18, otherwise the opcode hasn't been received yet. 257*4882a593Smuzhiyun Normally the period of a data bit is between 2.05 and 2.75 milliseconds. 258*4882a593Smuzhiyun With this command the period of this bit is 2.9 milliseconds, this is 259*4882a593Smuzhiyun done by increasing the time the CEC bus is high. 260*4882a593Smuzhiyun 261*4882a593Smuzhiyun Even though this bit period is longer than is valid it is undefined what 262*4882a593Smuzhiyun a receiver will do. It might just accept it, or it might time out and 263*4882a593Smuzhiyun return to Idle state. Unfortunately the CEC specification is silent about 264*4882a593Smuzhiyun this. 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun This command is ignored for 0 bits in bit positions 0 to 3. This is 267*4882a593Smuzhiyun because the receiver also looks for an Arbitration Lost condition in 268*4882a593Smuzhiyun those first four bits and it is undefined what will happen if it 269*4882a593Smuzhiyun sees a too-long 0 bit. 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun``<op>[,<mode>] tx-short-start`` 272*4882a593Smuzhiyun Make this start bit period shorter than allowed. Normally the period of 273*4882a593Smuzhiyun a start bit is between 4.3 and 4.7 milliseconds. With this command the 274*4882a593Smuzhiyun period of the start bit is 4.1 milliseconds, this is done by reducing 275*4882a593Smuzhiyun the time the CEC bus is high. This start bit period is less than is 276*4882a593Smuzhiyun allowed and the receiver should return to Idle state when this is detected. 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun``<op>[,<mode>] tx-long-start`` 279*4882a593Smuzhiyun Make this start bit period longer than is valid. Normally the period of 280*4882a593Smuzhiyun a start bit is between 4.3 and 4.7 milliseconds. With this command the 281*4882a593Smuzhiyun period of the start bit is 5 milliseconds, this is done by increasing 282*4882a593Smuzhiyun the time the CEC bus is high. This start bit period is more than is 283*4882a593Smuzhiyun valid and the receiver should return to Idle state when this is detected. 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun Even though this start bit period is longer than is valid it is undefined 286*4882a593Smuzhiyun what a receiver will do. It might just accept it, or it might time out and 287*4882a593Smuzhiyun return to Idle state. Unfortunately the CEC specification is silent about 288*4882a593Smuzhiyun this. 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun``<op>[,<mode>] tx-last-bit <bit>`` 291*4882a593Smuzhiyun Just stop transmitting after this bit. If <op> specifies a specific CEC 292*4882a593Smuzhiyun opcode then the bit position must be at least 18, otherwise the opcode 293*4882a593Smuzhiyun hasn't been received yet. This command can be used to test how the receiver 294*4882a593Smuzhiyun reacts when a message just suddenly stops. It should time out and go back 295*4882a593Smuzhiyun to Idle state. 296*4882a593Smuzhiyun 297*4882a593Smuzhiyun``<op>[,<mode>] tx-low-drive <bit>`` 298*4882a593Smuzhiyun Force a Low Drive condition at this bit position. If <op> specifies a 299*4882a593Smuzhiyun specific CEC opcode then the bit position must be at least 18, otherwise 300*4882a593Smuzhiyun the opcode hasn't been received yet. This can be used to test how the 301*4882a593Smuzhiyun receiver handles Low Drive conditions. Note that if this happens at bit 302*4882a593Smuzhiyun positions 0-3 the receiver can interpret this as an Arbitration Lost 303*4882a593Smuzhiyun condition. This is implementation dependent. 304*4882a593Smuzhiyun 305*4882a593SmuzhiyunCustom Pulses 306*4882a593Smuzhiyun------------- 307*4882a593Smuzhiyun 308*4882a593Smuzhiyun``tx-custom-low-usecs <usecs>`` 309*4882a593Smuzhiyun This defines the duration in microseconds that the custom pulse pulls 310*4882a593Smuzhiyun the CEC line low. The default is 1000 microseconds. 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun``tx-custom-high-usecs <usecs>`` 313*4882a593Smuzhiyun This defines the duration in microseconds that the custom pulse keeps the 314*4882a593Smuzhiyun CEC line high (unless another CEC adapter pulls it low in that time). 315*4882a593Smuzhiyun The default is 1000 microseconds. The total period of the custom pulse is 316*4882a593Smuzhiyun ``tx-custom-low-usecs + tx-custom-high-usecs``. 317*4882a593Smuzhiyun 318*4882a593Smuzhiyun``<op>[,<mode>] tx-custom-bit <bit>`` 319*4882a593Smuzhiyun Send the custom bit instead of a regular data bit. The bit position cannot 320*4882a593Smuzhiyun be an Ack bit. If <op> specifies a specific CEC opcode then the bit 321*4882a593Smuzhiyun position must be at least 18, otherwise the opcode hasn't been received yet. 322*4882a593Smuzhiyun 323*4882a593Smuzhiyun``<op>[,<mode>] tx-custom-start`` 324*4882a593Smuzhiyun Send the custom bit instead of a regular start bit. 325*4882a593Smuzhiyun 326*4882a593Smuzhiyun``tx-custom-pulse`` 327*4882a593Smuzhiyun Transmit a single custom pulse as soon as the CEC bus is idle. 328