xref: /openbmc/linux/drivers/net/mctp/mctp-serial.c (revision e2aa5e65)
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_ni(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 const struct net_device_ops mctp_serial_netdev_ops = {
407 	.ndo_start_xmit = mctp_serial_tx,
408 };
409 
410 static void mctp_serial_setup(struct net_device *ndev)
411 {
412 	ndev->type = ARPHRD_MCTP;
413 
414 	/* we limit at the fixed MTU, which is also the MCTP-standard
415 	 * baseline MTU, so is also our minimum
416 	 */
417 	ndev->mtu = MCTP_SERIAL_MTU;
418 	ndev->max_mtu = MCTP_SERIAL_MTU;
419 	ndev->min_mtu = MCTP_SERIAL_MTU;
420 
421 	ndev->hard_header_len = 0;
422 	ndev->addr_len = 0;
423 	ndev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
424 	ndev->flags = IFF_NOARP;
425 	ndev->netdev_ops = &mctp_serial_netdev_ops;
426 	ndev->needs_free_netdev = true;
427 }
428 
429 static int mctp_serial_open(struct tty_struct *tty)
430 {
431 	struct mctp_serial *dev;
432 	struct net_device *ndev;
433 	char name[32];
434 	int idx, rc;
435 
436 	if (!capable(CAP_NET_ADMIN))
437 		return -EPERM;
438 
439 	if (!tty->ops->write)
440 		return -EOPNOTSUPP;
441 
442 	idx = ida_alloc(&mctp_serial_ida, GFP_KERNEL);
443 	if (idx < 0)
444 		return idx;
445 
446 	snprintf(name, sizeof(name), "mctpserial%d", idx);
447 	ndev = alloc_netdev(sizeof(*dev), name, NET_NAME_ENUM,
448 			    mctp_serial_setup);
449 	if (!ndev) {
450 		rc = -ENOMEM;
451 		goto free_ida;
452 	}
453 
454 	dev = netdev_priv(ndev);
455 	dev->idx = idx;
456 	dev->tty = tty;
457 	dev->netdev = ndev;
458 	dev->txstate = STATE_IDLE;
459 	dev->rxstate = STATE_IDLE;
460 	spin_lock_init(&dev->lock);
461 	INIT_WORK(&dev->tx_work, mctp_serial_tx_work);
462 
463 	rc = register_netdev(ndev);
464 	if (rc)
465 		goto free_netdev;
466 
467 	tty->receive_room = 64 * 1024;
468 	tty->disc_data = dev;
469 
470 	return 0;
471 
472 free_netdev:
473 	free_netdev(ndev);
474 
475 free_ida:
476 	ida_free(&mctp_serial_ida, idx);
477 	return rc;
478 }
479 
480 static void mctp_serial_close(struct tty_struct *tty)
481 {
482 	struct mctp_serial *dev = tty->disc_data;
483 	int idx = dev->idx;
484 
485 	unregister_netdev(dev->netdev);
486 	cancel_work_sync(&dev->tx_work);
487 	ida_free(&mctp_serial_ida, idx);
488 }
489 
490 static struct tty_ldisc_ops mctp_ldisc = {
491 	.owner		= THIS_MODULE,
492 	.num		= N_MCTP,
493 	.name		= "mctp",
494 	.open		= mctp_serial_open,
495 	.close		= mctp_serial_close,
496 	.receive_buf	= mctp_serial_tty_receive_buf,
497 	.write_wakeup	= mctp_serial_tty_write_wakeup,
498 };
499 
500 static int __init mctp_serial_init(void)
501 {
502 	return tty_register_ldisc(&mctp_ldisc);
503 }
504 
505 static void __exit mctp_serial_exit(void)
506 {
507 	tty_unregister_ldisc(&mctp_ldisc);
508 }
509 
510 module_init(mctp_serial_init);
511 module_exit(mctp_serial_exit);
512 
513 MODULE_LICENSE("GPL v2");
514 MODULE_AUTHOR("Jeremy Kerr <jk@codeconstruct.com.au>");
515 MODULE_DESCRIPTION("MCTP Serial transport");
516