Skip to content

Commit b23a842

Browse files
vincent-mailholmarckleinebudde
authored andcommitted
can: netlink: add can_validate_tdc()
Factorise the TDC validation out of can_validate() and move it in the new can_validate_tdc() function. This is a preparation patch for the introduction of CAN XL because this TDC validation will be reused later on. Signed-off-by: Vincent Mailhol <mailhol@kernel.org> Link: https://patch.msgid.link/20250923-canxl-netlink-prep-v4-5-e720d28f66fe@kernel.org Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
1 parent f5ae5a7 commit b23a842

2 files changed

Lines changed: 52 additions & 34 deletions

File tree

drivers/net/can/dev/netlink.c

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,49 @@ static int can_validate_bittiming(struct nlattr *data[],
5757
return 0;
5858
}
5959

60+
static int can_validate_tdc(struct nlattr *data_tdc,
61+
struct netlink_ext_ack *extack, u32 tdc_flags)
62+
{
63+
bool tdc_manual = tdc_flags & CAN_CTRLMODE_TDC_MANUAL_MASK;
64+
bool tdc_auto = tdc_flags & CAN_CTRLMODE_TDC_AUTO_MASK;
65+
int err;
66+
67+
/* CAN_CTRLMODE_TDC_{AUTO,MANUAL} are mutually exclusive */
68+
if (tdc_auto && tdc_manual)
69+
return -EOPNOTSUPP;
70+
71+
/* If one of the CAN_CTRLMODE_TDC_* flag is set then TDC
72+
* must be set and vice-versa
73+
*/
74+
if ((tdc_auto || tdc_manual) != !!data_tdc)
75+
return -EOPNOTSUPP;
76+
77+
/* If providing TDC parameters, at least TDCO is needed. TDCV
78+
* is needed if and only if CAN_CTRLMODE_TDC_MANUAL is set
79+
*/
80+
if (data_tdc) {
81+
struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1];
82+
83+
err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX,
84+
data_tdc, can_tdc_policy, extack);
85+
if (err)
86+
return err;
87+
88+
if (tb_tdc[IFLA_CAN_TDC_TDCV]) {
89+
if (tdc_auto)
90+
return -EOPNOTSUPP;
91+
} else {
92+
if (tdc_manual)
93+
return -EOPNOTSUPP;
94+
}
95+
96+
if (!tb_tdc[IFLA_CAN_TDC_TDCO])
97+
return -EOPNOTSUPP;
98+
}
99+
100+
return 0;
101+
}
102+
60103
static int can_validate(struct nlattr *tb[], struct nlattr *data[],
61104
struct netlink_ext_ack *extack)
62105
{
@@ -67,50 +110,21 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
67110
* - nominal/arbitration bittiming
68111
* - data bittiming
69112
* - control mode with CAN_CTRLMODE_FD set
70-
* - TDC parameters are coherent (details below)
113+
* - TDC parameters are coherent (details in can_validate_tdc())
71114
*/
72115

73116
if (!data)
74117
return 0;
75118

76119
if (data[IFLA_CAN_CTRLMODE]) {
77120
struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
78-
u32 tdc_flags = cm->flags & CAN_CTRLMODE_FD_TDC_MASK;
79121

80122
is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD;
81123

82-
/* CAN_CTRLMODE_TDC_{AUTO,MANUAL} are mutually exclusive */
83-
if (tdc_flags == CAN_CTRLMODE_FD_TDC_MASK)
84-
return -EOPNOTSUPP;
85-
/* If one of the CAN_CTRLMODE_TDC_* flag is set then
86-
* TDC must be set and vice-versa
87-
*/
88-
if (!!tdc_flags != !!data[IFLA_CAN_TDC])
89-
return -EOPNOTSUPP;
90-
/* If providing TDC parameters, at least TDCO is
91-
* needed. TDCV is needed if and only if
92-
* CAN_CTRLMODE_TDC_MANUAL is set
93-
*/
94-
if (data[IFLA_CAN_TDC]) {
95-
struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1];
96-
97-
err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX,
98-
data[IFLA_CAN_TDC],
99-
can_tdc_policy, extack);
100-
if (err)
101-
return err;
102-
103-
if (tb_tdc[IFLA_CAN_TDC_TDCV]) {
104-
if (tdc_flags & CAN_CTRLMODE_TDC_AUTO)
105-
return -EOPNOTSUPP;
106-
} else {
107-
if (tdc_flags & CAN_CTRLMODE_TDC_MANUAL)
108-
return -EOPNOTSUPP;
109-
}
110-
111-
if (!tb_tdc[IFLA_CAN_TDC_TDCO])
112-
return -EOPNOTSUPP;
113-
}
124+
err = can_validate_tdc(data[IFLA_CAN_TDC], extack,
125+
cm->flags & CAN_CTRLMODE_FD_TDC_MASK);
126+
if (err)
127+
return err;
114128
}
115129

116130
err = can_validate_bittiming(data, extack, IFLA_CAN_BITTIMING);

include/linux/can/bittiming.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616

1717
#define CAN_CTRLMODE_FD_TDC_MASK \
1818
(CAN_CTRLMODE_TDC_AUTO | CAN_CTRLMODE_TDC_MANUAL)
19+
#define CAN_CTRLMODE_TDC_AUTO_MASK \
20+
(CAN_CTRLMODE_TDC_AUTO)
21+
#define CAN_CTRLMODE_TDC_MANUAL_MASK \
22+
(CAN_CTRLMODE_TDC_MANUAL)
1923

2024
/*
2125
* struct can_tdc - CAN FD Transmission Delay Compensation parameters

0 commit comments

Comments
 (0)