xref: /openbmc/linux/drivers/net/mctp/mctp-serial.c (revision 7a2f6f61)
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 
69 static bool needs_escape(unsigned char c)
70 {
71 	return c == BYTE_ESC || c == BYTE_FRAME;
72 }
73 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
507 static int __init mctp_serial_init(void)
508 {
509 	return tty_register_ldisc(&mctp_ldisc);
510 }
511 
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