1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Management Component Transport Protocol (MCTP) - serial transport
4 * binding. This driver is an implementation of the DMTF specificiation
5 * "DSP0253 - Management Component Transport Protocol (MCTP) Serial Transport
6 * Binding", available at:
7 *
8 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0253_1.0.0.pdf
9 *
10 * This driver provides DSP0253-type MCTP-over-serial transport using a Linux
11 * tty device, by setting the N_MCTP line discipline on the tty.
12 *
13 * Copyright (c) 2021 Code Construct
14 */
15
16 #include <linux/idr.h>
17 #include <linux/if_arp.h>
18 #include <linux/module.h>
19 #include <linux/skbuff.h>
20 #include <linux/tty.h>
21 #include <linux/workqueue.h>
22 #include <linux/crc-ccitt.h>
23
24 #include <linux/mctp.h>
25 #include <net/mctp.h>
26 #include <net/pkt_sched.h>
27
28 #define MCTP_SERIAL_MTU 68 /* base mtu (64) + mctp header */
29 #define MCTP_SERIAL_FRAME_MTU (MCTP_SERIAL_MTU + 6) /* + serial framing */
30
31 #define MCTP_SERIAL_VERSION 0x1 /* DSP0253 defines a single version: 1 */
32
33 #define BUFSIZE MCTP_SERIAL_FRAME_MTU
34
35 #define BYTE_FRAME 0x7e
36 #define BYTE_ESC 0x7d
37
38 static DEFINE_IDA(mctp_serial_ida);
39
40 enum mctp_serial_state {
41 STATE_IDLE,
42 STATE_START,
43 STATE_HEADER,
44 STATE_DATA,
45 STATE_ESCAPE,
46 STATE_TRAILER,
47 STATE_DONE,
48 STATE_ERR,
49 };
50
51 struct mctp_serial {
52 struct net_device *netdev;
53 struct tty_struct *tty;
54
55 int idx;
56
57 /* protects our rx & tx state machines; held during both paths */
58 spinlock_t lock;
59
60 struct work_struct tx_work;
61 enum mctp_serial_state txstate, rxstate;
62 u16 txfcs, rxfcs, rxfcs_rcvd;
63 unsigned int txlen, rxlen;
64 unsigned int txpos, rxpos;
65 unsigned char txbuf[BUFSIZE],
66 rxbuf[BUFSIZE];
67 };
68
needs_escape(unsigned char c)69 static bool needs_escape(unsigned char c)
70 {
71 return c == BYTE_ESC || c == BYTE_FRAME;
72 }
73
next_chunk_len(struct mctp_serial * dev)74 static int next_chunk_len(struct mctp_serial *dev)
75 {
76 int i;
77
78 /* either we have no bytes to send ... */
79 if (dev->txpos == dev->txlen)
80 return 0;
81
82 /* ... or the next byte to send is an escaped byte; requiring a
83 * single-byte chunk...
84 */
85 if (needs_escape(dev->txbuf[dev->txpos]))
86 return 1;
87
88 /* ... or we have one or more bytes up to the next escape - this chunk
89 * will be those non-escaped bytes, and does not include the escaped
90 * byte.
91 */
92 for (i = 1; i + dev->txpos + 1 < dev->txlen; i++) {
93 if (needs_escape(dev->txbuf[dev->txpos + i + 1]))
94 break;
95 }
96
97 return i;
98 }
99
write_chunk(struct mctp_serial * dev,unsigned char * buf,int len)100 static int write_chunk(struct mctp_serial *dev, unsigned char *buf, int len)
101 {
102 return dev->tty->ops->write(dev->tty, buf, len);
103 }
104
mctp_serial_tx_work(struct work_struct * work)105 static void mctp_serial_tx_work(struct work_struct *work)
106 {
107 struct mctp_serial *dev = container_of(work, struct mctp_serial,
108 tx_work);
109 unsigned char c, buf[3];
110 unsigned long flags;
111 int len, txlen;
112
113 spin_lock_irqsave(&dev->lock, flags);
114
115 /* txstate represents the next thing to send */
116 switch (dev->txstate) {
117 case STATE_START:
118 dev->txpos = 0;
119 fallthrough;
120 case STATE_HEADER:
121 buf[0] = BYTE_FRAME;
122 buf[1] = MCTP_SERIAL_VERSION;
123 buf[2] = dev->txlen;
124
125 if (!dev->txpos)
126 dev->txfcs = crc_ccitt(0, buf + 1, 2);
127
128 txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
129 if (txlen <= 0) {
130 dev->txstate = STATE_ERR;
131 } else {
132 dev->txpos += txlen;
133 if (dev->txpos == 3) {
134 dev->txstate = STATE_DATA;
135 dev->txpos = 0;
136 }
137 }
138 break;
139
140 case STATE_ESCAPE:
141 buf[0] = dev->txbuf[dev->txpos] & ~0x20;
142 txlen = write_chunk(dev, buf, 1);
143 if (txlen <= 0) {
144 dev->txstate = STATE_ERR;
145 } else {
146 dev->txpos += txlen;
147 if (dev->txpos == dev->txlen) {
148 dev->txstate = STATE_TRAILER;
149 dev->txpos = 0;
150 }
151 }
152
153 break;
154
155 case STATE_DATA:
156 len = next_chunk_len(dev);
157 if (len) {
158 c = dev->txbuf[dev->txpos];
159 if (len == 1 && needs_escape(c)) {
160 buf[0] = BYTE_ESC;
161 buf[1] = c & ~0x20;
162 dev->txfcs = crc_ccitt_byte(dev->txfcs, c);
163 txlen = write_chunk(dev, buf, 2);
164 if (txlen == 2)
165 dev->txpos++;
166 else if (txlen == 1)
167 dev->txstate = STATE_ESCAPE;
168 else
169 dev->txstate = STATE_ERR;
170 } else {
171 txlen = write_chunk(dev,
172 dev->txbuf + dev->txpos,
173 len);
174 if (txlen <= 0) {
175 dev->txstate = STATE_ERR;
176 } else {
177 dev->txfcs = crc_ccitt(dev->txfcs,
178 dev->txbuf +
179 dev->txpos,
180 txlen);
181 dev->txpos += txlen;
182 }
183 }
184 if (dev->txstate == STATE_DATA &&
185 dev->txpos == dev->txlen) {
186 dev->txstate = STATE_TRAILER;
187 dev->txpos = 0;
188 }
189 break;
190 }
191 dev->txstate = STATE_TRAILER;
192 dev->txpos = 0;
193 fallthrough;
194
195 case STATE_TRAILER:
196 buf[0] = dev->txfcs >> 8;
197 buf[1] = dev->txfcs & 0xff;
198 buf[2] = BYTE_FRAME;
199 txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
200 if (txlen <= 0) {
201 dev->txstate = STATE_ERR;
202 } else {
203 dev->txpos += txlen;
204 if (dev->txpos == 3) {
205 dev->txstate = STATE_DONE;
206 dev->txpos = 0;
207 }
208 }
209 break;
210 default:
211 netdev_err_once(dev->netdev, "invalid tx state %d\n",
212 dev->txstate);
213 }
214
215 if (dev->txstate == STATE_DONE) {
216 dev->netdev->stats.tx_packets++;
217 dev->netdev->stats.tx_bytes += dev->txlen;
218 dev->txlen = 0;
219 dev->txpos = 0;
220 clear_bit(TTY_DO_WRITE_WAKEUP, &dev->tty->flags);
221 dev->txstate = STATE_IDLE;
222 spin_unlock_irqrestore(&dev->lock, flags);
223
224 netif_wake_queue(dev->netdev);
225 } else {
226 spin_unlock_irqrestore(&dev->lock, flags);
227 }
228 }
229
mctp_serial_tx(struct sk_buff * skb,struct net_device * ndev)230 static netdev_tx_t mctp_serial_tx(struct sk_buff *skb, struct net_device *ndev)
231 {
232 struct mctp_serial *dev = netdev_priv(ndev);
233 unsigned long flags;
234
235 WARN_ON(dev->txstate != STATE_IDLE);
236
237 if (skb->len > MCTP_SERIAL_MTU) {
238 dev->netdev->stats.tx_dropped++;
239 goto out;
240 }
241
242 spin_lock_irqsave(&dev->lock, flags);
243 netif_stop_queue(dev->netdev);
244 skb_copy_bits(skb, 0, dev->txbuf, skb->len);
245 dev->txpos = 0;
246 dev->txlen = skb->len;
247 dev->txstate = STATE_START;
248 spin_unlock_irqrestore(&dev->lock, flags);
249
250 set_bit(TTY_DO_WRITE_WAKEUP, &dev->tty->flags);
251 schedule_work(&dev->tx_work);
252
253 out:
254 kfree_skb(skb);
255 return NETDEV_TX_OK;
256 }
257
mctp_serial_tty_write_wakeup(struct tty_struct * tty)258 static void mctp_serial_tty_write_wakeup(struct tty_struct *tty)
259 {
260 struct mctp_serial *dev = tty->disc_data;
261
262 schedule_work(&dev->tx_work);
263 }
264
mctp_serial_rx(struct mctp_serial * dev)265 static void mctp_serial_rx(struct mctp_serial *dev)
266 {
267 struct mctp_skb_cb *cb;
268 struct sk_buff *skb;
269
270 if (dev->rxfcs != dev->rxfcs_rcvd) {
271 dev->netdev->stats.rx_dropped++;
272 dev->netdev->stats.rx_crc_errors++;
273 return;
274 }
275
276 skb = netdev_alloc_skb(dev->netdev, dev->rxlen);
277 if (!skb) {
278 dev->netdev->stats.rx_dropped++;
279 return;
280 }
281
282 skb->protocol = htons(ETH_P_MCTP);
283 skb_put_data(skb, dev->rxbuf, dev->rxlen);
284 skb_reset_network_header(skb);
285
286 cb = __mctp_cb(skb);
287 cb->halen = 0;
288
289 netif_rx(skb);
290 dev->netdev->stats.rx_packets++;
291 dev->netdev->stats.rx_bytes += dev->rxlen;
292 }
293
mctp_serial_push_header(struct mctp_serial * dev,unsigned char c)294 static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
295 {
296 switch (dev->rxpos) {
297 case 0:
298 if (c == BYTE_FRAME)
299 dev->rxpos++;
300 else
301 dev->rxstate = STATE_ERR;
302 break;
303 case 1:
304 if (c == MCTP_SERIAL_VERSION) {
305 dev->rxpos++;
306 dev->rxfcs = crc_ccitt_byte(0, c);
307 } else {
308 dev->rxstate = STATE_ERR;
309 }
310 break;
311 case 2:
312 if (c > MCTP_SERIAL_FRAME_MTU) {
313 dev->rxstate = STATE_ERR;
314 } else {
315 dev->rxlen = c;
316 dev->rxpos = 0;
317 dev->rxstate = STATE_DATA;
318 dev->rxfcs = crc_ccitt_byte(dev->rxfcs, c);
319 }
320 break;
321 }
322 }
323
mctp_serial_push_trailer(struct mctp_serial * dev,unsigned char c)324 static void mctp_serial_push_trailer(struct mctp_serial *dev, unsigned char c)
325 {
326 switch (dev->rxpos) {
327 case 0:
328 dev->rxfcs_rcvd = c << 8;
329 dev->rxpos++;
330 break;
331 case 1:
332 dev->rxfcs_rcvd |= c;
333 dev->rxpos++;
334 break;
335 case 2:
336 if (c != BYTE_FRAME) {
337 dev->rxstate = STATE_ERR;
338 } else {
339 mctp_serial_rx(dev);
340 dev->rxlen = 0;
341 dev->rxpos = 0;
342 dev->rxstate = STATE_IDLE;
343 }
344 break;
345 }
346 }
347
mctp_serial_push(struct mctp_serial * dev,unsigned char c)348 static void mctp_serial_push(struct mctp_serial *dev, unsigned char c)
349 {
350 switch (dev->rxstate) {
351 case STATE_IDLE:
352 dev->rxstate = STATE_HEADER;
353 fallthrough;
354 case STATE_HEADER:
355 mctp_serial_push_header(dev, c);
356 break;
357
358 case STATE_ESCAPE:
359 c |= 0x20;
360 fallthrough;
361 case STATE_DATA:
362 if (dev->rxstate != STATE_ESCAPE && c == BYTE_ESC) {
363 dev->rxstate = STATE_ESCAPE;
364 } else {
365 dev->rxfcs = crc_ccitt_byte(dev->rxfcs, c);
366 dev->rxbuf[dev->rxpos] = c;
367 dev->rxpos++;
368 dev->rxstate = STATE_DATA;
369 if (dev->rxpos == dev->rxlen) {
370 dev->rxpos = 0;
371 dev->rxstate = STATE_TRAILER;
372 }
373 }
374 break;
375
376 case STATE_TRAILER:
377 mctp_serial_push_trailer(dev, c);
378 break;
379
380 case STATE_ERR:
381 if (c == BYTE_FRAME)
382 dev->rxstate = STATE_IDLE;
383 break;
384
385 default:
386 netdev_err_once(dev->netdev, "invalid rx state %d\n",
387 dev->rxstate);
388 }
389 }
390
mctp_serial_tty_receive_buf(struct tty_struct * tty,const unsigned char * c,const char * f,int len)391 static void mctp_serial_tty_receive_buf(struct tty_struct *tty,
392 const unsigned char *c,
393 const char *f, int len)
394 {
395 struct mctp_serial *dev = tty->disc_data;
396 int i;
397
398 if (!netif_running(dev->netdev))
399 return;
400
401 /* we don't (currently) use the flag bytes, just data. */
402 for (i = 0; i < len; i++)
403 mctp_serial_push(dev, c[i]);
404 }
405
mctp_serial_uninit(struct net_device * ndev)406 static void mctp_serial_uninit(struct net_device *ndev)
407 {
408 struct mctp_serial *dev = netdev_priv(ndev);
409
410 cancel_work_sync(&dev->tx_work);
411 }
412
413 static const struct net_device_ops mctp_serial_netdev_ops = {
414 .ndo_start_xmit = mctp_serial_tx,
415 .ndo_uninit = mctp_serial_uninit,
416 };
417
mctp_serial_setup(struct net_device * ndev)418 static void mctp_serial_setup(struct net_device *ndev)
419 {
420 ndev->type = ARPHRD_MCTP;
421
422 /* we limit at the fixed MTU, which is also the MCTP-standard
423 * baseline MTU, so is also our minimum
424 */
425 ndev->mtu = MCTP_SERIAL_MTU;
426 ndev->max_mtu = MCTP_SERIAL_MTU;
427 ndev->min_mtu = MCTP_SERIAL_MTU;
428
429 ndev->hard_header_len = 0;
430 ndev->addr_len = 0;
431 ndev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
432 ndev->flags = IFF_NOARP;
433 ndev->netdev_ops = &mctp_serial_netdev_ops;
434 ndev->needs_free_netdev = true;
435 }
436
mctp_serial_open(struct tty_struct * tty)437 static int mctp_serial_open(struct tty_struct *tty)
438 {
439 struct mctp_serial *dev;
440 struct net_device *ndev;
441 char name[32];
442 int idx, rc;
443
444 if (!capable(CAP_NET_ADMIN))
445 return -EPERM;
446
447 if (!tty->ops->write)
448 return -EOPNOTSUPP;
449
450 idx = ida_alloc(&mctp_serial_ida, GFP_KERNEL);
451 if (idx < 0)
452 return idx;
453
454 snprintf(name, sizeof(name), "mctpserial%d", idx);
455 ndev = alloc_netdev(sizeof(*dev), name, NET_NAME_ENUM,
456 mctp_serial_setup);
457 if (!ndev) {
458 rc = -ENOMEM;
459 goto free_ida;
460 }
461
462 dev = netdev_priv(ndev);
463 dev->idx = idx;
464 dev->tty = tty;
465 dev->netdev = ndev;
466 dev->txstate = STATE_IDLE;
467 dev->rxstate = STATE_IDLE;
468 spin_lock_init(&dev->lock);
469 INIT_WORK(&dev->tx_work, mctp_serial_tx_work);
470
471 rc = register_netdev(ndev);
472 if (rc)
473 goto free_netdev;
474
475 tty->receive_room = 64 * 1024;
476 tty->disc_data = dev;
477
478 return 0;
479
480 free_netdev:
481 free_netdev(ndev);
482
483 free_ida:
484 ida_free(&mctp_serial_ida, idx);
485 return rc;
486 }
487
mctp_serial_close(struct tty_struct * tty)488 static void mctp_serial_close(struct tty_struct *tty)
489 {
490 struct mctp_serial *dev = tty->disc_data;
491 int idx = dev->idx;
492
493 unregister_netdev(dev->netdev);
494 ida_free(&mctp_serial_ida, idx);
495 }
496
497 static struct tty_ldisc_ops mctp_ldisc = {
498 .owner = THIS_MODULE,
499 .num = N_MCTP,
500 .name = "mctp",
501 .open = mctp_serial_open,
502 .close = mctp_serial_close,
503 .receive_buf = mctp_serial_tty_receive_buf,
504 .write_wakeup = mctp_serial_tty_write_wakeup,
505 };
506
mctp_serial_init(void)507 static int __init mctp_serial_init(void)
508 {
509 return tty_register_ldisc(&mctp_ldisc);
510 }
511
mctp_serial_exit(void)512 static void __exit mctp_serial_exit(void)
513 {
514 tty_unregister_ldisc(&mctp_ldisc);
515 }
516
517 module_init(mctp_serial_init);
518 module_exit(mctp_serial_exit);
519
520 MODULE_LICENSE("GPL v2");
521 MODULE_AUTHOR("Jeremy Kerr <jk@codeconstruct.com.au>");
522 MODULE_DESCRIPTION("MCTP Serial transport");
523