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