1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/* SPDX-License-Identifier: GPL-2.0 */
/*
* mctp-usb.h - MCTP USB transport binding: common definitions,
* based on DMTF0283 specification:
* 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.
*
* Copyright (C) 2024-2025 Code Construct Pty Ltd
*/
#ifndef __LINUX_USB_MCTP_USB_H
#define __LINUX_USB_MCTP_USB_H
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/types.h>
/*
* 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;
__be16 len;
} __packed;
/* 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_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 */
/*
* 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;
u16 ep_pktlen;
bool span;
};
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,
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);
/*
* TX handle: created by mctp_usblib_tx_push() during the tx path, and
* may persist across multiple packet transmits.
*/
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;
bool span;
/* 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,
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);
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 */
|