From 2f2e974f8fbe8a19311842afaf66394f4caa0ae4 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:22 +0800 Subject: net: mctp: usb: Include version indicator in max packet size defines DSP0283 v1.1.0 will introduce larger maximum packet sizes. In preparation, indicate that the current maxima are specific to v1.0.x. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-1-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index a2f6f1e04efb..47e2e3931d63 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -21,10 +21,11 @@ struct mctp_usb_hdr { u8 len; } __packed; -#define MCTP_USB_XFER_SIZE 512 +/* max transfer size for DSP0283 v1.0 */ +#define MCTP_USB_1_0_XFER_SIZE 512 #define MCTP_USB_BTU 68 #define MCTP_USB_MTU_MIN MCTP_USB_BTU -#define MCTP_USB_MTU_MAX (U8_MAX - sizeof(struct mctp_usb_hdr)) +#define MCTP_USB_1_0_MTU_MAX (U8_MAX - sizeof(struct mctp_usb_hdr)) #define MCTP_USB_DMTF_ID 0x1ab4 #endif /* __LINUX_USB_MCTP_USB_H */ -- cgit v1.2.3 From 05b1a3a5eeaa64a5d412688e682a3b13acd99e8b Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:23 +0800 Subject: net: mctp: usb: Use packet-length max for maximum packet-size check The max packet size is smaller than the max transfer size, as we only have a u8 length field in the transport header. Add a define for the maximum representable length, and use that for our check. Use this for the MTU maximum calculation too. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-2-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index 47e2e3931d63..2bece8afd1c7 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -25,7 +25,8 @@ struct mctp_usb_hdr { #define MCTP_USB_1_0_XFER_SIZE 512 #define MCTP_USB_BTU 68 #define MCTP_USB_MTU_MIN MCTP_USB_BTU -#define MCTP_USB_1_0_MTU_MAX (U8_MAX - sizeof(struct mctp_usb_hdr)) +#define MCTP_USB_1_0_PKTLEN_MAX U8_MAX +#define MCTP_USB_1_0_MTU_MAX (MCTP_USB_1_0_PKTLEN_MAX - sizeof(struct mctp_usb_hdr)) #define MCTP_USB_DMTF_ID 0x1ab4 #endif /* __LINUX_USB_MCTP_USB_H */ -- cgit v1.2.3 From b8564b19c0fffb0ddfef760655c419b3953ceb0e Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:24 +0800 Subject: net: mctp: usblib: Move RX transfer processing to a new mctp-usblib The processing of USB receive transfers is common to both sides of a MCTP over USB transport. In order to support a future gadget driver, move the current host-side driver into a new common file, mctp-usblib. This currently handles the submit-complete-packetise process of the receive path of the USB transport. We'll add transmit handling in an upcoming change. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-3-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index 2bece8afd1c7..595e6af16dd0 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -13,6 +13,8 @@ #ifndef __LINUX_USB_MCTP_USB_H #define __LINUX_USB_MCTP_USB_H +#include +#include #include struct mctp_usb_hdr { @@ -29,4 +31,28 @@ struct mctp_usb_hdr { #define MCTP_USB_1_0_MTU_MAX (MCTP_USB_1_0_PKTLEN_MAX - sizeof(struct mctp_usb_hdr)) #define MCTP_USB_DMTF_ID 0x1ab4 +/* mctp-usblib */ + +/* + * RX handle: drivers will typically create one on init, which persists for + * the life of the driver. The same handle is used for progressive + * prepare -> complete operations (for each incoming USB transfer), which + * result in netif_rx()-ing the MCTP packets received + */ +struct mctp_usblib_rx { + struct sk_buff *skb; +}; + +void mctp_usblib_rx_init(struct mctp_usblib_rx *rx); +void mctp_usblib_rx_fini(struct mctp_usblib_rx *rx); + +int mctp_usblib_rx_prepare(struct net_device *netdev, + struct mctp_usblib_rx *rx, + void **bufp, size_t *lenp, gfp_t gfp); + +int mctp_usblib_rx_complete(struct net_device *netdev, + struct mctp_usblib_rx *rx, size_t len); + +void mctp_usblib_rx_cancel(struct mctp_usblib_rx *rx); + #endif /* __LINUX_USB_MCTP_USB_H */ -- cgit v1.2.3 From aadf5ed03e85736d755162ecbfc4d57d2044be49 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:26 +0800 Subject: net: mctp: usblib: Move TX transfer processing to mctp-usblib With the RX processing in mctp-usblib, add TX processing alongside. To accommodate packed transfers in DSP0283, where a transfer may contain multiple MCTP packets, we move to a split process for the transmit API: * push: create a new transmit context, and add a skb to it. * send: callback to the driver implementation to send the (possibly multi-packet) USB transfer * complete: update skb accounting and release the tx context The actual multi-packet transfer implementation will be added in the next change; no tx context persists beyond the single send at present. However, we use an anchor in the host driver implementation to track the submitted TX urb when necessary. While we're here, fix an inconsistency between tx and rx stats: both should not include the transport header. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-5-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index 595e6af16dd0..76f9d8879254 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -55,4 +55,43 @@ int mctp_usblib_rx_complete(struct net_device *netdev, void mctp_usblib_rx_cancel(struct mctp_usblib_rx *rx); +/* + * TX handle: created by mctp_usblib_tx_push() during the tx path, and + * may persist across multiple packet transmits. + * + * Currently though, there is a 1:1 mapping between packets and transfers, so + * the tx context will be cleared over each transmit. This will change in + * future. + */ +struct mctp_usblib_tx_ctx; + +struct mctp_usblib_tx_ops { + /* Start a USB TX for @data. On returning success, the implementation + * must arrange for mctp_usblib_tx_send_complete() to be called at some + * later point (eg., on urb completion). + */ + int (*send)(struct mctp_usblib_tx_ctx *tx_ctx, void *data, size_t len); +}; + +struct mctp_usblib_tx { + struct mctp_usblib_tx_ops ops; + void *priv; +}; + +void mctp_usblib_tx_init(struct mctp_usblib_tx *tx, + const struct mctp_usblib_tx_ops *ops, void *priv); +void mctp_usblib_tx_fini(struct mctp_usblib_tx *tx); + +void *mctp_usblib_tx_ctx_priv(struct mctp_usblib_tx_ctx *tx_ctx); + +int mctp_usblib_tx_push(struct net_device *dev, + struct mctp_usblib_tx *tx, + struct sk_buff *skb, bool more); + +void mctp_usblib_tx_send_complete(struct mctp_usblib_tx_ctx *tx_ctx, + struct net_device *dev, bool ok); + +void mctp_usblib_tx_cancel(struct mctp_usblib_tx *tx, struct net_device *dev, + enum skb_drop_reason reason); + #endif /* __LINUX_USB_MCTP_USB_H */ -- cgit v1.2.3 From 76a58ffd741719eada095e311961539a82c75e71 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:27 +0800 Subject: net: mctp: usblib: Add support for multi-packet transmit The MCTP over USB spec allows us to pack multiple packets in one transfer. Given the packet max length is 255, and the transfer max length is 512, we can typically include two full-size packets per urb submission. To do this, we allow a struct mctp_usb_tx to persist a tx_ctx, representing the ongoing context for a transmit. If possible, a TX skb will be queued to the context and the send deferred until the context is full, or the device queue reports no more packets. This typically requires a linear buffer for the 512-byte TX, which we allocate along with the TX context. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-6-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index 76f9d8879254..2e1cde6a6745 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -58,10 +58,6 @@ void mctp_usblib_rx_cancel(struct mctp_usblib_rx *rx); /* * TX handle: created by mctp_usblib_tx_push() during the tx path, and * may persist across multiple packet transmits. - * - * Currently though, there is a 1:1 mapping between packets and transfers, so - * the tx context will be cleared over each transmit. This will change in - * future. */ struct mctp_usblib_tx_ctx; @@ -76,6 +72,10 @@ struct mctp_usblib_tx_ops { struct mctp_usblib_tx { struct mctp_usblib_tx_ops ops; void *priv; + /* protects access to cur_ctx */ + spinlock_t lock; + /* context to which we are adding packets, cleared on send */ + struct mctp_usblib_tx_ctx *cur_ctx; }; void mctp_usblib_tx_init(struct mctp_usblib_tx *tx, -- cgit v1.2.3 From f5bf226f3c7aab957d8874f7d437b08017b5c428 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:28 +0800 Subject: net: mctp: usb: Accommodate DSP0283 v1.1 header format In the v1.1 update to DSP0283, we have a larger header field, of 13 bits rather than 8. In order to accommodate this, in preparation for proper v1.1 support, expand our struct mctp_usb_hdr's len field to a u16, and endian-convert when necessary. Because we don't yet support spanning mode, we will never receive or transmit with the top 5 bits set, so we always mask out anyway. This allows for a future change where we allow spanning mode with >512-byte transfers. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-7-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index 2e1cde6a6745..1a5e795b4ec1 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -2,7 +2,7 @@ /* * mctp-usb.h - MCTP USB transport binding: common definitions, * based on DMTF0283 specification: - * https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.0.1.pdf + * https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.1.0.pdf * * These are protocol-level definitions, that may be shared between host * and gadget drivers. @@ -17,10 +17,15 @@ #include #include +/* + * MCTP-over-USB transport header. DSP0283 v1.0 has an 8-bit length field + * (preceded by 8 reserved bits), v1.1 has a 13-bit length field (preceded by + * 3 reserved bits). We use a be16 for our length to handle the larger v1.1 + * representation, and mask as appropriate. + */ struct mctp_usb_hdr { __be16 id; - u8 rsvd; - u8 len; + __be16 len; } __packed; /* max transfer size for DSP0283 v1.0 */ -- cgit v1.2.3 From d52fc7f09a18d0c2b2c164e0a82136510cfa1798 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:29 +0800 Subject: net: mctp: usblib: Implement receive-side packet spanning Using the existing prepare/complete API, we can persist the rx skb across receives to implement v1.1 packet spanning. Alter the packet-extraction loop to allow truncated packets, returning early with the skb persisted for the next IN urb completion. When we see we have a complete packet, netif_rx() that. If the packet boundary aligns with the urb completion, we can netif_rx() the whole thing. Those intermediate packets are cloned from the original (large-transfer-data) skb. Unlike existing behaviour, if the clone fails, we drop just that clone, instead of the existing transfer skb. This allows us to process the rest of the skb data, and any continuation of the span into the next transfer. One subtle change: the mctp_usblib_rx() helper now handles skbs with the full transport header, so we shift the skb_pull() for the header data to the helper, before doing the rx_bytes stats update. We still need to handle non-spanning mode, so error out on truncated-packet cases there. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-8-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index 1a5e795b4ec1..2979ddaa4dab 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -34,6 +34,8 @@ struct mctp_usb_hdr { #define MCTP_USB_MTU_MIN MCTP_USB_BTU #define MCTP_USB_1_0_PKTLEN_MAX U8_MAX #define MCTP_USB_1_0_MTU_MAX (MCTP_USB_1_0_PKTLEN_MAX - sizeof(struct mctp_usb_hdr)) +#define MCTP_USB_1_1_PKTLEN_MAX GENMASK(12, 0) +#define MCTP_USB_1_1_MTU_MAX (MCTP_USB_1_1_PKTLEN_MAX - sizeof(struct mctp_usb_hdr)) #define MCTP_USB_DMTF_ID 0x1ab4 /* mctp-usblib */ @@ -46,9 +48,11 @@ struct mctp_usb_hdr { */ struct mctp_usblib_rx { struct sk_buff *skb; + u16 ep_pktlen; + bool span; }; -void mctp_usblib_rx_init(struct mctp_usblib_rx *rx); +int mctp_usblib_rx_init(struct mctp_usblib_rx *rx, u16 ep_pktlen, bool span); void mctp_usblib_rx_fini(struct mctp_usblib_rx *rx); int mctp_usblib_rx_prepare(struct net_device *netdev, -- cgit v1.2.3 From 081ac93ca99c2ded63a4fb78c385ebedf03560c2 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Fri, 24 Jul 2026 13:15:30 +0800 Subject: net: mctp: usblib: Implement transmit-side packet spanning Add support for packet spanning as defined in DSP0283 v1.1. With the existing v1.0 implementation of multi-packet transfers, all we need here is to adjust the buffer sizes to suit v1.1. Signed-off-by: Jeremy Kerr Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-9-e66bbba0dbdc@codeconstruct.com.au Signed-off-by: Jakub Kicinski --- include/linux/usb/mctp-usb.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/usb/mctp-usb.h b/include/linux/usb/mctp-usb.h index 2979ddaa4dab..4bb04a371105 100644 --- a/include/linux/usb/mctp-usb.h +++ b/include/linux/usb/mctp-usb.h @@ -81,6 +81,7 @@ struct mctp_usblib_tx_ops { struct mctp_usblib_tx { struct mctp_usblib_tx_ops ops; void *priv; + bool span; /* protects access to cur_ctx */ spinlock_t lock; /* context to which we are adding packets, cleared on send */ @@ -88,7 +89,8 @@ struct mctp_usblib_tx { }; void mctp_usblib_tx_init(struct mctp_usblib_tx *tx, - const struct mctp_usblib_tx_ops *ops, void *priv); + const struct mctp_usblib_tx_ops *ops, void *priv, + bool span); void mctp_usblib_tx_fini(struct mctp_usblib_tx *tx); void *mctp_usblib_tx_ctx_priv(struct mctp_usblib_tx_ctx *tx_ctx); -- cgit v1.2.3