|
53 | 53 | #define CC_MCTP_DBUS_IFACE_INTERFACE "au.com.codeconstruct.MCTP.Interface1"
|
54 | 54 | #define CC_MCTP_DBUS_NETWORK_INTERFACE "au.com.codeconstruct.MCTP.Network1"
|
55 | 55 |
|
| 56 | +#define BRIDGE_SETTLE_DELAY_SEC 4 |
56 | 57 | // an arbitrary constant for use with sd_id128_get_machine_app_specific()
|
57 | 58 | static const char* mctpd_appid = "67369c05-4b97-4b7e-be72-65cfd8639f10";
|
58 | 59 |
|
@@ -243,6 +244,7 @@ static int add_local_eid(ctx *ctx, int net, int eid);
|
243 | 244 | static int del_local_eid(ctx *ctx, int net, int eid);
|
244 | 245 | static int add_net(ctx *ctx, int net);
|
245 | 246 | static int add_interface(ctx *ctx, int ifindex);
|
| 247 | +static int endpoint_allocate_eid(peer *peer); |
246 | 248 |
|
247 | 249 | mctp_eid_t local_addr(const ctx *ctx, int ifindex) {
|
248 | 250 | mctp_eid_t *eids, ret = 0;
|
@@ -2107,6 +2109,16 @@ static int method_assign_endpoint(sd_bus_message *call, void *data, sd_bus_error
|
2107 | 2109 | goto err;
|
2108 | 2110 | dfree(peer_path);
|
2109 | 2111 |
|
| 2112 | + /* MCTP Bridge Support */ |
| 2113 | + /* Allocate Endopint EID while looking for pool start eid |
| 2114 | + * Update pool endpoints to dbus */ |
| 2115 | + |
| 2116 | + if(peer->pool_size > 0) { |
| 2117 | + /* new start eid will be assigned before MCTP Allocate eid control command */ |
| 2118 | + peer->pool_start = peer->eid + 1; |
| 2119 | + rc = endpoint_allocate_eid(peer); |
| 2120 | + } |
| 2121 | + |
2110 | 2122 | return sd_bus_reply_method_return(call, "yisb",
|
2111 | 2123 | peer->eid, peer->net, peer_path, 1);
|
2112 | 2124 | err:
|
@@ -2185,8 +2197,11 @@ static int method_assign_endpoint_static(sd_bus_message *call, void *data,
|
2185 | 2197 | dfree(peer_path);
|
2186 | 2198 |
|
2187 | 2199 | /* MCTP Bridge Support */
|
| 2200 | + /* Allocate Endopint EID |
| 2201 | + * Update pool endpoints to dbus */ |
2188 | 2202 | if(peer->pool_size > 0) {
|
2189 | 2203 | peer->pool_start = start_eid;
|
| 2204 | + rc = endpoint_allocate_eid(peer); |
2190 | 2205 | }
|
2191 | 2206 |
|
2192 | 2207 | return sd_bus_reply_method_return(call, "yisb",
|
@@ -4494,6 +4509,160 @@ static void setup_config_defaults(ctx *ctx)
|
4494 | 4509 | ctx->default_role = ENDPOINT_ROLE_BUS_OWNER;
|
4495 | 4510 | }
|
4496 | 4511 |
|
| 4512 | +static int endpoint_send_allocate_endpoint_id(peer *peer, |
| 4513 | + mctp_eid_t eid_start, uint8_t eid_pool_size, mctp_ctrl_cmd_alloc_eid_op oper, |
| 4514 | + uint8_t *allocated_pool_size, mctp_eid_t *allocated_pool_start) |
| 4515 | +{ |
| 4516 | + struct sockaddr_mctp_ext addr; |
| 4517 | + struct mctp_ctrl_cmd_alloc_eid req = {0}; |
| 4518 | + struct mctp_ctrl_resp_alloc_eid *resp = NULL; |
| 4519 | + uint8_t *buf = NULL; |
| 4520 | + size_t buf_size; |
| 4521 | + uint8_t iid, stat; |
| 4522 | + int rc; |
| 4523 | + |
| 4524 | + iid = mctp_next_iid(peer->ctx); |
| 4525 | + req.ctrl_hdr.rq_dgram_inst = RQDI_REQ | iid; |
| 4526 | + req.ctrl_hdr.command_code = MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS; |
| 4527 | + req.alloc_eid_op = alloc_eid; |
| 4528 | + req.pool_size = eid_pool_size; |
| 4529 | + req.start_eid = eid_start; |
| 4530 | + rc = endpoint_query_peer(peer, MCTP_CTRL_HDR_MSG_TYPE, &req, sizeof(req), |
| 4531 | + &buf, &buf_size, &addr); |
| 4532 | + if (rc < 0) |
| 4533 | + goto out; |
| 4534 | + |
| 4535 | + rc = mctp_ctrl_validate_response(buf, buf_size, sizeof(*resp), |
| 4536 | + peer_tostr_short(peer), iid, |
| 4537 | + MCTP_CTRL_CMD_ALLOCATE_ENDPOINT_IDS); |
| 4538 | + |
| 4539 | + if (rc) |
| 4540 | + goto out; |
| 4541 | + |
| 4542 | + resp = (void *)buf; |
| 4543 | + if (!resp) { |
| 4544 | + warnx("%s Invalid response Buffer\n", __func__); |
| 4545 | + return -ENOMEM; |
| 4546 | + } |
| 4547 | + |
| 4548 | + stat = resp->status & 0x03; |
| 4549 | + if (stat == 0x00) { |
| 4550 | + if(peer->ctx->verbose) { |
| 4551 | + fprintf(stderr, "%s Allocation Accepted \n", __func__); |
| 4552 | + } |
| 4553 | + } |
| 4554 | + else if (stat == 0x1) { |
| 4555 | + warnx("%s Allocation was rejected as it was Allocated by other bus \n", __func__); |
| 4556 | + } |
| 4557 | + |
| 4558 | + *allocated_pool_size = resp->eid_pool_size; |
| 4559 | + *allocated_pool_start = resp->eid_set; |
| 4560 | + if(peer->ctx->verbose) { |
| 4561 | + fprintf(stderr, "%s Allocated size of %d, starting from EID %d\n", __func__, |
| 4562 | + resp->eid_pool_size, resp->eid_set); |
| 4563 | + } |
| 4564 | + |
| 4565 | + return 0; |
| 4566 | +out: |
| 4567 | + free(buf); |
| 4568 | + return rc; |
| 4569 | +} |
| 4570 | +static int cb_populate_pool_eids(sd_event_source *s, uint64_t t, void* data) |
| 4571 | +{ |
| 4572 | + peer *peer = data; |
| 4573 | + int net = peer->net; |
| 4574 | + struct peer *allocated_peer = NULL; |
| 4575 | + dest_phys dest = peer->phys; |
| 4576 | + int rc; |
| 4577 | + |
| 4578 | + fprintf (stderr, "Bridge Time expired, set pool eids\n"); |
| 4579 | + for (mctp_eid_t eid = peer->pool_start; |
| 4580 | + eid < peer->pool_start + peer->pool_size; eid++) { |
| 4581 | + rc = add_peer(peer->ctx, &dest, eid, net, &allocated_peer); |
| 4582 | + if (rc < 0) { |
| 4583 | + warnx("%s failed to find peer for allocated eid %d\n", |
| 4584 | + __func__, eid); |
| 4585 | + continue; |
| 4586 | + } |
| 4587 | + |
| 4588 | + rc = setup_added_peer(allocated_peer); |
| 4589 | + if (rc < 0) { |
| 4590 | + warnx("%s failed to setup peer for allocated eid %d\n", |
| 4591 | + __func__, eid); |
| 4592 | + continue; |
| 4593 | + } |
| 4594 | + } |
| 4595 | + |
| 4596 | + return 0; |
| 4597 | +} |
| 4598 | + |
| 4599 | +static mctp_eid_t get_pool_start (peer *peer, mctp_eid_t eid_start, uint8_t pool_size) |
| 4600 | +{ |
| 4601 | + uint8_t count = 0; |
| 4602 | + mctp_eid_t pool_start = eid_alloc_max; |
| 4603 | + net_det *n = lookup_net(peer->ctx, peer->net); |
| 4604 | + |
| 4605 | + if (!n) { |
| 4606 | + warnx("BUG: Unknown net %d : failed to get pool start\n", peer->net); |
| 4607 | + return eid_alloc_max; |
| 4608 | + } |
| 4609 | + |
| 4610 | + for (mctp_eid_t e = eid_start; e <= eid_alloc_max; e++) { |
| 4611 | + if (n->peeridx[e] == -1) { |
| 4612 | + if(pool_start == eid_alloc_max) { |
| 4613 | + pool_start = e; |
| 4614 | + } |
| 4615 | + count++; |
| 4616 | + if (count == pool_size) return pool_start; |
| 4617 | + } else { |
| 4618 | + pool_start = eid_alloc_max; |
| 4619 | + count = 0; |
| 4620 | + } |
| 4621 | + } |
| 4622 | + |
| 4623 | + return eid_alloc_max; |
| 4624 | +} |
| 4625 | + |
| 4626 | +static int endpoint_allocate_eid(peer* peer) |
| 4627 | +{ |
| 4628 | + uint8_t allocated_pool_size = 0; |
| 4629 | + mctp_eid_t allocated_pool_start = 0; |
| 4630 | + |
| 4631 | + /* Find pool sized contiguous unused eids to allocate on the bridge. */ |
| 4632 | + peer->pool_start = get_pool_start(peer, peer->pool_start, peer->pool_size); |
| 4633 | + if(peer->pool_start == eid_alloc_max) { |
| 4634 | + warnx("%s failed to find contiguous EIDs of required size", __func__); |
| 4635 | + return 0; |
| 4636 | + } else { |
| 4637 | + if(peer->ctx->verbose) |
| 4638 | + fprintf(stderr, "%s Asking for contiguous EIDs for pool with start eid : %d\n", __func__, peer->pool_start); |
| 4639 | + } |
| 4640 | + |
| 4641 | + int rc = endpoint_send_allocate_endpoint_id(peer, peer->pool_start, peer->pool_size, |
| 4642 | + alloc_eid, &allocated_pool_size, &allocated_pool_start); |
| 4643 | + if (rc) { |
| 4644 | + warnx("%s failed to allocate endpoints, returned %s %d\n", |
| 4645 | + __func__, strerror(-rc), rc); |
| 4646 | + } else { |
| 4647 | + peer->pool_size = allocated_pool_size; |
| 4648 | + peer->pool_start = allocated_pool_start; |
| 4649 | + |
| 4650 | + //delay for settling MCTP Bridge after allocation of downstream eid |
| 4651 | + uint64_t now_usec, timer_usec; |
| 4652 | + // Get the current time in microseconds |
| 4653 | + if (sd_event_now(peer->ctx->event, CLOCK_MONOTONIC, &now_usec) < 0) { |
| 4654 | + warnx("Failed to get current time"); |
| 4655 | + return -1; |
| 4656 | + } |
| 4657 | + timer_usec = now_usec + BRIDGE_SETTLE_DELAY_SEC * 1000000ULL; |
| 4658 | + rc = sd_event_add_time(peer->ctx->event, NULL, |
| 4659 | + CLOCK_MONOTONIC, timer_usec, 0, |
| 4660 | + cb_populate_pool_eids, peer); |
| 4661 | + } |
| 4662 | + |
| 4663 | + return 0; |
| 4664 | +} |
| 4665 | + |
4497 | 4666 | int main(int argc, char **argv)
|
4498 | 4667 | {
|
4499 | 4668 | int rc;
|
|
0 commit comments