-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add MCTP over USB Binding support #95347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Add MCTP over USB Binding support #95347
Conversation
In order to support the USB binding for libMCTP, we must first add a device class for MCTP. MCTP is one of the base classes in the USB specification. Signed-off-by: Eric Ocasio <eric.ocasio@nxp.com>
Adds support for the USB device binding for MCTP. Binding created based on the DMTF specification for USB Transport Binding. The overall design of this binding follows the existing UART and I2C+GPIO bindings that already exist in Zephyr. This binding interacts with the new USBD_MCTP device class that is part of this PR. Signed-off-by: Eric Ocasio <eric.ocasio@nxp.com>
Based on the existing sample applications for MCTP, this new sample demonstrates how to use MCTP using the USB device binding. Signed-off-by: Eric Ocasio <eric.ocasio@nxp.com>
Hello @eric-ocasio-nxp, and thank you very much for your first pull request to the Zephyr project! |
|
@@ -0,0 +1,11 @@ | |||
.. _usbd_mctp: | |||
|
|||
MCTP USB device API |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please detail what "MCTP" actually is here.
|
||
cmake_minimum_required(VERSION 3.20.0) | ||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(mctp_endpoint) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
project name could use something more descriptive, I get I'm guilty of probably starting this but perhaps mctp_usb_endpoint would be better
project(mctp_endpoint) | ||
|
||
include(${ZEPHYR_BASE}/samples/subsys/usb/common/common.cmake) | ||
FILE(GLOB app_sources src/*.c) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please don't glob here
|
||
An example script to test this interface is provided below. | ||
|
||
.. code-block:: python |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly probably better to put this into scripts or into the sample directory itself as a python script with requirements.txt and all rather than pushing users to copy/paste, and figure out how to get the python deps installed.
Can always include whole code files into the docs like this with literalinclude
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good. I moved it to a script within the sample folder with a requirements.txt and instructions in the README.
Non-blocking comments obviously, but would be good to see improvements. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to support the USB binding for libMCTP, we must first add a device
class for MCTP. MCTP is one of the base classes in the USB specification.
Well no, it is specified by the "DMTF association", https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.0.0.pdf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's base class 0x14 in the USB spec, so I'm not sure what you mean here.
+-----------------------------------+-------------------------+-------------------------+ | ||
| USB Video Class (UVC) | Video device | :samp:`uvc_{n}` | | ||
+-----------------------------------+-------------------------+-------------------------+ | ||
| USB MCTP over USB Endpoint | :ref:`usbd_mctp` | :samp:`mctp_{n}` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/USB MCTP over USB Endpoint/MCTP over USB Binding
|
||
* :zephyr:code-sample:`usb-hid-mouse` | ||
|
||
* :zephyr:code-sample:`mctp-usb-endpoint` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* :zephyr:code-sample:
mctp-usb-binding`` Anyway, you cannot add it in this commit, this sample does not exist yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you suggest that I just update this file in a commit with the sample application, or do one 'super commit' with all of these feature/MCTP changes? I did it this way for human readability, but didn't fully understand the need for every commit to build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Commits in a pull request should represent clear, logical units of change that are easy to review and maintain bisectability." https://docs.zephyrproject.org/latest/contribute/contributor_expectations.html#pr-requirements
|
||
/** | ||
* @file | ||
* @brief USB MCTP over USB Protocol Endpoint Device Class (MCTP) public header |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brief MCTP over USB Binding implementation
* @brief USB MCTP over USB Protocol Endpoint Device Class (MCTP) public header | ||
* | ||
* This header describes MCTP class interactions desgined to be used by libMCTP. | ||
* The MCTP device itself is modelled with devicetree zephyr,mctp-usb compatible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what that means, but usually devicetree is used to describe and instantiate a device. Whether it makes sense here or not is disputable.
#include <zephyr/logging/log.h> | ||
LOG_MODULE_REGISTER(usbd_mctp, CONFIG_USBD_MCTP_LOG_LEVEL); | ||
|
||
#define DT_DRV_COMPAT zephyr_mctp_usb |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you thing it should model a device and use DT for instantiation. You do not have to follow usbd_hid approach. This looks more like a backend implementation, and for that you could provide hooks and instantiation macro, please take a look at new USB DFU device implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did it this way because there exists the possibility of having multiple MCTP buses/bindings. If the application requires more than one MCTP endpoint, a USB composite device could be used with more than one instance of USBD MCTP. Is there a way to accomplish this without DT?
|
||
config MCTP_USB | ||
bool "MCTP USB Binding" | ||
depends on USB_DEVICE_STACK_NEXT |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant, USBD_MCTP_CLASS already depends on USB_DEVICE_STACK_NEXT.
.name = STRINGIFY(_name), .version = 1, \ | ||
.pkt_size = \ | ||
MCTP_PACKET_SIZE(MCTP_USB_MAX_PACKET_LENGTH), \ | ||
.pkt_header = 0, .pkt_trailer = 0, \ | ||
.start = mctp_usb_start, .tx = mctp_usb_tx, \ | ||
}, \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Broken style.
* @param _name Symbolic name of the bus binding variable | ||
* @param _dev DeviceTree Node containing the configuration of this MCTP binding | ||
*/ | ||
#define MCTP_USB_DT_DEFINE(_name, _dev) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not get the purpose of this macro and the mctp_usb.c, you already have implemented instantiation and support for this function in the previous commit, what it that and why does it have to be divided?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not following. This macro was created based on the other libmctp binding implementations. What do you mean by it being divided?
@@ -0,0 +1,9 @@ | |||
# Copyright (c) 2023 Nordic Semiconductor ASA |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused, is PMCI/MCTP not part of the Zephyr but an external module? If so then I do not think you can add any dependency on it to the USB subsystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way I looked at it is that MCTP is called out as a base class on usb.org, so the device class implementation can exists in Zephyr, even if the higher-level MCTP protocol management comes from an external module. Right now it comes from libmctp (https://github.com/openbmc/libmctp).
I understand this concern. Is there something you think would create such a dependency? Again, I'm new to Zephyr, so maybe I don't fully understand something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused, is PMCI/MCTP not part of the Zephyr but an external module?
mctp is not an external module, it is part of the main manifest and there are dependencies on it already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused, is PMCI/MCTP not part of the Zephyr but an external module?
mctp is not an external module, it is part of the main manifest and there are dependencies on it already.
Anyway, the implementation cannot be part of subsys/usb, and has to go to the modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that MCTP is listed on usb.org doesn't matter then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfischer-no I too am confused by the comment that this should go to modules, mctp is a subsystem in zephyr built on libmctp.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfischer-no I too am confused by the comment that this should go to a modules, mctp is a subsystem in zephyr built on libmctp.
yeah, this is confusing. The fact that libmctp is a module is irrelevant, this is implementing usb bindings, using both mctp and usb in zephyr, this has nothing to do with libmctp, the usb binding is a zephyr thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that MCTP is listed on usb.org doesn't matter then?
It does not mean anything. The specification is from DMTF association, and I already mentioned that, see #95347 (comment). You should know that, as you had to read it to write this code, or where does the code come from?
I too am confused by the comment that this should go to modules, mctp is a subsystem in zephyr built on libmctp.
What is external dependency, and like a sample in this PR is placed under sample/modules
the implementation should be in modules/foobar
.
yeah, this is confusing. The fact that libmctp is a module is irrelevant, this is implementing usb bindings, using both mctp and usb in zephyr, this has nothing to do with libmctp, the usb binding is a zephyr thing.
"usb binding" are useless without libmctp, "usb binding" is some trivial USB code that I will not accept in subsys/usb
as long as there is no native libmctp implementation in Zephyr. And even then there is no need to place yet another backend to "something" in subsys/usb
, a very good example is 6fddc44.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfischer-no please, this is like saying I should not accept any code that depends on a hal, we've passed that rubicon long ago
To say it should go in subsys/pmci/mctp that's fine, its where the rest of the binding code is anyways. I get if you don't want to take maintainership of this code that's very understandable and reasonable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"usb binding" are useless without libmctp
right, but we have libmctp and it is not optional.
Anyways, what is it exactly that you want?
- Is it about the location where the code should be hosted?
- Is it about this base class not being defined by USB-IF? Where should those go? What about bluetooth, not defined by USB-IF yet it is hosted in
subsys/usb/device/class
? - Or is it about libmctp being a module? In this case, this is a library, mctp and bindings use this library, libmctp on its own does not do anything.
Add USB device binding for MCTP. Created new USB device class for MCTP, libMCTP binding, and sample application.