1 // SPDX-License-Identifier: GPL-2.0
2
3 /* Copyright (c) 2025 Vincent Mailhol <mailhol@kernel.org> */
4
5 #include <linux/array_size.h>
6 #include <linux/errno.h>
7 #include <linux/init.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/netdevice.h>
11 #include <linux/units.h>
12 #include <linux/string_choices.h>
13
14 #include <linux/can.h>
15 #include <linux/can/bittiming.h>
16 #include <linux/can/dev.h>
17 #include <linux/can/skb.h>
18
19 struct dummy_can {
20 struct can_priv can;
21 struct net_device *dev;
22 };
23
24 static struct dummy_can *dummy_can;
25
26 static const struct can_bittiming_const dummy_can_bittiming_const = {
27 .name = "dummy_can CC",
28 .tseg1_min = 2,
29 .tseg1_max = 256,
30 .tseg2_min = 2,
31 .tseg2_max = 128,
32 .sjw_max = 128,
33 .brp_min = 1,
34 .brp_max = 512,
35 .brp_inc = 1
36 };
37
38 static const struct can_bittiming_const dummy_can_fd_databittiming_const = {
39 .name = "dummy_can FD",
40 .tseg1_min = 2,
41 .tseg1_max = 256,
42 .tseg2_min = 2,
43 .tseg2_max = 128,
44 .sjw_max = 128,
45 .brp_min = 1,
46 .brp_max = 512,
47 .brp_inc = 1
48 };
49
50 static const struct can_tdc_const dummy_can_fd_tdc_const = {
51 .tdcv_min = 0,
52 .tdcv_max = 0, /* Manual mode not supported. */
53 .tdco_min = 0,
54 .tdco_max = 127,
55 .tdcf_min = 0,
56 .tdcf_max = 127
57 };
58
59 static const struct can_bittiming_const dummy_can_xl_databittiming_const = {
60 .name = "dummy_can XL",
61 .tseg1_min = 2,
62 .tseg1_max = 256,
63 .tseg2_min = 2,
64 .tseg2_max = 128,
65 .sjw_max = 128,
66 .brp_min = 1,
67 .brp_max = 512,
68 .brp_inc = 1
69 };
70
71 static const struct can_tdc_const dummy_can_xl_tdc_const = {
72 .tdcv_min = 0,
73 .tdcv_max = 0, /* Manual mode not supported. */
74 .tdco_min = 0,
75 .tdco_max = 127,
76 .tdcf_min = 0,
77 .tdcf_max = 127
78 };
79
80 static const struct can_pwm_const dummy_can_pwm_const = {
81 .pwms_min = 1,
82 .pwms_max = 8,
83 .pwml_min = 2,
84 .pwml_max = 24,
85 .pwmo_min = 0,
86 .pwmo_max = 16,
87 };
88
dummy_can_print_bittiming(struct net_device * dev,struct can_bittiming * bt)89 static void dummy_can_print_bittiming(struct net_device *dev,
90 struct can_bittiming *bt)
91 {
92 netdev_dbg(dev, "\tbitrate: %u\n", bt->bitrate);
93 netdev_dbg(dev, "\tsample_point: %u\n", bt->sample_point);
94 netdev_dbg(dev, "\ttq: %u\n", bt->tq);
95 netdev_dbg(dev, "\tprop_seg: %u\n", bt->prop_seg);
96 netdev_dbg(dev, "\tphase_seg1: %u\n", bt->phase_seg1);
97 netdev_dbg(dev, "\tphase_seg2: %u\n", bt->phase_seg2);
98 netdev_dbg(dev, "\tsjw: %u\n", bt->sjw);
99 netdev_dbg(dev, "\tbrp: %u\n", bt->brp);
100 }
101
dummy_can_print_tdc(struct net_device * dev,struct can_tdc * tdc)102 static void dummy_can_print_tdc(struct net_device *dev, struct can_tdc *tdc)
103 {
104 netdev_dbg(dev, "\t\ttdcv: %u\n", tdc->tdcv);
105 netdev_dbg(dev, "\t\ttdco: %u\n", tdc->tdco);
106 netdev_dbg(dev, "\t\ttdcf: %u\n", tdc->tdcf);
107 }
108
dummy_can_print_pwm(struct net_device * dev,struct can_pwm * pwm,struct can_bittiming * dbt)109 static void dummy_can_print_pwm(struct net_device *dev, struct can_pwm *pwm,
110 struct can_bittiming *dbt)
111 {
112 netdev_dbg(dev, "\t\tpwms: %u\n", pwm->pwms);
113 netdev_dbg(dev, "\t\tpwml: %u\n", pwm->pwml);
114 netdev_dbg(dev, "\t\tpwmo: %u\n", pwm->pwmo);
115 }
116
dummy_can_print_ctrlmode(struct net_device * dev)117 static void dummy_can_print_ctrlmode(struct net_device *dev)
118 {
119 struct dummy_can *priv = netdev_priv(dev);
120 struct can_priv *can_priv = &priv->can;
121 unsigned long supported = can_priv->ctrlmode_supported;
122 u32 enabled = can_priv->ctrlmode;
123
124 netdev_dbg(dev, "Control modes:\n");
125 netdev_dbg(dev, "\tsupported: 0x%08x\n", (u32)supported);
126 netdev_dbg(dev, "\tenabled: 0x%08x\n", enabled);
127
128 if (supported) {
129 int idx;
130
131 netdev_dbg(dev, "\tlist:");
132 for_each_set_bit(idx, &supported, BITS_PER_TYPE(u32))
133 netdev_dbg(dev, "\t\t%s: %s\n",
134 can_get_ctrlmode_str(BIT(idx)),
135 enabled & BIT(idx) ? "on" : "off");
136 }
137 }
138
dummy_can_print_bittiming_info(struct net_device * dev)139 static void dummy_can_print_bittiming_info(struct net_device *dev)
140 {
141 struct dummy_can *priv = netdev_priv(dev);
142 struct can_priv *can_priv = &priv->can;
143
144 netdev_dbg(dev, "Clock frequency: %u\n", can_priv->clock.freq);
145 netdev_dbg(dev, "Maximum bitrate: %u\n", can_priv->bitrate_max);
146 netdev_dbg(dev, "MTU: %u\n", dev->mtu);
147 netdev_dbg(dev, "\n");
148
149 dummy_can_print_ctrlmode(dev);
150 netdev_dbg(dev, "\n");
151
152 netdev_dbg(dev, "Classical CAN nominal bittiming:\n");
153 dummy_can_print_bittiming(dev, &can_priv->bittiming);
154 netdev_dbg(dev, "\n");
155
156 if (can_priv->ctrlmode & CAN_CTRLMODE_FD) {
157 netdev_dbg(dev, "CAN FD databittiming:\n");
158 dummy_can_print_bittiming(dev, &can_priv->fd.data_bittiming);
159 if (can_fd_tdc_is_enabled(can_priv)) {
160 netdev_dbg(dev, "\tCAN FD TDC:\n");
161 dummy_can_print_tdc(dev, &can_priv->fd.tdc);
162 }
163 }
164 netdev_dbg(dev, "\n");
165
166 if (can_priv->ctrlmode & CAN_CTRLMODE_XL) {
167 netdev_dbg(dev, "CAN XL databittiming:\n");
168 dummy_can_print_bittiming(dev, &can_priv->xl.data_bittiming);
169 if (can_xl_tdc_is_enabled(can_priv)) {
170 netdev_dbg(dev, "\tCAN XL TDC:\n");
171 dummy_can_print_tdc(dev, &can_priv->xl.tdc);
172 }
173 if (can_priv->ctrlmode & CAN_CTRLMODE_XL_TMS) {
174 netdev_dbg(dev, "\tCAN XL PWM:\n");
175 dummy_can_print_pwm(dev, &can_priv->xl.pwm,
176 &can_priv->xl.data_bittiming);
177 }
178 }
179 netdev_dbg(dev, "\n");
180 }
181
dummy_can_netdev_open(struct net_device * dev)182 static int dummy_can_netdev_open(struct net_device *dev)
183 {
184 int ret;
185 struct can_priv *priv = netdev_priv(dev);
186
187 dummy_can_print_bittiming_info(dev);
188 netdev_dbg(dev, "error-signalling is %s\n",
189 str_enabled_disabled(!can_dev_in_xl_only_mode(priv)));
190
191 ret = open_candev(dev);
192 if (ret)
193 return ret;
194 netif_start_queue(dev);
195 netdev_dbg(dev, "dummy-can is up\n");
196
197 return 0;
198 }
199
dummy_can_netdev_close(struct net_device * dev)200 static int dummy_can_netdev_close(struct net_device *dev)
201 {
202 netif_stop_queue(dev);
203 close_candev(dev);
204 netdev_dbg(dev, "dummy-can is down\n");
205
206 return 0;
207 }
208
dummy_can_start_xmit(struct sk_buff * skb,struct net_device * dev)209 static netdev_tx_t dummy_can_start_xmit(struct sk_buff *skb,
210 struct net_device *dev)
211 {
212 if (can_dev_dropped_skb(dev, skb))
213 return NETDEV_TX_OK;
214
215 can_put_echo_skb(skb, dev, 0, 0);
216 dev->stats.tx_packets++;
217 dev->stats.tx_bytes += can_get_echo_skb(dev, 0, NULL);
218
219 return NETDEV_TX_OK;
220 }
221
222 static const struct net_device_ops dummy_can_netdev_ops = {
223 .ndo_open = dummy_can_netdev_open,
224 .ndo_stop = dummy_can_netdev_close,
225 .ndo_start_xmit = dummy_can_start_xmit,
226 };
227
228 static const struct ethtool_ops dummy_can_ethtool_ops = {
229 .get_ts_info = ethtool_op_get_ts_info,
230 };
231
dummy_can_init(void)232 static int __init dummy_can_init(void)
233 {
234 struct net_device *dev;
235 struct dummy_can *priv;
236 int ret;
237
238 dev = alloc_candev(sizeof(*priv), 1);
239 if (!dev)
240 return -ENOMEM;
241
242 dev->netdev_ops = &dummy_can_netdev_ops;
243 dev->ethtool_ops = &dummy_can_ethtool_ops;
244 dev->flags |= IFF_ECHO; /* enable echo handling */
245 priv = netdev_priv(dev);
246 priv->can.bittiming_const = &dummy_can_bittiming_const;
247 priv->can.bitrate_max = 20 * MEGA /* BPS */;
248 priv->can.clock.freq = 160 * MEGA /* Hz */;
249 priv->can.fd.data_bittiming_const = &dummy_can_fd_databittiming_const;
250 priv->can.fd.tdc_const = &dummy_can_fd_tdc_const;
251 priv->can.xl.data_bittiming_const = &dummy_can_xl_databittiming_const;
252 priv->can.xl.tdc_const = &dummy_can_xl_tdc_const;
253 priv->can.xl.pwm_const = &dummy_can_pwm_const;
254 priv->can.ctrlmode_supported = CAN_CTRLMODE_LISTENONLY |
255 CAN_CTRLMODE_FD | CAN_CTRLMODE_TDC_AUTO |
256 CAN_CTRLMODE_RESTRICTED | CAN_CTRLMODE_XL |
257 CAN_CTRLMODE_XL_TDC_AUTO | CAN_CTRLMODE_XL_TMS;
258 priv->dev = dev;
259
260 ret = register_candev(priv->dev);
261 if (ret) {
262 free_candev(priv->dev);
263 return ret;
264 }
265
266 dummy_can = priv;
267 netdev_dbg(dev, "dummy-can ready\n");
268
269 return 0;
270 }
271
dummy_can_exit(void)272 static void __exit dummy_can_exit(void)
273 {
274 struct net_device *dev = dummy_can->dev;
275
276 netdev_dbg(dev, "dummy-can bye bye\n");
277 unregister_candev(dev);
278 free_candev(dev);
279 }
280
281 module_init(dummy_can_init);
282 module_exit(dummy_can_exit);
283
284 MODULE_DESCRIPTION("A dummy CAN driver, mainly to test the netlink interface");
285 MODULE_LICENSE("GPL");
286 MODULE_AUTHOR("Vincent Mailhol <mailhol@kernel.org>");
287