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