1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * mctp-usb.c - MCTP-over-USB (DMTF DSP0283) transport binding driver. 4 * 5 * DSP0283 is available at: 6 * https://www.dmtf.org/sites/default/files/standards/documents/DSP0283_1.0.1.pdf 7 * 8 * Copyright (C) 2024-2025 Code Construct Pty Ltd 9 */ 10 11 #include <linux/module.h> 12 #include <linux/netdevice.h> 13 #include <linux/usb.h> 14 #include <linux/usb/mctp-usb.h> 15 16 #include <net/mctp.h> 17 #include <net/mctpdevice.h> 18 #include <net/pkt_sched.h> 19 20 #include <uapi/linux/if_arp.h> 21 22 struct mctp_usb { 23 struct usb_device *usbdev; 24 struct usb_interface *intf; 25 bool stopped; 26 27 struct net_device *netdev; 28 29 u8 ep_in; 30 u8 ep_out; 31 32 struct urb *tx_urb; 33 struct urb *rx_urb; 34 35 struct delayed_work rx_retry_work; 36 }; 37 38 static void mctp_usb_out_complete(struct urb *urb) 39 { 40 struct sk_buff *skb = urb->context; 41 struct net_device *netdev = skb->dev; 42 int status; 43 44 status = urb->status; 45 46 switch (status) { 47 case -ENOENT: 48 case -ECONNRESET: 49 case -ESHUTDOWN: 50 case -EPROTO: 51 dev_dstats_tx_dropped(netdev); 52 break; 53 case 0: 54 dev_dstats_tx_add(netdev, skb->len); 55 netif_wake_queue(netdev); 56 consume_skb(skb); 57 return; 58 default: 59 netdev_dbg(netdev, "unexpected tx urb status: %d\n", status); 60 dev_dstats_tx_dropped(netdev); 61 } 62 63 kfree_skb(skb); 64 } 65 66 static netdev_tx_t mctp_usb_start_xmit(struct sk_buff *skb, 67 struct net_device *dev) 68 { 69 struct mctp_usb *mctp_usb = netdev_priv(dev); 70 struct mctp_usb_hdr *hdr; 71 unsigned int plen; 72 struct urb *urb; 73 int rc; 74 75 plen = skb->len; 76 77 if (plen + sizeof(*hdr) > MCTP_USB_XFER_SIZE) 78 goto err_drop; 79 80 rc = skb_cow_head(skb, sizeof(*hdr)); 81 if (rc) 82 goto err_drop; 83 84 hdr = skb_push(skb, sizeof(*hdr)); 85 if (!hdr) 86 goto err_drop; 87 88 hdr->id = cpu_to_be16(MCTP_USB_DMTF_ID); 89 hdr->rsvd = 0; 90 hdr->len = plen + sizeof(*hdr); 91 92 urb = mctp_usb->tx_urb; 93 94 usb_fill_bulk_urb(urb, mctp_usb->usbdev, 95 usb_sndbulkpipe(mctp_usb->usbdev, mctp_usb->ep_out), 96 skb->data, skb->len, 97 mctp_usb_out_complete, skb); 98 99 rc = usb_submit_urb(urb, GFP_ATOMIC); 100 if (rc) 101 goto err_drop; 102 else 103 netif_stop_queue(dev); 104 105 return NETDEV_TX_OK; 106 107 err_drop: 108 dev_dstats_tx_dropped(dev); 109 kfree_skb(skb); 110 return NETDEV_TX_OK; 111 } 112 113 static void mctp_usb_in_complete(struct urb *urb); 114 115 /* If we fail to queue an in urb atomically (either due to skb allocation or 116 * urb submission), we will schedule a rx queue in nonatomic context 117 * after a delay, specified in jiffies 118 */ 119 static const unsigned long RX_RETRY_DELAY = HZ / 4; 120 121 static int mctp_usb_rx_queue(struct mctp_usb *mctp_usb, gfp_t gfp) 122 { 123 struct sk_buff *skb; 124 int rc; 125 126 skb = __netdev_alloc_skb(mctp_usb->netdev, MCTP_USB_XFER_SIZE, gfp); 127 if (!skb) { 128 rc = -ENOMEM; 129 goto err_retry; 130 } 131 132 usb_fill_bulk_urb(mctp_usb->rx_urb, mctp_usb->usbdev, 133 usb_rcvbulkpipe(mctp_usb->usbdev, mctp_usb->ep_in), 134 skb->data, MCTP_USB_XFER_SIZE, 135 mctp_usb_in_complete, skb); 136 137 rc = usb_submit_urb(mctp_usb->rx_urb, gfp); 138 if (rc) { 139 netdev_dbg(mctp_usb->netdev, "rx urb submit failure: %d\n", rc); 140 kfree_skb(skb); 141 if (rc == -ENOMEM) 142 goto err_retry; 143 } 144 145 return rc; 146 147 err_retry: 148 schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY); 149 return rc; 150 } 151 152 static void mctp_usb_in_complete(struct urb *urb) 153 { 154 struct sk_buff *skb = urb->context; 155 struct net_device *netdev = skb->dev; 156 struct mctp_usb *mctp_usb = netdev_priv(netdev); 157 struct mctp_skb_cb *cb; 158 unsigned int len; 159 int status; 160 161 status = urb->status; 162 163 switch (status) { 164 case -ENOENT: 165 case -ECONNRESET: 166 case -ESHUTDOWN: 167 case -EPROTO: 168 kfree_skb(skb); 169 return; 170 case 0: 171 break; 172 default: 173 netdev_dbg(netdev, "unexpected rx urb status: %d\n", status); 174 kfree_skb(skb); 175 return; 176 } 177 178 len = urb->actual_length; 179 __skb_put(skb, len); 180 181 while (skb) { 182 struct sk_buff *skb2 = NULL; 183 struct mctp_usb_hdr *hdr; 184 u8 pkt_len; /* length of MCTP packet, no USB header */ 185 186 hdr = skb_pull_data(skb, sizeof(*hdr)); 187 if (!hdr) 188 break; 189 190 if (be16_to_cpu(hdr->id) != MCTP_USB_DMTF_ID) { 191 netdev_dbg(netdev, "rx: invalid id %04x\n", 192 be16_to_cpu(hdr->id)); 193 break; 194 } 195 196 if (hdr->len < 197 sizeof(struct mctp_hdr) + sizeof(struct mctp_usb_hdr)) { 198 netdev_dbg(netdev, "rx: short packet (hdr) %d\n", 199 hdr->len); 200 break; 201 } 202 203 /* we know we have at least sizeof(struct mctp_usb_hdr) here */ 204 pkt_len = hdr->len - sizeof(struct mctp_usb_hdr); 205 if (pkt_len > skb->len) { 206 netdev_dbg(netdev, 207 "rx: short packet (xfer) %d, actual %d\n", 208 hdr->len, skb->len); 209 break; 210 } 211 212 if (pkt_len < skb->len) { 213 /* more packets may follow - clone to a new 214 * skb to use on the next iteration 215 */ 216 skb2 = skb_clone(skb, GFP_ATOMIC); 217 if (skb2) { 218 if (!skb_pull(skb2, pkt_len)) { 219 kfree_skb(skb2); 220 skb2 = NULL; 221 } 222 } 223 skb_trim(skb, pkt_len); 224 } 225 226 dev_dstats_rx_add(netdev, skb->len); 227 228 skb->protocol = htons(ETH_P_MCTP); 229 skb_reset_network_header(skb); 230 cb = __mctp_cb(skb); 231 cb->halen = 0; 232 netif_rx(skb); 233 234 skb = skb2; 235 } 236 237 if (skb) 238 kfree_skb(skb); 239 240 mctp_usb_rx_queue(mctp_usb, GFP_ATOMIC); 241 } 242 243 static void mctp_usb_rx_retry_work(struct work_struct *work) 244 { 245 struct mctp_usb *mctp_usb = container_of(work, struct mctp_usb, 246 rx_retry_work.work); 247 248 if (READ_ONCE(mctp_usb->stopped)) 249 return; 250 251 mctp_usb_rx_queue(mctp_usb, GFP_KERNEL); 252 } 253 254 static int mctp_usb_open(struct net_device *dev) 255 { 256 struct mctp_usb *mctp_usb = netdev_priv(dev); 257 258 WRITE_ONCE(mctp_usb->stopped, false); 259 260 netif_start_queue(dev); 261 262 return mctp_usb_rx_queue(mctp_usb, GFP_KERNEL); 263 } 264 265 static int mctp_usb_stop(struct net_device *dev) 266 { 267 struct mctp_usb *mctp_usb = netdev_priv(dev); 268 269 netif_stop_queue(dev); 270 271 /* prevent RX submission retry */ 272 WRITE_ONCE(mctp_usb->stopped, true); 273 274 usb_kill_urb(mctp_usb->rx_urb); 275 usb_kill_urb(mctp_usb->tx_urb); 276 277 cancel_delayed_work_sync(&mctp_usb->rx_retry_work); 278 279 return 0; 280 } 281 282 static const struct net_device_ops mctp_usb_netdev_ops = { 283 .ndo_start_xmit = mctp_usb_start_xmit, 284 .ndo_open = mctp_usb_open, 285 .ndo_stop = mctp_usb_stop, 286 }; 287 288 static void mctp_usb_netdev_setup(struct net_device *dev) 289 { 290 dev->type = ARPHRD_MCTP; 291 292 dev->mtu = MCTP_USB_MTU_MIN; 293 dev->min_mtu = MCTP_USB_MTU_MIN; 294 dev->max_mtu = MCTP_USB_MTU_MAX; 295 296 dev->hard_header_len = sizeof(struct mctp_usb_hdr); 297 dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; 298 dev->flags = IFF_NOARP; 299 dev->netdev_ops = &mctp_usb_netdev_ops; 300 dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 301 } 302 303 static int mctp_usb_probe(struct usb_interface *intf, 304 const struct usb_device_id *id) 305 { 306 struct usb_endpoint_descriptor *ep_in, *ep_out; 307 struct usb_host_interface *iface_desc; 308 struct net_device *netdev; 309 struct mctp_usb *dev; 310 int rc; 311 312 /* only one alternate */ 313 iface_desc = intf->cur_altsetting; 314 315 rc = usb_find_common_endpoints(iface_desc, &ep_in, &ep_out, NULL, NULL); 316 if (rc) { 317 dev_err(&intf->dev, "invalid endpoints on device?\n"); 318 return rc; 319 } 320 321 netdev = alloc_netdev(sizeof(*dev), "mctpusb%d", NET_NAME_ENUM, 322 mctp_usb_netdev_setup); 323 if (!netdev) 324 return -ENOMEM; 325 326 SET_NETDEV_DEV(netdev, &intf->dev); 327 dev = netdev_priv(netdev); 328 dev->netdev = netdev; 329 dev->usbdev = usb_get_dev(interface_to_usbdev(intf)); 330 dev->intf = intf; 331 usb_set_intfdata(intf, dev); 332 333 dev->ep_in = ep_in->bEndpointAddress; 334 dev->ep_out = ep_out->bEndpointAddress; 335 336 dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 337 dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 338 if (!dev->tx_urb || !dev->rx_urb) { 339 rc = -ENOMEM; 340 goto err_free_urbs; 341 } 342 343 INIT_DELAYED_WORK(&dev->rx_retry_work, mctp_usb_rx_retry_work); 344 345 rc = mctp_register_netdev(netdev, NULL, MCTP_PHYS_BINDING_USB); 346 if (rc) 347 goto err_free_urbs; 348 349 return 0; 350 351 err_free_urbs: 352 usb_free_urb(dev->tx_urb); 353 usb_free_urb(dev->rx_urb); 354 free_netdev(netdev); 355 return rc; 356 } 357 358 static void mctp_usb_disconnect(struct usb_interface *intf) 359 { 360 struct mctp_usb *dev = usb_get_intfdata(intf); 361 362 mctp_unregister_netdev(dev->netdev); 363 usb_free_urb(dev->tx_urb); 364 usb_free_urb(dev->rx_urb); 365 usb_put_dev(dev->usbdev); 366 free_netdev(dev->netdev); 367 } 368 369 static const struct usb_device_id mctp_usb_devices[] = { 370 { USB_INTERFACE_INFO(USB_CLASS_MCTP, 0x0, 0x1) }, 371 { 0 }, 372 }; 373 374 MODULE_DEVICE_TABLE(usb, mctp_usb_devices); 375 376 static struct usb_driver mctp_usb_driver = { 377 .name = "mctp-usb", 378 .id_table = mctp_usb_devices, 379 .probe = mctp_usb_probe, 380 .disconnect = mctp_usb_disconnect, 381 }; 382 383 module_usb_driver(mctp_usb_driver) 384 385 MODULE_LICENSE("GPL"); 386 MODULE_AUTHOR("Jeremy Kerr <jk@codeconstruct.com.au>"); 387 MODULE_DESCRIPTION("MCTP USB transport"); 388