Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

can: isotp: set default value for N_As to 50 micro seconds

The N_As value describes the time a CAN frame needs on the wire when
transmitted by the CAN controller. Even very short CAN FD frames need
arround 100 usecs (bitrate 1Mbit/s, data bitrate 8Mbit/s).

Having N_As to be zero (the former default) leads to 'no CAN frame
separation' when STmin is set to zero by the receiving node. This 'burst
mode' should not be enabled by default as it could potentially dump a high
number of CAN frames into the netdev queue from the soft hrtimer context.
This does not affect the system stability but is just not nice and
cooperative.

With this N_As/frame_txtime value the 'burst mode' is disabled by default.

As user space applications usually do not set the frame_txtime element
of struct can_isotp_options the new in-kernel default is very likely
overwritten with zero when the sockopt() CAN_ISOTP_OPTS is invoked.
To make sure that a N_As value of zero is only set intentional the
value '0' is now interpreted as 'do not change the current value'.
When a frame_txtime of zero is required for testing purposes this
CAN_ISOTP_FRAME_TXTIME_ZERO u32 value has to be set in frame_txtime.

Link: https://lore.kernel.org/all/20220309120416.83514-2-socketcan@hartkopp.net
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>

authored by

Oliver Hartkopp and committed by
Marc Kleine-Budde
530e0d46 4b7fe92c

+33 -7
+22 -6
include/uapi/linux/can/isotp.h
··· 137 137 #define CAN_ISOTP_WAIT_TX_DONE 0x400 /* wait for tx completion */ 138 138 #define CAN_ISOTP_SF_BROADCAST 0x800 /* 1-to-N functional addressing */ 139 139 140 - /* default values */ 140 + /* protocol machine default values */ 141 141 142 142 #define CAN_ISOTP_DEFAULT_FLAGS 0 143 143 #define CAN_ISOTP_DEFAULT_EXT_ADDRESS 0x00 144 144 #define CAN_ISOTP_DEFAULT_PAD_CONTENT 0xCC /* prevent bit-stuffing */ 145 - #define CAN_ISOTP_DEFAULT_FRAME_TXTIME 0 145 + #define CAN_ISOTP_DEFAULT_FRAME_TXTIME 50000 /* 50 micro seconds */ 146 146 #define CAN_ISOTP_DEFAULT_RECV_BS 0 147 147 #define CAN_ISOTP_DEFAULT_RECV_STMIN 0x00 148 148 #define CAN_ISOTP_DEFAULT_RECV_WFTMAX 0 149 - 150 - #define CAN_ISOTP_DEFAULT_LL_MTU CAN_MTU 151 - #define CAN_ISOTP_DEFAULT_LL_TX_DL CAN_MAX_DLEN 152 - #define CAN_ISOTP_DEFAULT_LL_TX_FLAGS 0 153 149 154 150 /* 155 151 * Remark on CAN_ISOTP_DEFAULT_RECV_* values: ··· 157 161 * For that reason the STmin value is intentionally _not_ checked for 158 162 * consistency and copied directly into the flow control (FC) frame. 159 163 */ 164 + 165 + /* link layer default values => make use of Classical CAN frames */ 166 + 167 + #define CAN_ISOTP_DEFAULT_LL_MTU CAN_MTU 168 + #define CAN_ISOTP_DEFAULT_LL_TX_DL CAN_MAX_DLEN 169 + #define CAN_ISOTP_DEFAULT_LL_TX_FLAGS 0 170 + 171 + /* 172 + * The CAN_ISOTP_DEFAULT_FRAME_TXTIME has become a non-zero value as 173 + * it only makes sense for isotp implementation tests to run without 174 + * a N_As value. As user space applications usually do not set the 175 + * frame_txtime element of struct can_isotp_options the new in-kernel 176 + * default is very likely overwritten with zero when the sockopt() 177 + * CAN_ISOTP_OPTS is invoked. 178 + * To make sure that a N_As value of zero is only set intentional the 179 + * value '0' is now interpreted as 'do not change the current value'. 180 + * When a frame_txtime of zero is required for testing purposes this 181 + * CAN_ISOTP_FRAME_TXTIME_ZERO u32 value has to be set in frame_txtime. 182 + */ 183 + #define CAN_ISOTP_FRAME_TXTIME_ZERO 0xFFFFFFFF 160 184 161 185 #endif /* !_UAPI_CAN_ISOTP_H */
+11 -1
net/can/isotp.c
··· 140 140 struct can_isotp_options opt; 141 141 struct can_isotp_fc_options rxfc, txfc; 142 142 struct can_isotp_ll_options ll; 143 + u32 frame_txtime; 143 144 u32 force_tx_stmin; 144 145 u32 force_rx_stmin; 145 146 u32 cfecho; /* consecutive frame echo tag */ ··· 361 360 362 361 so->tx_gap = ktime_set(0, 0); 363 362 /* add transmission time for CAN frame N_As */ 364 - so->tx_gap = ktime_add_ns(so->tx_gap, so->opt.frame_txtime); 363 + so->tx_gap = ktime_add_ns(so->tx_gap, so->frame_txtime); 365 364 /* add waiting time for consecutive frames N_Cs */ 366 365 if (so->opt.flags & CAN_ISOTP_FORCE_TXSTMIN) 367 366 so->tx_gap = ktime_add_ns(so->tx_gap, ··· 1294 1293 /* no separate rx_ext_address is given => use ext_address */ 1295 1294 if (!(so->opt.flags & CAN_ISOTP_RX_EXT_ADDR)) 1296 1295 so->opt.rx_ext_address = so->opt.ext_address; 1296 + 1297 + /* check for frame_txtime changes (0 => no changes) */ 1298 + if (so->opt.frame_txtime) { 1299 + if (so->opt.frame_txtime == CAN_ISOTP_FRAME_TXTIME_ZERO) 1300 + so->frame_txtime = 0; 1301 + else 1302 + so->frame_txtime = so->opt.frame_txtime; 1303 + } 1297 1304 break; 1298 1305 1299 1306 case CAN_ISOTP_RECV_FC: ··· 1507 1498 so->opt.rxpad_content = CAN_ISOTP_DEFAULT_PAD_CONTENT; 1508 1499 so->opt.txpad_content = CAN_ISOTP_DEFAULT_PAD_CONTENT; 1509 1500 so->opt.frame_txtime = CAN_ISOTP_DEFAULT_FRAME_TXTIME; 1501 + so->frame_txtime = CAN_ISOTP_DEFAULT_FRAME_TXTIME; 1510 1502 so->rxfc.bs = CAN_ISOTP_DEFAULT_RECV_BS; 1511 1503 so->rxfc.stmin = CAN_ISOTP_DEFAULT_RECV_STMIN; 1512 1504 so->rxfc.wftmax = CAN_ISOTP_DEFAULT_RECV_WFTMAX;