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