// SPDX-License-Identifier: GPL-2.0
/*
 * Management Component Transport Protocol (MCTP) - serial transport
 * binding. This driver is an implementation of the DMTF specificiation
 * "DSP0253 - Management Component Transport Protocol (MCTP) Serial Transport
 * Binding", available at:
 *
 *  https://www.dmtf.org/sites/default/files/standards/documents/DSP0253_1.0.0.pdf
 *
 * This driver provides DSP0253-type MCTP-over-serial transport using a Linux
 * tty device, by setting the N_MCTP line discipline on the tty.
 *
 * Copyright (c) 2021 Code Construct
 */

#include <linux/idr.h>
#include <linux/if_arp.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/tty.h>
#include <linux/workqueue.h>
#include <linux/crc-ccitt.h>

#include <linux/mctp.h>
#include <net/mctp.h>
#include <net/pkt_sched.h>

#define MCTP_SERIAL_MTU		68 /* base mtu (64) + mctp header */
#define MCTP_SERIAL_FRAME_MTU	(MCTP_SERIAL_MTU + 6) /* + serial framing */

#define MCTP_SERIAL_VERSION	0x1 /* DSP0253 defines a single version: 1 */

#define BUFSIZE			MCTP_SERIAL_FRAME_MTU

#define BYTE_FRAME		0x7e
#define BYTE_ESC		0x7d

#define FCS_INIT		0xffff

static DEFINE_IDA(mctp_serial_ida);

enum mctp_serial_state {
	STATE_IDLE,
	STATE_START,
	STATE_HEADER,
	STATE_DATA,
	STATE_ESCAPE,
	STATE_TRAILER,
	STATE_DONE,
	STATE_ERR,
};

struct mctp_serial {
	struct net_device	*netdev;
	struct tty_struct	*tty;

	int			idx;

	/* protects our rx & tx state machines; held during both paths */
	spinlock_t		lock;

	struct work_struct	tx_work;
	enum mctp_serial_state	txstate, rxstate;
	u16			txfcs, rxfcs, rxfcs_rcvd;
	unsigned int		txlen, rxlen;
	unsigned int		txpos, rxpos;
	unsigned char		txbuf[BUFSIZE],
				rxbuf[BUFSIZE];
};

static bool needs_escape(unsigned char c)
{
	return c == BYTE_ESC || c == BYTE_FRAME;
}

static int next_chunk_len(struct mctp_serial *dev)
{
	int i;

	/* either we have no bytes to send ... */
	if (dev->txpos == dev->txlen)
		return 0;

	/* ... or the next byte to send is an escaped byte; requiring a
	 * single-byte chunk...
	 */
	if (needs_escape(dev->txbuf[dev->txpos]))
		return 1;

	/* ... or we have one or more bytes up to the next escape - this chunk
	 * will be those non-escaped bytes, and does not include the escaped
	 * byte.
	 */
	for (i = 1; i + dev->txpos + 1 < dev->txlen; i++) {
		if (needs_escape(dev->txbuf[dev->txpos + i + 1]))
			break;
	}

	return i;
}

static int write_chunk(struct mctp_serial *dev, unsigned char *buf, int len)
{
	return dev->tty->ops->write(dev->tty, buf, len);
}

static void mctp_serial_tx_work(struct work_struct *work)
{
	struct mctp_serial *dev = container_of(work, struct mctp_serial,
					       tx_work);
	unsigned char c, buf[3];
	unsigned long flags;
	int len, txlen;

	spin_lock_irqsave(&dev->lock, flags);

	/* txstate represents the next thing to send */
	switch (dev->txstate) {
	case STATE_START:
		dev->txpos = 0;
		fallthrough;
	case STATE_HEADER:
		buf[0] = BYTE_FRAME;
		buf[1] = MCTP_SERIAL_VERSION;
		buf[2] = dev->txlen;

		if (!dev->txpos)
			dev->txfcs = crc_ccitt(FCS_INIT, buf + 1, 2);

		txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
		if (txlen <= 0) {
			dev->txstate = STATE_ERR;
		} else {
			dev->txpos += txlen;
			if (dev->txpos == 3) {
				dev->txstate = STATE_DATA;
				dev->txpos = 0;
			}
		}
		break;

	case STATE_ESCAPE:
		buf[0] = dev->txbuf[dev->txpos] & ~0x20;
		txlen = write_chunk(dev, buf, 1);
		if (txlen <= 0) {
			dev->txstate = STATE_ERR;
		} else {
			dev->txpos += txlen;
			if (dev->txpos == dev->txlen) {
				dev->txstate = STATE_TRAILER;
				dev->txpos = 0;
			}
		}

		break;

	case STATE_DATA:
		len = next_chunk_len(dev);
		if (len) {
			c = dev->txbuf[dev->txpos];
			if (len == 1 && needs_escape(c)) {
				buf[0] = BYTE_ESC;
				buf[1] = c & ~0x20;
				dev->txfcs = crc_ccitt_byte(dev->txfcs, c);
				txlen = write_chunk(dev, buf, 2);
				if (txlen == 2)
					dev->txpos++;
				else if (txlen == 1)
					dev->txstate = STATE_ESCAPE;
				else
					dev->txstate = STATE_ERR;
			} else {
				txlen = write_chunk(dev,
						    dev->txbuf + dev->txpos,
						    len);
				if (txlen <= 0) {
					dev->txstate = STATE_ERR;
				} else {
					dev->txfcs = crc_ccitt(dev->txfcs,
							       dev->txbuf +
							       dev->txpos,
							       txlen);
					dev->txpos += txlen;
				}
			}
			if (dev->txstate == STATE_DATA &&
			    dev->txpos == dev->txlen) {
				dev->txstate = STATE_TRAILER;
				dev->txpos = 0;
			}
			break;
		}
		dev->txstate = STATE_TRAILER;
		dev->txpos = 0;
		fallthrough;

	case STATE_TRAILER:
		buf[0] = dev->txfcs >> 8;
		buf[1] = dev->txfcs & 0xff;
		buf[2] = BYTE_FRAME;
		txlen = write_chunk(dev, buf + dev->txpos, 3 - dev->txpos);
		if (txlen <= 0) {
			dev->txstate = STATE_ERR;
		} else {
			dev->txpos += txlen;
			if (dev->txpos == 3) {
				dev->txstate = STATE_DONE;
				dev->txpos = 0;
			}
		}
		break;
	default:
		netdev_err_once(dev->netdev, "invalid tx state %d\n",
				dev->txstate);
	}

	if (dev->txstate == STATE_DONE) {
		dev->netdev->stats.tx_packets++;
		dev->netdev->stats.tx_bytes += dev->txlen;
		dev->txlen = 0;
		dev->txpos = 0;
		clear_bit(TTY_DO_WRITE_WAKEUP, &dev->tty->flags);
		dev->txstate = STATE_IDLE;
		spin_unlock_irqrestore(&dev->lock, flags);

		netif_wake_queue(dev->netdev);
	} else {
		spin_unlock_irqrestore(&dev->lock, flags);
	}
}

static netdev_tx_t mctp_serial_tx(struct sk_buff *skb, struct net_device *ndev)
{
	struct mctp_serial *dev = netdev_priv(ndev);
	unsigned long flags;

	WARN_ON(dev->txstate != STATE_IDLE);

	if (skb->len > MCTP_SERIAL_MTU) {
		dev->netdev->stats.tx_dropped++;
		goto out;
	}

	spin_lock_irqsave(&dev->lock, flags);
	netif_stop_queue(dev->netdev);
	skb_copy_bits(skb, 0, dev->txbuf, skb->len);
	dev->txpos = 0;
	dev->txlen = skb->len;
	dev->txstate = STATE_START;
	spin_unlock_irqrestore(&dev->lock, flags);

	set_bit(TTY_DO_WRITE_WAKEUP, &dev->tty->flags);
	schedule_work(&dev->tx_work);

out:
	kfree_skb(skb);
	return NETDEV_TX_OK;
}

static void mctp_serial_tty_write_wakeup(struct tty_struct *tty)
{
	struct mctp_serial *dev = tty->disc_data;

	schedule_work(&dev->tx_work);
}

static void mctp_serial_rx(struct mctp_serial *dev)
{
	struct mctp_skb_cb *cb;
	struct sk_buff *skb;

	if (dev->rxfcs != dev->rxfcs_rcvd) {
		dev->netdev->stats.rx_dropped++;
		dev->netdev->stats.rx_crc_errors++;
		return;
	}

	skb = netdev_alloc_skb(dev->netdev, dev->rxlen);
	if (!skb) {
		dev->netdev->stats.rx_dropped++;
		return;
	}

	skb->protocol = htons(ETH_P_MCTP);
	skb_put_data(skb, dev->rxbuf, dev->rxlen);
	skb_reset_network_header(skb);

	cb = __mctp_cb(skb);
	cb->halen = 0;

	netif_rx(skb);
	dev->netdev->stats.rx_packets++;
	dev->netdev->stats.rx_bytes += dev->rxlen;
}

static void mctp_serial_push_header(struct mctp_serial *dev, unsigned char c)
{
	switch (dev->rxpos) {
	case 0:
		if (c == BYTE_FRAME)
			dev->rxpos++;
		else
			dev->rxstate = STATE_ERR;
		break;
	case 1:
		if (c == MCTP_SERIAL_VERSION) {
			dev->rxpos++;
			dev->rxfcs = crc_ccitt_byte(FCS_INIT, c);
		} else {
			dev->rxstate = STATE_ERR;
		}
		break;
	case 2:
		if (c > MCTP_SERIAL_FRAME_MTU) {
			dev->rxstate = STATE_ERR;
		} else {
			dev->rxlen = c;
			dev->rxpos = 0;
			dev->rxstate = STATE_DATA;
			dev->rxfcs = crc_ccitt_byte(dev->rxfcs, c);
		}
		break;
	}
}

static void mctp_serial_push_trailer(struct mctp_serial *dev, unsigned char c)
{
	switch (dev->rxpos) {
	case 0:
		dev->rxfcs_rcvd = c << 8;
		dev->rxpos++;
		break;
	case 1:
		dev->rxfcs_rcvd |= c;
		dev->rxpos++;
		break;
	case 2:
		if (c != BYTE_FRAME) {
			dev->rxstate = STATE_ERR;
		} else {
			mctp_serial_rx(dev);
			dev->rxlen = 0;
			dev->rxpos = 0;
			dev->rxstate = STATE_IDLE;
		}
		break;
	}
}

static void mctp_serial_push(struct mctp_serial *dev, unsigned char c)
{
	switch (dev->rxstate) {
	case STATE_IDLE:
		dev->rxstate = STATE_HEADER;
		fallthrough;
	case STATE_HEADER:
		mctp_serial_push_header(dev, c);
		break;

	case STATE_ESCAPE:
		c |= 0x20;
		fallthrough;
	case STATE_DATA:
		if (dev->rxstate != STATE_ESCAPE && c == BYTE_ESC) {
			dev->rxstate = STATE_ESCAPE;
		} else {
			dev->rxfcs = crc_ccitt_byte(dev->rxfcs, c);
			dev->rxbuf[dev->rxpos] = c;
			dev->rxpos++;
			dev->rxstate = STATE_DATA;
			if (dev->rxpos == dev->rxlen) {
				dev->rxpos = 0;
				dev->rxstate = STATE_TRAILER;
			}
		}
		break;

	case STATE_TRAILER:
		mctp_serial_push_trailer(dev, c);
		break;

	case STATE_ERR:
		if (c == BYTE_FRAME)
			dev->rxstate = STATE_IDLE;
		break;

	default:
		netdev_err_once(dev->netdev, "invalid rx state %d\n",
				dev->rxstate);
	}
}

static void mctp_serial_tty_receive_buf(struct tty_struct *tty, const u8 *c,
					const u8 *f, size_t len)
{
	struct mctp_serial *dev = tty->disc_data;
	int i;

	if (!netif_running(dev->netdev))
		return;

	/* we don't (currently) use the flag bytes, just data. */
	for (i = 0; i < len; i++)
		mctp_serial_push(dev, c[i]);
}

static void mctp_serial_uninit(struct net_device *ndev)
{
	struct mctp_serial *dev = netdev_priv(ndev);

	cancel_work_sync(&dev->tx_work);
}

static const struct net_device_ops mctp_serial_netdev_ops = {
	.ndo_start_xmit = mctp_serial_tx,
	.ndo_uninit = mctp_serial_uninit,
};

static void mctp_serial_setup(struct net_device *ndev)
{
	ndev->type = ARPHRD_MCTP;

	/* we limit at the fixed MTU, which is also the MCTP-standard
	 * baseline MTU, so is also our minimum
	 */
	ndev->mtu = MCTP_SERIAL_MTU;
	ndev->max_mtu = MCTP_SERIAL_MTU;
	ndev->min_mtu = MCTP_SERIAL_MTU;

	ndev->hard_header_len = 0;
	ndev->addr_len = 0;
	ndev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
	ndev->flags = IFF_NOARP;
	ndev->netdev_ops = &mctp_serial_netdev_ops;
	ndev->needs_free_netdev = true;
}

static int mctp_serial_open(struct tty_struct *tty)
{
	struct mctp_serial *dev;
	struct net_device *ndev;
	char name[32];
	int idx, rc;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (!tty->ops->write)
		return -EOPNOTSUPP;

	idx = ida_alloc(&mctp_serial_ida, GFP_KERNEL);
	if (idx < 0)
		return idx;

	snprintf(name, sizeof(name), "mctpserial%d", idx);
	ndev = alloc_netdev(sizeof(*dev), name, NET_NAME_ENUM,
			    mctp_serial_setup);
	if (!ndev) {
		rc = -ENOMEM;
		goto free_ida;
	}

	dev = netdev_priv(ndev);
	dev->idx = idx;
	dev->tty = tty;
	dev->netdev = ndev;
	dev->txstate = STATE_IDLE;
	dev->rxstate = STATE_IDLE;
	spin_lock_init(&dev->lock);
	INIT_WORK(&dev->tx_work, mctp_serial_tx_work);

	rc = register_netdev(ndev);
	if (rc)
		goto free_netdev;

	tty->receive_room = 64 * 1024;
	tty->disc_data = dev;

	return 0;

free_netdev:
	free_netdev(ndev);

free_ida:
	ida_free(&mctp_serial_ida, idx);
	return rc;
}

static void mctp_serial_close(struct tty_struct *tty)
{
	struct mctp_serial *dev = tty->disc_data;
	int idx = dev->idx;

	unregister_netdev(dev->netdev);
	ida_free(&mctp_serial_ida, idx);
}

static struct tty_ldisc_ops mctp_ldisc = {
	.owner		= THIS_MODULE,
	.num		= N_MCTP,
	.name		= "mctp",
	.open		= mctp_serial_open,
	.close		= mctp_serial_close,
	.receive_buf	= mctp_serial_tty_receive_buf,
	.write_wakeup	= mctp_serial_tty_write_wakeup,
};

static int __init mctp_serial_init(void)
{
	return tty_register_ldisc(&mctp_ldisc);
}

static void __exit mctp_serial_exit(void)
{
	tty_unregister_ldisc(&mctp_ldisc);
}

module_init(mctp_serial_init);
module_exit(mctp_serial_exit);

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Jeremy Kerr <jk@codeconstruct.com.au>");
MODULE_DESCRIPTION("MCTP Serial transport");
