1 // SPDX-License-Identifier: GPL-2.0
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:
8 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0253_1.0.0.pdf
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.
13 * Copyright (c) 2021 Code Construct
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>
24 #include <linux/mctp.h>
26 #include <net/pkt_sched.h>
28 #define MCTP_SERIAL_MTU 68 /* base mtu (64) + mctp header */
29 #define MCTP_SERIAL_FRAME_MTU (MCTP_SERIAL_MTU + 6) /* + serial framing */
31 #define MCTP_SERIAL_VERSION 0x1 /* DSP0253 defines a single version: 1 */
33 #define BUFSIZE MCTP_SERIAL_FRAME_MTU
35 #define BYTE_FRAME 0x7e
38 #define FCS_INIT 0xffff
40 static DEFINE_IDA(mctp_serial_ida);
42 enum mctp_serial_state {
54 struct net_device *netdev;
55 struct tty_struct *tty;
59 /* protects our rx & tx state machines; held during both paths */
62 struct work_struct tx_work;
63 enum mctp_serial_state txstate, rxstate;
64 u16 txfcs, rxfcs, rxfcs_rcvd;
65 unsigned int txlen, rxlen;
66 unsigned int txpos, rxpos;
67 unsigned char txbuf[BUFSIZE],
71 static bool needs_escape(unsigned char c)
73 return c == BYTE_ESC || c == BYTE_FRAME;
76 static int next_chunk_len(struct mctp_serial *dev)
80 /* either we have no bytes to send ... */
81 if (dev->txpos == dev->txlen)
84 /* ... or the next byte to send is an escaped byte; requiring a
85 * single-byte chunk...
87 if (needs_escape(dev->txbuf[dev->txpos]))
90 /* ... or we have one or more bytes up to the next escape - this chunk
91 * will be those non-escaped bytes, and does not include the escaped
94 for (i = 1; i + dev->txpos + 1 < dev->txlen; i++) {
95 if (needs_escape(dev->txbuf[dev->txpos + i + 1]))
102 static int write_chunk(struct mctp_serial *dev, unsigned char *buf, int len)
104 return dev->tty->ops->write(dev->tty, buf, len);
107 static void mctp_serial_tx_work(struct work_struct *work)
109 struct mctp_serial *dev = container_of(work, struct mctp_serial,
111 unsigned char c, buf[3];
115 spin_lock_irqsave(&dev->lock, flags);
117 /* txstate represents the next thing to send */
118 switch (dev->txstate) {
124 buf[1] = MCTP_SERIAL_VERSION;
128 dev->txfcs = crc_ccitt(FCS_INIT, buf + 1, 2);
130 txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
132 dev->txstate = STATE_ERR;
135 if (dev->txpos == 3) {
136 dev->txstate = STATE_DATA;
143 buf[0] = dev->txbuf[dev->txpos] & ~0x20;
144 txlen = write_chunk(dev, buf, 1);
146 dev->txstate = STATE_ERR;
149 if (dev->txpos == dev->txlen) {
150 dev->txstate = STATE_TRAILER;
158 len = next_chunk_len(dev);
160 c = dev->txbuf[dev->txpos];
161 if (len == 1 && needs_escape(c)) {
164 dev->txfcs = crc_ccitt_byte(dev->txfcs, c);
165 txlen = write_chunk(dev, buf, 2);
169 dev->txstate = STATE_ESCAPE;
171 dev->txstate = STATE_ERR;
173 txlen = write_chunk(dev,
174 dev->txbuf + dev->txpos,
177 dev->txstate = STATE_ERR;
179 dev->txfcs = crc_ccitt(dev->txfcs,
186 if (dev->txstate == STATE_DATA &&
187 dev->txpos == dev->txlen) {
188 dev->txstate = STATE_TRAILER;
193 dev->txstate = STATE_TRAILER;
198 buf[0] = dev->txfcs >> 8;
199 buf[1] = dev->txfcs & 0xff;
201 txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
203 dev->txstate = STATE_ERR;
206 if (dev->txpos == 3) {
207 dev->txstate = STATE_DONE;
213 netdev_err_once(dev->netdev, "invalid tx state %d\n",
217 if (dev->txstate == STATE_DONE) {
218 dev->netdev->stats.tx_packets++;
219 dev->netdev->stats.tx_bytes += dev->txlen;
222 clear_bit(TTY_DO_WRITE_WAKEUP, &dev->tty->flags);
223 dev->txstate = STATE_IDLE;
224 spin_unlock_irqrestore(&dev->lock, flags);
226 netif_wake_queue(dev->netdev);
228 spin_unlock_irqrestore(&dev->lock, flags);
232 static netdev_tx_t mctp_serial_tx(struct sk_buff *skb, struct net_device *ndev)
234 struct mctp_serial *dev = netdev_priv(ndev);
237 WARN_ON(dev->txstate != STATE_IDLE);
239 if (skb->len > MCTP_SERIAL_MTU) {
240 dev->netdev->stats.tx_dropped++;
244 spin_lock_irqsave(&dev->lock, flags);
245 netif_stop_queue(dev->netdev);
246 skb_copy_bits(skb, 0, dev->txbuf, skb->len);
248 dev->txlen = skb->len;
249 dev->txstate = STATE_START;
250 spin_unlock_irqrestore(&dev->lock, flags);
252 set_bit(TTY_DO_WRITE_WAKEUP, &dev->tty->flags);
253 schedule_work(&dev->tx_work);
260 static void mctp_serial_tty_write_wakeup(struct tty_struct *tty)
262 struct mctp_serial *dev = tty->disc_data;
264 schedule_work(&dev->tx_work);
267 static void mctp_serial_rx(struct mctp_serial *dev)
269 struct mctp_skb_cb *cb;
272 if (dev->rxfcs != dev->rxfcs_rcvd) {
273 dev->netdev->stats.rx_dropped++;
274 dev->netdev->stats.rx_crc_errors++;
278 skb = netdev_alloc_skb(dev->netdev, dev->rxlen);
280 dev->netdev->stats.rx_dropped++;
284 skb->protocol = htons(ETH_P_MCTP);
285 skb_put_data(skb, dev->rxbuf, dev->rxlen);
286 skb_reset_network_header(skb);
292 dev->netdev->stats.rx_packets++;
293 dev->netdev->stats.rx_bytes += dev->rxlen;
296 static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
298 switch (dev->rxpos) {
303 dev->rxstate = STATE_ERR;
306 if (c == MCTP_SERIAL_VERSION) {
308 dev->rxfcs = crc_ccitt_byte(FCS_INIT, c);
310 dev->rxstate = STATE_ERR;
314 if (c > MCTP_SERIAL_FRAME_MTU) {
315 dev->rxstate = STATE_ERR;
319 dev->rxstate = STATE_DATA;
320 dev->rxfcs = crc_ccitt_byte(dev->rxfcs, c);
326 static void mctp_serial_push_trailer(struct mctp_serial *dev, unsigned char c)
328 switch (dev->rxpos) {
330 dev->rxfcs_rcvd = c << 8;
334 dev->rxfcs_rcvd |= c;
338 if (c != BYTE_FRAME) {
339 dev->rxstate = STATE_ERR;
344 dev->rxstate = STATE_IDLE;
350 static void mctp_serial_push(struct mctp_serial *dev, unsigned char c)
352 switch (dev->rxstate) {
354 dev->rxstate = STATE_HEADER;
357 mctp_serial_push_header(dev, c);
364 if (dev->rxstate != STATE_ESCAPE && c == BYTE_ESC) {
365 dev->rxstate = STATE_ESCAPE;
367 dev->rxfcs = crc_ccitt_byte(dev->rxfcs, c);
368 dev->rxbuf[dev->rxpos] = c;
370 dev->rxstate = STATE_DATA;
371 if (dev->rxpos == dev->rxlen) {
373 dev->rxstate = STATE_TRAILER;
379 mctp_serial_push_trailer(dev, c);
384 dev->rxstate = STATE_IDLE;
388 netdev_err_once(dev->netdev, "invalid rx state %d\n",
393 static void mctp_serial_tty_receive_buf(struct tty_struct *tty,
394 const unsigned char *c,
395 const char *f, int len)
397 struct mctp_serial *dev = tty->disc_data;
400 if (!netif_running(dev->netdev))
403 /* we don't (currently) use the flag bytes, just data. */
404 for (i = 0; i < len; i++)
405 mctp_serial_push(dev, c[i]);
408 static void mctp_serial_uninit(struct net_device *ndev)
410 struct mctp_serial *dev = netdev_priv(ndev);
412 cancel_work_sync(&dev->tx_work);
415 static const struct net_device_ops mctp_serial_netdev_ops = {
416 .ndo_start_xmit = mctp_serial_tx,
417 .ndo_uninit = mctp_serial_uninit,
420 static void mctp_serial_setup(struct net_device *ndev)
422 ndev->type = ARPHRD_MCTP;
424 /* we limit at the fixed MTU, which is also the MCTP-standard
425 * baseline MTU, so is also our minimum
427 ndev->mtu = MCTP_SERIAL_MTU;
428 ndev->max_mtu = MCTP_SERIAL_MTU;
429 ndev->min_mtu = MCTP_SERIAL_MTU;
431 ndev->hard_header_len = 0;
433 ndev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
434 ndev->flags = IFF_NOARP;
435 ndev->netdev_ops = &mctp_serial_netdev_ops;
436 ndev->needs_free_netdev = true;
439 static int mctp_serial_open(struct tty_struct *tty)
441 struct mctp_serial *dev;
442 struct net_device *ndev;
446 if (!capable(CAP_NET_ADMIN))
449 if (!tty->ops->write)
452 idx = ida_alloc(&mctp_serial_ida, GFP_KERNEL);
456 snprintf(name, sizeof(name), "mctpserial%d", idx);
457 ndev = alloc_netdev(sizeof(*dev), name, NET_NAME_ENUM,
464 dev = netdev_priv(ndev);
468 dev->txstate = STATE_IDLE;
469 dev->rxstate = STATE_IDLE;
470 spin_lock_init(&dev->lock);
471 INIT_WORK(&dev->tx_work, mctp_serial_tx_work);
473 rc = register_netdev(ndev);
477 tty->receive_room = 64 * 1024;
478 tty->disc_data = dev;
486 ida_free(&mctp_serial_ida, idx);
490 static void mctp_serial_close(struct tty_struct *tty)
492 struct mctp_serial *dev = tty->disc_data;
495 unregister_netdev(dev->netdev);
496 ida_free(&mctp_serial_ida, idx);
499 static struct tty_ldisc_ops mctp_ldisc = {
500 .owner = THIS_MODULE,
503 .open = mctp_serial_open,
504 .close = mctp_serial_close,
505 .receive_buf = mctp_serial_tty_receive_buf,
506 .write_wakeup = mctp_serial_tty_write_wakeup,
509 static int __init mctp_serial_init(void)
511 return tty_register_ldisc(&mctp_ldisc);
514 static void __exit mctp_serial_exit(void)
516 tty_unregister_ldisc(&mctp_ldisc);
519 module_init(mctp_serial_init);
520 module_exit(mctp_serial_exit);
522 MODULE_LICENSE("GPL v2");
524 MODULE_DESCRIPTION("MCTP Serial transport");