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