Merge tag 'for-v5.17-rc' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux...
[linux-2.6-microblaze.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 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 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");