net: mctp: usb: enable v1.1 packet spanning

Now that mctp-usblib supports DSP0283 v1.1 packet spanning, enable it in
our host-side transport driver.

Add a match for the new device subclass (0x02), and indicating spanning
mode to the usblib rx/tx implementation.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
Link: https://patch.msgid.link/20260724-dev-mctp-usb-1-1-v5-11-e66bbba0dbdc@codeconstruct.com.au
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jeremy Kerr 2026-07-24 13:15:32 +08:00 committed by Jakub Kicinski
parent e84c0edbc4
commit b4a27a474b

View File

@ -3,9 +3,9 @@
* mctp-usb.c - MCTP-over-USB (DMTF DSP0283) transport binding driver.
*
* DSP0283 is available at:
* 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
*
* Copyright (C) 2024-2025 Code Construct Pty Ltd
* Copyright (C) 2024-2026 Code Construct Pty Ltd
*/
#include <linux/module.h>
@ -22,6 +22,7 @@
struct mctp_usb {
struct usb_device *usbdev;
struct usb_interface *intf;
bool span;
struct net_device *netdev;
@ -43,6 +44,11 @@ struct mctp_usb {
struct usb_anchor tx_anchor;
};
enum {
MCTP_USB_SUBCLASS_BASE = 0x00,
MCTP_USB_SUBCLASS_SPAN = 0x02,
};
static void mctp_usb_out_complete(struct urb *urb)
{
struct mctp_usblib_tx_ctx *tx_ctx = urb->context;
@ -71,6 +77,9 @@ static int mctp_usb_tx_send(struct mctp_usblib_tx_ctx *tx_ctx,
usb_sndbulkpipe(mctp_usb->usbdev, mctp_usb->ep_out),
data, len, mctp_usb_out_complete, tx_ctx);
if (mctp_usb->span)
urb->transfer_flags |= URB_ZERO_PACKET;
netif_stop_queue(mctp_usb->netdev);
usb_anchor_urb(urb, &mctp_usb->tx_anchor);
@ -316,6 +325,7 @@ static int mctp_usb_probe(struct usb_interface *intf,
struct usb_host_interface *iface_desc;
struct net_device *netdev;
struct mctp_usb *dev;
bool span;
int rc;
/* only one alternate */
@ -327,6 +337,8 @@ static int mctp_usb_probe(struct usb_interface *intf,
return rc;
}
span = iface_desc->desc.bInterfaceSubClass == MCTP_USB_SUBCLASS_SPAN;
netdev = alloc_netdev(sizeof(*dev), "mctpusb%d", NET_NAME_ENUM,
mctp_usb_netdev_setup);
if (!netdev)
@ -334,17 +346,20 @@ static int mctp_usb_probe(struct usb_interface *intf,
SET_NETDEV_DEV(netdev, &intf->dev);
dev = netdev_priv(netdev);
dev->span = span;
dev->netdev = netdev;
dev->usbdev = interface_to_usbdev(intf);
dev->intf = intf;
spin_lock_init(&dev->rx_lock);
if (dev->span)
netdev->max_mtu = MCTP_USB_1_1_MTU_MAX;
usb_set_intfdata(intf, dev);
rc = mctp_usblib_rx_init(&dev->rx, le16_to_cpu(ep_in->wMaxPacketSize),
false);
dev->span);
if (rc)
goto err_free_netdev;
mctp_usblib_tx_init(&dev->tx, &tx_ops, dev, false);
mctp_usblib_tx_init(&dev->tx, &tx_ops, dev, dev->span);
init_usb_anchor(&dev->tx_anchor);
dev->ep_in = ep_in->bEndpointAddress;
@ -386,7 +401,8 @@ static void mctp_usb_disconnect(struct usb_interface *intf)
}
static const struct usb_device_id mctp_usb_devices[] = {
{ USB_INTERFACE_INFO(USB_CLASS_MCTP, 0x0, 0x1) },
{ USB_INTERFACE_INFO(USB_CLASS_MCTP, MCTP_USB_SUBCLASS_BASE, 0x1) },
{ USB_INTERFACE_INFO(USB_CLASS_MCTP, MCTP_USB_SUBCLASS_SPAN, 0x1) },
{ 0 },
};