Skip to content

Commit 33b83a9

Browse files
vincent-mailholgregkh
authored andcommitted
can: bittiming: allow TDC{V,O} to be zero and add can_tdc_const::tdc{v,o,f}_min
[ Upstream commit 63dfe07 ] ISO 11898-1 specifies in section 11.3.3 "Transmitter delay compensation" that "the configuration range for [the] SSP position shall be at least 0 to 63 minimum time quanta." Because SSP = TDCV + TDCO, it means that we should allow both TDCV and TDCO to hold zero value in order to honor SSP's minimum possible value. However, current implementation assigned special meaning to TDCV and TDCO's zero values: * TDCV = 0 -> TDCV is automatically measured by the transceiver. * TDCO = 0 -> TDC is off. In order to allow for those values to really be zero and to maintain current features, we introduce two new flags: * CAN_CTRLMODE_TDC_AUTO indicates that the controller support automatic measurement of TDCV. * CAN_CTRLMODE_TDC_MANUAL indicates that the controller support manual configuration of TDCV. N.B.: current implementation failed to provide an option for the driver to indicate that only manual mode was supported. TDC is disabled if both CAN_CTRLMODE_TDC_AUTO and CAN_CTRLMODE_TDC_MANUAL flags are off, c.f. the helper function can_tdc_is_enabled() which is also introduced in this patch. Also, this patch adds three fields: tdcv_min, tdco_min and tdcf_min to struct can_tdc_const. While we are not convinced that those three fields could be anything else than zero, we can imagine that some controllers might specify a lower bound on these. Thus, those minimums are really added "just in case". Comments of struct can_tdc and can_tdc_const are updated accordingly. Finally, the changes are applied to the etas_es58x driver. Link: https://lore.kernel.org/all/20210918095637.20108-2-mailhol.vincent@wanadoo.fr Signed-off-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de> Stable-dep-of: 38c0aba ("can: etas_es58x: populate ndo_change_mtu() to prevent buffer overflow") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d51c6b5 commit 33b83a9

5 files changed

Lines changed: 65 additions & 22 deletions

File tree

drivers/net/can/dev/bittiming.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,12 @@ void can_calc_tdco(struct net_device *dev)
182182
struct can_tdc *tdc = &priv->tdc;
183183
const struct can_tdc_const *tdc_const = priv->tdc_const;
184184

185-
if (!tdc_const)
185+
if (!tdc_const ||
186+
!(priv->ctrlmode_supported & CAN_CTRLMODE_TDC_AUTO))
186187
return;
187188

189+
priv->ctrlmode &= ~CAN_CTRLMODE_TDC_MASK;
190+
188191
/* As specified in ISO 11898-1 section 11.3.3 "Transmitter
189192
* delay compensation" (TDC) is only applicable if data BRP is
190193
* one or two.
@@ -193,9 +196,10 @@ void can_calc_tdco(struct net_device *dev)
193196
/* Reuse "normal" sample point and convert it to time quanta */
194197
u32 sample_point_in_tq = can_bit_time(dbt) * dbt->sample_point / 1000;
195198

199+
if (sample_point_in_tq < tdc_const->tdco_min)
200+
return;
196201
tdc->tdco = min(sample_point_in_tq, tdc_const->tdco_max);
197-
} else {
198-
tdc->tdco = 0;
202+
priv->ctrlmode |= CAN_CTRLMODE_TDC_AUTO;
199203
}
200204
}
201205
#endif /* CONFIG_CAN_CALC_BITTIMING */

drivers/net/can/usb/etas_es58x/es58x_fd.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ static int es58x_fd_enable_channel(struct es58x_priv *priv)
427427
es58x_fd_convert_bittiming(&tx_conf_msg.data_bittiming,
428428
&priv->can.data_bittiming);
429429

430-
if (priv->can.tdc.tdco) {
430+
if (can_tdc_is_enabled(&priv->can)) {
431431
tx_conf_msg.tdc_enabled = 1;
432432
tx_conf_msg.tdco = cpu_to_le16(priv->can.tdc.tdco);
433433
tx_conf_msg.tdcf = cpu_to_le16(priv->can.tdc.tdcf);
@@ -504,8 +504,11 @@ static const struct can_bittiming_const es58x_fd_data_bittiming_const = {
504504
* Register" from Microchip.
505505
*/
506506
static const struct can_tdc_const es58x_tdc_const = {
507+
.tdcv_min = 0,
507508
.tdcv_max = 0, /* Manual mode not supported. */
509+
.tdco_min = 0,
508510
.tdco_max = 127,
511+
.tdcf_min = 0,
509512
.tdcf_max = 127
510513
};
511514

@@ -522,7 +525,7 @@ const struct es58x_parameters es58x_fd_param = {
522525
.clock = {.freq = 80 * CAN_MHZ},
523526
.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY |
524527
CAN_CTRLMODE_3_SAMPLES | CAN_CTRLMODE_FD | CAN_CTRLMODE_FD_NON_ISO |
525-
CAN_CTRLMODE_CC_LEN8_DLC,
528+
CAN_CTRLMODE_CC_LEN8_DLC | CAN_CTRLMODE_TDC_AUTO,
526529
.tx_start_of_frame = 0xCEFA, /* FACE in little endian */
527530
.rx_start_of_frame = 0xFECA, /* CAFE in little endian */
528531
.tx_urb_cmd_max_len = ES58X_FD_TX_URB_CMD_MAX_LEN,

include/linux/can/bittiming.h

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
/* Megahertz */
2020
#define CAN_MHZ 1000000UL
2121

22+
#define CAN_CTRLMODE_TDC_MASK \
23+
(CAN_CTRLMODE_TDC_AUTO | CAN_CTRLMODE_TDC_MANUAL)
24+
2225
/*
2326
* struct can_tdc - CAN FD Transmission Delay Compensation parameters
2427
*
@@ -33,29 +36,43 @@
3336
*
3437
* This structure contains the parameters to calculate that SSP.
3538
*
36-
* @tdcv: Transmitter Delay Compensation Value. Distance, in time
37-
* quanta, from when the bit is sent on the TX pin to when it is
38-
* received on the RX pin of the transmitter. Possible options:
39+
* -+----------- one bit ----------+-- TX pin
40+
* |<--- Sample Point --->|
41+
*
42+
* --+----------- one bit ----------+-- RX pin
43+
* |<-------- TDCV -------->|
44+
* |<------- TDCO ------->|
45+
* |<----------- Secondary Sample Point ---------->|
46+
*
47+
* @tdcv: Transmitter Delay Compensation Value. The time needed for
48+
* the signal to propagate, i.e. the distance, in time quanta,
49+
* from the start of the bit on the TX pin to when it is received
50+
* on the RX pin. @tdcv depends on the controller modes:
51+
*
52+
* CAN_CTRLMODE_TDC_AUTO is set: The transceiver dynamically
53+
* measures @tdcv for each transmitted CAN FD frame and the
54+
* value provided here should be ignored.
3955
*
40-
* 0: automatic mode. The controller dynamically measures @tdcv
41-
* for each transmitted CAN FD frame.
56+
* CAN_CTRLMODE_TDC_MANUAL is set: use the fixed provided @tdcv
57+
* value.
4258
*
43-
* Other values: manual mode. Use the fixed provided value.
59+
* N.B. CAN_CTRLMODE_TDC_AUTO and CAN_CTRLMODE_TDC_MANUAL are
60+
* mutually exclusive. Only one can be set at a time. If both
61+
* CAN_TDC_CTRLMODE_AUTO and CAN_TDC_CTRLMODE_MANUAL are unset,
62+
* TDC is disabled and all the values of this structure should be
63+
* ignored.
4464
*
4565
* @tdco: Transmitter Delay Compensation Offset. Offset value, in time
4666
* quanta, defining the distance between the start of the bit
4767
* reception on the RX pin of the transceiver and the SSP
4868
* position such that SSP = @tdcv + @tdco.
4969
*
50-
* If @tdco is zero, then TDC is disabled and both @tdcv and
51-
* @tdcf should be ignored.
52-
*
5370
* @tdcf: Transmitter Delay Compensation Filter window. Defines the
54-
* minimum value for the SSP position in time quanta. If SSP is
55-
* less than @tdcf, then no delay compensations occur and the
56-
* normal sampling point is used instead. The feature is enabled
57-
* if and only if @tdcv is set to zero (automatic mode) and @tdcf
58-
* is configured to a value greater than @tdco.
71+
* minimum value for the SSP position in time quanta. If the SSP
72+
* position is less than @tdcf, then no delay compensations occur
73+
* and the normal sampling point is used instead. The feature is
74+
* enabled if and only if @tdcv is set to zero (automatic mode)
75+
* and @tdcf is configured to a value greater than @tdco.
5976
*/
6077
struct can_tdc {
6178
u32 tdcv;
@@ -67,19 +84,32 @@ struct can_tdc {
6784
* struct can_tdc_const - CAN hardware-dependent constant for
6885
* Transmission Delay Compensation
6986
*
70-
* @tdcv_max: Transmitter Delay Compensation Value maximum value.
71-
* Should be set to zero if the controller does not support
72-
* manual mode for tdcv.
87+
* @tdcv_min: Transmitter Delay Compensation Value minimum value. If
88+
* the controller does not support manual mode for tdcv
89+
* (c.f. flag CAN_CTRLMODE_TDC_MANUAL) then this value is
90+
* ignored.
91+
* @tdcv_max: Transmitter Delay Compensation Value maximum value. If
92+
* the controller does not support manual mode for tdcv
93+
* (c.f. flag CAN_CTRLMODE_TDC_MANUAL) then this value is
94+
* ignored.
95+
*
96+
* @tdco_min: Transmitter Delay Compensation Offset minimum value.
7397
* @tdco_max: Transmitter Delay Compensation Offset maximum value.
7498
* Should not be zero. If the controller does not support TDC,
7599
* then the pointer to this structure should be NULL.
100+
*
101+
* @tdcf_min: Transmitter Delay Compensation Filter window minimum
102+
* value. If @tdcf_max is zero, this value is ignored.
76103
* @tdcf_max: Transmitter Delay Compensation Filter window maximum
77104
* value. Should be set to zero if the controller does not
78105
* support this feature.
79106
*/
80107
struct can_tdc_const {
108+
u32 tdcv_min;
81109
u32 tdcv_max;
110+
u32 tdco_min;
82111
u32 tdco_max;
112+
u32 tdcf_min;
83113
u32 tdcf_max;
84114
};
85115

include/linux/can/dev.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ struct can_priv {
9696
#endif
9797
};
9898

99+
static inline bool can_tdc_is_enabled(const struct can_priv *priv)
100+
{
101+
return !!(priv->ctrlmode & CAN_CTRLMODE_TDC_MASK);
102+
}
99103

100104
/* helper to define static CAN controller features at device creation time */
101105
static inline void can_set_static_ctrlmode(struct net_device *dev,

include/uapi/linux/can/netlink.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ struct can_ctrlmode {
101101
#define CAN_CTRLMODE_PRESUME_ACK 0x40 /* Ignore missing CAN ACKs */
102102
#define CAN_CTRLMODE_FD_NON_ISO 0x80 /* CAN FD in non-ISO mode */
103103
#define CAN_CTRLMODE_CC_LEN8_DLC 0x100 /* Classic CAN DLC option */
104+
#define CAN_CTRLMODE_TDC_AUTO 0x200 /* CAN transiver automatically calculates TDCV */
105+
#define CAN_CTRLMODE_TDC_MANUAL 0x400 /* TDCV is manually set up by user */
104106

105107
/*
106108
* CAN device statistics

0 commit comments

Comments
 (0)