|
14 | 14 | #include "libmctp.h" |
15 | 15 | #include "libmctp-alloc.h" |
16 | 16 | #include "libmctp-log.h" |
| 17 | +#include "libmctp-cmds.h" |
17 | 18 |
|
18 | 19 | /* Internal data structures */ |
19 | 20 |
|
@@ -313,12 +314,85 @@ int mctp_bridge_busses(struct mctp *mctp, |
313 | 314 | return 0; |
314 | 315 | } |
315 | 316 |
|
316 | | -static void mctp_rx(struct mctp *mctp, struct mctp_bus *bus, |
317 | | - mctp_eid_t src, mctp_eid_t dest, void *buf, size_t len) |
| 317 | +static inline bool mctp_ctrl_cmd_is_transport(struct mctp_ctrl_msg_hdr *hdr) |
318 | 318 | { |
| 319 | + return ((hdr->command_code >= MCTP_CTRL_CMD_FIRST_TRANSPORT) && |
| 320 | + (hdr->command_code <= MCTP_CTRL_CMD_LAST_TRANSPORT)); |
| 321 | +} |
| 322 | + |
| 323 | +static bool mctp_ctrl_handle_msg(struct mctp *mctp, struct mctp_bus *bus, |
| 324 | + mctp_eid_t src, mctp_eid_t dest, void *buffer, |
| 325 | + size_t length) |
| 326 | +{ |
| 327 | + struct mctp_ctrl_msg_hdr *msg_hdr = buffer; |
| 328 | + |
| 329 | + /* |
| 330 | + * Control message is received. If a transport control message handler |
| 331 | + * is provided, it will called. If there is no dedicated handler, this |
| 332 | + * function returns false and data can be handled by the generic |
| 333 | + * message handler. The transport control message handler will be |
| 334 | + * provided with messages in the command range 0xF0 - 0xFF. |
| 335 | + */ |
| 336 | + if (mctp_ctrl_cmd_is_transport(msg_hdr)) { |
| 337 | + if (bus->binding->control_rx != NULL) { |
| 338 | + /* MCTP bus binding handler */ |
| 339 | + bus->binding->control_rx(src, |
| 340 | + bus->binding->control_rx_data, |
| 341 | + buffer, length); |
| 342 | + return true; |
| 343 | + } |
| 344 | + } |
| 345 | + |
| 346 | + /* |
| 347 | + * Command was not handled, due to lack of specific callback. |
| 348 | + * It will be passed to regular message_rx handler. |
| 349 | + */ |
| 350 | + return false; |
| 351 | +} |
| 352 | + |
| 353 | +static inline bool mctp_rx_dest_is_local(struct mctp_bus *bus, mctp_eid_t dest) |
| 354 | +{ |
| 355 | + return dest == bus->eid || dest == MCTP_EID_NULL || |
| 356 | + dest == MCTP_EID_BROADCAST; |
| 357 | +} |
| 358 | + |
| 359 | +static inline bool mctp_ctrl_cmd_is_request(struct mctp_ctrl_msg_hdr *hdr) |
| 360 | +{ |
| 361 | + return hdr->ic_msg_type == MCTP_CTRL_HDR_MSG_TYPE && |
| 362 | + hdr->rq_dgram_inst & MCTP_CTRL_HDR_FLAG_REQUEST; |
| 363 | +} |
| 364 | + |
| 365 | +/* |
| 366 | + * Receive the complete MCTP message and route it. |
| 367 | + * Asserts: |
| 368 | + * 'buf' is not NULL. |
| 369 | + */ |
| 370 | +static void mctp_rx(struct mctp *mctp, struct mctp_bus *bus, mctp_eid_t src, |
| 371 | + mctp_eid_t dest, void *buf, size_t len) |
| 372 | +{ |
| 373 | + assert(buf != NULL); |
| 374 | + |
319 | 375 | if (mctp->route_policy == ROUTE_ENDPOINT && |
320 | | - dest == bus->eid && mctp->message_rx) |
321 | | - mctp->message_rx(src, mctp->message_rx_data, buf, len); |
| 376 | + mctp_rx_dest_is_local(bus, dest)) { |
| 377 | + /* Handle MCTP Control Messages: */ |
| 378 | + if (len >= sizeof(struct mctp_ctrl_msg_hdr)) { |
| 379 | + struct mctp_ctrl_msg_hdr *msg_hdr = buf; |
| 380 | + |
| 381 | + /* |
| 382 | + * Identify if this is a control request message. |
| 383 | + * See DSP0236 v1.3.0 sec. 11.5. |
| 384 | + */ |
| 385 | + if (mctp_ctrl_cmd_is_request(msg_hdr)) { |
| 386 | + bool handled; |
| 387 | + handled = mctp_ctrl_handle_msg(mctp, bus, src, |
| 388 | + dest, buf, len); |
| 389 | + if (handled) |
| 390 | + return; |
| 391 | + } |
| 392 | + } |
| 393 | + if (mctp->message_rx) |
| 394 | + mctp->message_rx(src, mctp->message_rx_data, buf, len); |
| 395 | + } |
322 | 396 |
|
323 | 397 | if (mctp->route_policy == ROUTE_BRIDGE) { |
324 | 398 | int i; |
|
0 commit comments