1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */ 2 3 #include <assert.h> 4 #include <errno.h> 5 #include <stdarg.h> 6 #include <stddef.h> 7 #include <stdint.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #undef pr_fmt 13 #define pr_fmt(fmt) "core: " fmt 14 15 #include "libmctp.h" 16 #include "libmctp-alloc.h" 17 #include "libmctp-log.h" 18 #include "libmctp-cmds.h" 19 #include "range.h" 20 21 /* Internal data structures */ 22 23 enum mctp_bus_state { 24 mctp_bus_state_constructed = 0, 25 mctp_bus_state_tx_enabled, 26 mctp_bus_state_tx_disabled, 27 }; 28 29 struct mctp_bus { 30 mctp_eid_t eid; 31 struct mctp_binding *binding; 32 enum mctp_bus_state state; 33 34 struct mctp_pktbuf *tx_queue_head; 35 struct mctp_pktbuf *tx_queue_tail; 36 37 /* todo: routing */ 38 }; 39 40 struct mctp_msg_ctx { 41 uint8_t src; 42 uint8_t dest; 43 uint8_t tag; 44 uint8_t last_seq; 45 void *buf; 46 size_t buf_size; 47 size_t buf_alloc_size; 48 size_t fragment_size; 49 }; 50 51 struct mctp { 52 int n_busses; 53 struct mctp_bus *busses; 54 55 /* Message RX callback */ 56 mctp_rx_fn message_rx; 57 void *message_rx_data; 58 59 /* Packet capture callback */ 60 mctp_capture_fn capture; 61 void *capture_data; 62 63 /* Message reassembly. 64 * @todo: flexible context count 65 */ 66 struct mctp_msg_ctx msg_ctxs[16]; 67 68 enum { 69 ROUTE_ENDPOINT, 70 ROUTE_BRIDGE, 71 } route_policy; 72 size_t max_message_size; 73 }; 74 75 #ifndef BUILD_ASSERT 76 #define BUILD_ASSERT(x) \ 77 do { (void)sizeof(char[0-(!(x))]); } while (0) 78 #endif 79 80 #ifndef ARRAY_SIZE 81 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) 82 #endif 83 84 /* 64kb should be sufficient for a single message. Applications 85 * requiring higher sizes can override by setting max_message_size.*/ 86 #ifndef MCTP_MAX_MESSAGE_SIZE 87 #define MCTP_MAX_MESSAGE_SIZE 65536 88 #endif 89 90 static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src, 91 mctp_eid_t dest, void *msg, size_t msg_len); 92 93 struct mctp_pktbuf *mctp_pktbuf_alloc(struct mctp_binding *binding, size_t len) 94 { 95 struct mctp_pktbuf *buf; 96 size_t size; 97 98 size = binding->pkt_size + binding->pkt_header + binding->pkt_trailer; 99 100 /* todo: pools */ 101 buf = __mctp_alloc(sizeof(*buf) + size); 102 103 buf->size = size; 104 buf->start = binding->pkt_header; 105 buf->end = buf->start + len; 106 buf->mctp_hdr_off = buf->start; 107 buf->next = NULL; 108 109 return buf; 110 } 111 112 void mctp_pktbuf_free(struct mctp_pktbuf *pkt) 113 { 114 __mctp_free(pkt); 115 } 116 117 struct mctp_hdr *mctp_pktbuf_hdr(struct mctp_pktbuf *pkt) 118 { 119 return (void *)pkt->data + pkt->mctp_hdr_off; 120 } 121 122 void *mctp_pktbuf_data(struct mctp_pktbuf *pkt) 123 { 124 return (void *)pkt->data + pkt->mctp_hdr_off + sizeof(struct mctp_hdr); 125 } 126 127 size_t mctp_pktbuf_size(struct mctp_pktbuf *pkt) 128 { 129 return pkt->end - pkt->start; 130 } 131 132 void *mctp_pktbuf_alloc_start(struct mctp_pktbuf *pkt, size_t size) 133 { 134 assert(size <= pkt->start); 135 pkt->start -= size; 136 return pkt->data + pkt->start; 137 } 138 139 void *mctp_pktbuf_alloc_end(struct mctp_pktbuf *pkt, size_t size) 140 { 141 void *buf; 142 143 assert(size <= (pkt->size - pkt->end)); 144 buf = pkt->data + pkt->end; 145 pkt->end += size; 146 return buf; 147 } 148 149 int mctp_pktbuf_push(struct mctp_pktbuf *pkt, void *data, size_t len) 150 { 151 void *p; 152 153 if (pkt->end + len > pkt->size) 154 return -1; 155 156 p = pkt->data + pkt->end; 157 158 pkt->end += len; 159 memcpy(p, data, len); 160 161 return 0; 162 } 163 164 void *mctp_pktbuf_pop(struct mctp_pktbuf *pkt, size_t len) 165 { 166 if (len > mctp_pktbuf_size(pkt)) 167 return NULL; 168 169 pkt->end -= len; 170 return pkt->data + pkt->end; 171 } 172 173 /* Message reassembly */ 174 static struct mctp_msg_ctx *mctp_msg_ctx_lookup(struct mctp *mctp, 175 uint8_t src, uint8_t dest, uint8_t tag) 176 { 177 unsigned int i; 178 179 /* @todo: better lookup, if we add support for more outstanding 180 * message contexts */ 181 for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) { 182 struct mctp_msg_ctx *ctx = &mctp->msg_ctxs[i]; 183 if (ctx->src == src && ctx->dest == dest && ctx->tag == tag) 184 return ctx; 185 } 186 187 return NULL; 188 } 189 190 static struct mctp_msg_ctx *mctp_msg_ctx_create(struct mctp *mctp, 191 uint8_t src, uint8_t dest, uint8_t tag) 192 { 193 struct mctp_msg_ctx *ctx = NULL; 194 unsigned int i; 195 196 for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) { 197 struct mctp_msg_ctx *tmp = &mctp->msg_ctxs[i]; 198 if (!tmp->src) { 199 ctx = tmp; 200 break; 201 } 202 } 203 204 if (!ctx) 205 return NULL; 206 207 ctx->src = src; 208 ctx->dest = dest; 209 ctx->tag = tag; 210 ctx->buf_size = 0; 211 212 return ctx; 213 } 214 215 static void mctp_msg_ctx_drop(struct mctp_msg_ctx *ctx) 216 { 217 ctx->src = 0; 218 } 219 220 static void mctp_msg_ctx_reset(struct mctp_msg_ctx *ctx) 221 { 222 ctx->buf_size = 0; 223 ctx->fragment_size = 0; 224 } 225 226 static int mctp_msg_ctx_add_pkt(struct mctp_msg_ctx *ctx, 227 struct mctp_pktbuf *pkt, size_t max_size) 228 { 229 size_t len; 230 231 len = mctp_pktbuf_size(pkt) - sizeof(struct mctp_hdr); 232 233 if (len + ctx->buf_size < ctx->buf_size) { 234 return -1; 235 } 236 237 if (ctx->buf_size + len > ctx->buf_alloc_size) { 238 size_t new_alloc_size; 239 void *lbuf; 240 241 /* @todo: finer-grained allocation */ 242 if (!ctx->buf_alloc_size) { 243 new_alloc_size = MAX(len, 4096UL); 244 } else { 245 new_alloc_size = MAX(ctx->buf_alloc_size * 2, len + ctx->buf_size); 246 } 247 248 /* Don't allow heap to grow beyond a limit */ 249 if (new_alloc_size > max_size) 250 return -1; 251 252 253 lbuf = __mctp_realloc(ctx->buf, new_alloc_size); 254 if (lbuf) { 255 ctx->buf = lbuf; 256 ctx->buf_alloc_size = new_alloc_size; 257 } else { 258 __mctp_free(ctx->buf); 259 return -1; 260 } 261 } 262 263 memcpy(ctx->buf + ctx->buf_size, mctp_pktbuf_data(pkt), len); 264 ctx->buf_size += len; 265 266 return 0; 267 } 268 269 /* Core API functions */ 270 struct mctp *mctp_init(void) 271 { 272 struct mctp *mctp; 273 274 mctp = __mctp_alloc(sizeof(*mctp)); 275 276 if(!mctp) 277 return NULL; 278 279 memset(mctp, 0, sizeof(*mctp)); 280 mctp->max_message_size = MCTP_MAX_MESSAGE_SIZE; 281 282 return mctp; 283 } 284 285 void mctp_set_max_message_size(struct mctp *mctp, size_t message_size) 286 { 287 mctp->max_message_size = message_size; 288 } 289 290 void mctp_set_capture_handler(struct mctp *mctp, mctp_capture_fn fn, void *user) 291 { 292 mctp->capture = fn; 293 mctp->capture_data = user; 294 } 295 296 static void mctp_bus_destroy(struct mctp_bus *bus) 297 { 298 while (bus->tx_queue_head) { 299 struct mctp_pktbuf *curr = bus->tx_queue_head; 300 301 bus->tx_queue_head = curr->next; 302 mctp_pktbuf_free(curr); 303 } 304 } 305 306 void mctp_destroy(struct mctp *mctp) 307 { 308 size_t i; 309 310 /* Cleanup message assembly contexts */ 311 BUILD_ASSERT(ARRAY_SIZE(mctp->msg_ctxs) < SIZE_MAX); 312 for (i = 0; i < ARRAY_SIZE(mctp->msg_ctxs); i++) { 313 struct mctp_msg_ctx *tmp = &mctp->msg_ctxs[i]; 314 if (tmp->buf) 315 __mctp_free(tmp->buf); 316 } 317 318 while (mctp->n_busses--) 319 mctp_bus_destroy(&mctp->busses[mctp->n_busses]); 320 321 __mctp_free(mctp->busses); 322 __mctp_free(mctp); 323 } 324 325 int mctp_set_rx_all(struct mctp *mctp, mctp_rx_fn fn, void *data) 326 { 327 mctp->message_rx = fn; 328 mctp->message_rx_data = data; 329 return 0; 330 } 331 332 static struct mctp_bus *find_bus_for_eid(struct mctp *mctp, 333 mctp_eid_t dest __attribute__((unused))) 334 { 335 /* for now, just use the first bus. For full routing support, 336 * we will need a table of neighbours */ 337 return &mctp->busses[0]; 338 } 339 340 int mctp_register_bus(struct mctp *mctp, 341 struct mctp_binding *binding, 342 mctp_eid_t eid) 343 { 344 int rc = 0; 345 346 /* todo: multiple busses */ 347 assert(mctp->n_busses == 0); 348 mctp->n_busses = 1; 349 350 mctp->busses = __mctp_alloc(sizeof(struct mctp_bus)); 351 if (!mctp->busses) 352 return -ENOMEM; 353 354 memset(mctp->busses, 0, sizeof(struct mctp_bus)); 355 mctp->busses[0].binding = binding; 356 mctp->busses[0].eid = eid; 357 binding->bus = &mctp->busses[0]; 358 binding->mctp = mctp; 359 mctp->route_policy = ROUTE_ENDPOINT; 360 361 if (binding->start) { 362 rc = binding->start(binding); 363 if (rc < 0) { 364 mctp_prerr("Failed to start binding: %d", rc); 365 binding->bus = NULL; 366 __mctp_free(mctp->busses); 367 mctp->busses = NULL; 368 mctp->n_busses = 0; 369 } 370 } 371 372 return rc; 373 } 374 375 int mctp_bridge_busses(struct mctp *mctp, 376 struct mctp_binding *b1, struct mctp_binding *b2) 377 { 378 int rc = 0; 379 380 assert(mctp->n_busses == 0); 381 mctp->busses = __mctp_alloc(2 * sizeof(struct mctp_bus)); 382 if (!mctp->busses) 383 return -ENOMEM; 384 memset(mctp->busses, 0, 2 * sizeof(struct mctp_bus)); 385 mctp->n_busses = 2; 386 mctp->busses[0].binding = b1; 387 b1->bus = &mctp->busses[0]; 388 b1->mctp = mctp; 389 mctp->busses[1].binding = b2; 390 b2->bus = &mctp->busses[1]; 391 b2->mctp = mctp; 392 393 mctp->route_policy = ROUTE_BRIDGE; 394 395 if (b1->start) { 396 rc = b1->start(b1); 397 if (rc < 0) { 398 mctp_prerr("Failed to start bridged bus %s: %d", 399 b1->name, rc); 400 goto done; 401 } 402 } 403 404 if (b2->start) { 405 rc = b2->start(b2); 406 if (rc < 0) { 407 mctp_prerr("Failed to start bridged bus %s: %d", 408 b2->name, rc); 409 goto done; 410 } 411 } 412 413 done: 414 return rc; 415 } 416 417 static inline bool mctp_ctrl_cmd_is_transport(struct mctp_ctrl_msg_hdr *hdr) 418 { 419 return ((hdr->command_code >= MCTP_CTRL_CMD_FIRST_TRANSPORT) && 420 (hdr->command_code <= MCTP_CTRL_CMD_LAST_TRANSPORT)); 421 } 422 423 static bool mctp_ctrl_handle_msg(struct mctp_bus *bus, mctp_eid_t src, 424 void *buffer, size_t length) 425 { 426 struct mctp_ctrl_msg_hdr *msg_hdr = buffer; 427 428 /* 429 * Control message is received. If a transport control message handler 430 * is provided, it will called. If there is no dedicated handler, this 431 * function returns false and data can be handled by the generic 432 * message handler. The transport control message handler will be 433 * provided with messages in the command range 0xF0 - 0xFF. 434 */ 435 if (mctp_ctrl_cmd_is_transport(msg_hdr)) { 436 if (bus->binding->control_rx != NULL) { 437 /* MCTP bus binding handler */ 438 bus->binding->control_rx(src, 439 bus->binding->control_rx_data, 440 buffer, length); 441 return true; 442 } 443 } 444 445 /* 446 * Command was not handled, due to lack of specific callback. 447 * It will be passed to regular message_rx handler. 448 */ 449 return false; 450 } 451 452 static inline bool mctp_rx_dest_is_local(struct mctp_bus *bus, mctp_eid_t dest) 453 { 454 return dest == bus->eid || dest == MCTP_EID_NULL || 455 dest == MCTP_EID_BROADCAST; 456 } 457 458 static inline bool mctp_ctrl_cmd_is_request(struct mctp_ctrl_msg_hdr *hdr) 459 { 460 return hdr->ic_msg_type == MCTP_CTRL_HDR_MSG_TYPE && 461 hdr->rq_dgram_inst & MCTP_CTRL_HDR_FLAG_REQUEST; 462 } 463 464 /* 465 * Receive the complete MCTP message and route it. 466 * Asserts: 467 * 'buf' is not NULL. 468 */ 469 static void mctp_rx(struct mctp *mctp, struct mctp_bus *bus, mctp_eid_t src, 470 mctp_eid_t dest, void *buf, size_t len) 471 { 472 assert(buf != NULL); 473 474 if (mctp->route_policy == ROUTE_ENDPOINT && 475 mctp_rx_dest_is_local(bus, dest)) { 476 /* Handle MCTP Control Messages: */ 477 if (len >= sizeof(struct mctp_ctrl_msg_hdr)) { 478 struct mctp_ctrl_msg_hdr *msg_hdr = buf; 479 480 /* 481 * Identify if this is a control request message. 482 * See DSP0236 v1.3.0 sec. 11.5. 483 */ 484 if (mctp_ctrl_cmd_is_request(msg_hdr)) { 485 bool handled; 486 handled = mctp_ctrl_handle_msg(bus, src, buf, 487 len); 488 if (handled) 489 return; 490 } 491 } 492 if (mctp->message_rx) 493 mctp->message_rx(src, mctp->message_rx_data, buf, len); 494 } 495 496 if (mctp->route_policy == ROUTE_BRIDGE) { 497 int i; 498 499 for (i = 0; i < mctp->n_busses; i++) { 500 struct mctp_bus *dest_bus = &mctp->busses[i]; 501 if (dest_bus == bus) 502 continue; 503 504 mctp_message_tx_on_bus(dest_bus, src, dest, buf, len); 505 } 506 507 } 508 } 509 510 void mctp_bus_rx(struct mctp_binding *binding, struct mctp_pktbuf *pkt) 511 { 512 struct mctp_bus *bus = binding->bus; 513 struct mctp *mctp = binding->mctp; 514 uint8_t flags, exp_seq, seq, tag; 515 struct mctp_msg_ctx *ctx; 516 struct mctp_hdr *hdr; 517 size_t len; 518 void *p; 519 int rc; 520 521 assert(bus); 522 523 /* Drop packet if it was smaller than mctp hdr size */ 524 if (mctp_pktbuf_size(pkt) <= sizeof(struct mctp_hdr)) 525 goto out; 526 527 if (mctp->capture) 528 mctp->capture(pkt, mctp->capture_data); 529 530 hdr = mctp_pktbuf_hdr(pkt); 531 532 /* small optimisation: don't bother reassembly if we're going to 533 * drop the packet in mctp_rx anyway */ 534 if (mctp->route_policy == ROUTE_ENDPOINT && hdr->dest != bus->eid) 535 goto out; 536 537 flags = hdr->flags_seq_tag & (MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM); 538 tag = (hdr->flags_seq_tag >> MCTP_HDR_TAG_SHIFT) & MCTP_HDR_TAG_MASK; 539 seq = (hdr->flags_seq_tag >> MCTP_HDR_SEQ_SHIFT) & MCTP_HDR_SEQ_MASK; 540 541 switch (flags) { 542 case MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM: 543 /* single-packet message - send straight up to rx function, 544 * no need to create a message context */ 545 len = pkt->end - pkt->mctp_hdr_off - sizeof(struct mctp_hdr); 546 p = pkt->data + pkt->mctp_hdr_off + sizeof(struct mctp_hdr); 547 mctp_rx(mctp, bus, hdr->src, hdr->dest, p, len); 548 break; 549 550 case MCTP_HDR_FLAG_SOM: 551 /* start of a new message - start the new context for 552 * future message reception. If an existing context is 553 * already present, drop it. */ 554 ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag); 555 if (ctx) { 556 mctp_msg_ctx_reset(ctx); 557 } else { 558 ctx = mctp_msg_ctx_create(mctp, 559 hdr->src, hdr->dest, tag); 560 /* If context creation fails due to exhaution of contexts we 561 * can support, drop the packet */ 562 if (!ctx) { 563 mctp_prdebug("Context buffers exhausted."); 564 goto out; 565 } 566 } 567 568 /* Save the fragment size, subsequent middle fragments 569 * should of the same size */ 570 ctx->fragment_size = mctp_pktbuf_size(pkt); 571 572 rc = mctp_msg_ctx_add_pkt(ctx, pkt, mctp->max_message_size); 573 if (rc) { 574 mctp_msg_ctx_drop(ctx); 575 } else { 576 ctx->last_seq = seq; 577 } 578 579 break; 580 581 case MCTP_HDR_FLAG_EOM: 582 ctx = mctp_msg_ctx_lookup(mctp, hdr->src, hdr->dest, tag); 583 if (!ctx) 584 goto out; 585 586 exp_seq = (ctx->last_seq + 1) % 4; 587 588 if (exp_seq != seq) { 589 mctp_prdebug( 590 "Sequence number %d does not match expected %d", 591 seq, exp_seq); 592 mctp_msg_ctx_drop(ctx); 593 goto out; 594 } 595 596 len = mctp_pktbuf_size(pkt); 597 598 if (len > ctx->fragment_size) { 599 mctp_prdebug("Unexpected fragment size. Expected" \ 600 " less than %zu, received = %zu", 601 ctx->fragment_size, len); 602 mctp_msg_ctx_drop(ctx); 603 goto out; 604 } 605 606 rc = mctp_msg_ctx_add_pkt(ctx, pkt, mctp->max_message_size); 607 if (!rc) 608 mctp_rx(mctp, bus, ctx->src, ctx->dest, 609 ctx->buf, ctx->buf_size); 610 611 mctp_msg_ctx_drop(ctx); 612 break; 613 614 case 0: 615 /* Neither SOM nor EOM */ 616 ctx = mctp_msg_ctx_lookup(mctp, hdr->src,hdr->dest, tag); 617 if (!ctx) 618 goto out; 619 620 exp_seq = (ctx->last_seq + 1) % 4; 621 if (exp_seq != seq) { 622 mctp_prdebug( 623 "Sequence number %d does not match expected %d", 624 seq, exp_seq); 625 mctp_msg_ctx_drop(ctx); 626 goto out; 627 } 628 629 len = mctp_pktbuf_size(pkt); 630 631 if (len != ctx->fragment_size) { 632 mctp_prdebug("Unexpected fragment size. Expected = %zu " \ 633 "received = %zu", ctx->fragment_size, len); 634 mctp_msg_ctx_drop(ctx); 635 goto out; 636 } 637 638 rc = mctp_msg_ctx_add_pkt(ctx, pkt, mctp->max_message_size); 639 if (rc) { 640 mctp_msg_ctx_drop(ctx); 641 goto out; 642 } 643 ctx->last_seq = seq; 644 645 break; 646 } 647 out: 648 mctp_pktbuf_free(pkt); 649 } 650 651 static int mctp_packet_tx(struct mctp_bus *bus, 652 struct mctp_pktbuf *pkt) 653 { 654 struct mctp *mctp = bus->binding->mctp; 655 656 if (bus->state != mctp_bus_state_tx_enabled) 657 return -1; 658 659 if (mctp->capture) 660 mctp->capture(pkt, mctp->capture_data); 661 662 return bus->binding->tx(bus->binding, pkt); 663 } 664 665 static void mctp_send_tx_queue(struct mctp_bus *bus) 666 { 667 struct mctp_pktbuf *pkt; 668 669 while ((pkt = bus->tx_queue_head)) { 670 int rc; 671 672 rc = mctp_packet_tx(bus, pkt); 673 if (rc) 674 break; 675 676 bus->tx_queue_head = pkt->next; 677 mctp_pktbuf_free(pkt); 678 } 679 680 if (!bus->tx_queue_head) 681 bus->tx_queue_tail = NULL; 682 683 } 684 685 void mctp_binding_set_tx_enabled(struct mctp_binding *binding, bool enable) 686 { 687 struct mctp_bus *bus = binding->bus; 688 689 switch(bus->state) { 690 case mctp_bus_state_constructed: 691 if (!enable) 692 return; 693 694 if (binding->pkt_size < MCTP_PACKET_SIZE(MCTP_BTU)) { 695 mctp_prerr("Cannot start %s binding with invalid MTU: %zu", 696 binding->name, 697 MCTP_BODY_SIZE(binding->pkt_size)); 698 return; 699 } 700 701 bus->state = mctp_bus_state_tx_enabled; 702 mctp_prinfo("%s binding started", binding->name); 703 return; 704 case mctp_bus_state_tx_enabled: 705 if (enable) 706 return; 707 708 bus->state = mctp_bus_state_tx_disabled; 709 mctp_prdebug("%s binding Tx disabled", binding->name); 710 return; 711 case mctp_bus_state_tx_disabled: 712 if (!enable) 713 return; 714 715 bus->state = mctp_bus_state_tx_enabled; 716 mctp_prdebug("%s binding Tx enabled", binding->name); 717 mctp_send_tx_queue(bus); 718 return; 719 } 720 } 721 722 static int mctp_message_tx_on_bus(struct mctp_bus *bus, mctp_eid_t src, 723 mctp_eid_t dest, void *msg, size_t msg_len) 724 { 725 size_t max_payload_len, payload_len, p; 726 struct mctp_pktbuf *pkt; 727 struct mctp_hdr *hdr; 728 int i; 729 730 if (bus->state == mctp_bus_state_constructed) 731 return -ENXIO; 732 733 max_payload_len = MCTP_BODY_SIZE(bus->binding->pkt_size); 734 735 { 736 const bool valid_mtu = max_payload_len >= MCTP_BTU; 737 assert(valid_mtu); 738 if (!valid_mtu) 739 return -EINVAL; 740 } 741 742 mctp_prdebug("%s: Generating packets for transmission of %zu byte message from %hhu to %hhu", 743 __func__, msg_len, src, dest); 744 745 /* queue up packets, each of max MCTP_MTU size */ 746 for (p = 0, i = 0; p < msg_len; i++) { 747 payload_len = msg_len - p; 748 if (payload_len > max_payload_len) 749 payload_len = max_payload_len; 750 751 pkt = mctp_pktbuf_alloc(bus->binding, 752 payload_len + sizeof(*hdr)); 753 hdr = mctp_pktbuf_hdr(pkt); 754 755 /* todo: tags */ 756 hdr->ver = bus->binding->version & 0xf; 757 hdr->dest = dest; 758 hdr->src = src; 759 hdr->flags_seq_tag = MCTP_HDR_FLAG_TO | 760 (0 << MCTP_HDR_TAG_SHIFT); 761 762 if (i == 0) 763 hdr->flags_seq_tag |= MCTP_HDR_FLAG_SOM; 764 if (p + payload_len >= msg_len) 765 hdr->flags_seq_tag |= MCTP_HDR_FLAG_EOM; 766 hdr->flags_seq_tag |= 767 (i & MCTP_HDR_SEQ_MASK) << MCTP_HDR_SEQ_SHIFT; 768 769 memcpy(mctp_pktbuf_data(pkt), msg + p, payload_len); 770 771 /* add to tx queue */ 772 if (bus->tx_queue_tail) 773 bus->tx_queue_tail->next = pkt; 774 else 775 bus->tx_queue_head = pkt; 776 bus->tx_queue_tail = pkt; 777 778 p += payload_len; 779 } 780 781 mctp_prdebug("%s: Enqueued %d packets", __func__, i); 782 783 mctp_send_tx_queue(bus); 784 785 return 0; 786 } 787 788 int mctp_message_tx(struct mctp *mctp, mctp_eid_t eid, 789 void *msg, size_t msg_len) 790 { 791 struct mctp_bus *bus; 792 793 bus = find_bus_for_eid(mctp, eid); 794 return mctp_message_tx_on_bus(bus, bus->eid, eid, msg, msg_len); 795 } 796