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 skb_reset_mac_header(skb); 187 hdr = skb_pull_data(skb, sizeof(*hdr)); 188 if (!hdr) 189 break; 190 191 if (be16_to_cpu(hdr->id) != MCTP_USB_DMTF_ID) { 192 netdev_dbg(netdev, "rx: invalid id %04x\n", 193 be16_to_cpu(hdr->id)); 194 break; 195 } 196 197 if (hdr->len < 198 sizeof(struct mctp_hdr) + sizeof(struct mctp_usb_hdr)) { 199 netdev_dbg(netdev, "rx: short packet (hdr) %d\n", 200 hdr->len); 201 break; 202 } 203 204 /* we know we have at least sizeof(struct mctp_usb_hdr) here */ 205 pkt_len = hdr->len - sizeof(struct mctp_usb_hdr); 206 if (pkt_len > skb->len) { 207 netdev_dbg(netdev, 208 "rx: short packet (xfer) %d, actual %d\n", 209 hdr->len, skb->len); 210 break; 211 } 212 213 if (pkt_len < skb->len) { 214 /* more packets may follow - clone to a new 215 * skb to use on the next iteration 216 */ 217 skb2 = skb_clone(skb, GFP_ATOMIC); 218 if (skb2) { 219 if (!skb_pull(skb2, pkt_len)) { 220 kfree_skb(skb2); 221 skb2 = NULL; 222 } 223 } 224 skb_trim(skb, pkt_len); 225 } 226 227 dev_dstats_rx_add(netdev, skb->len); 228 229 skb->protocol = htons(ETH_P_MCTP); 230 skb_reset_network_header(skb); 231 cb = __mctp_cb(skb); 232 cb->halen = 0; 233 netif_rx(skb); 234 235 skb = skb2; 236 } 237 238 if (skb) 239 kfree_skb(skb); 240 241 mctp_usb_rx_queue(mctp_usb, GFP_ATOMIC); 242 } 243 244 static void mctp_usb_rx_retry_work(struct work_struct *work) 245 { 246 struct mctp_usb *mctp_usb = container_of(work, struct mctp_usb, 247 rx_retry_work.work); 248 249 if (READ_ONCE(mctp_usb->stopped)) 250 return; 251 252 mctp_usb_rx_queue(mctp_usb, GFP_KERNEL); 253 } 254 255 static int mctp_usb_open(struct net_device *dev) 256 { 257 struct mctp_usb *mctp_usb = netdev_priv(dev); 258 259 WRITE_ONCE(mctp_usb->stopped, false); 260 261 netif_start_queue(dev); 262 263 return mctp_usb_rx_queue(mctp_usb, GFP_KERNEL); 264 } 265 266 static int mctp_usb_stop(struct net_device *dev) 267 { 268 struct mctp_usb *mctp_usb = netdev_priv(dev); 269 270 netif_stop_queue(dev); 271 272 /* prevent RX submission retry */ 273 WRITE_ONCE(mctp_usb->stopped, true); 274 275 usb_kill_urb(mctp_usb->rx_urb); 276 usb_kill_urb(mctp_usb->tx_urb); 277 278 cancel_delayed_work_sync(&mctp_usb->rx_retry_work); 279 280 return 0; 281 } 282 283 static const struct net_device_ops mctp_usb_netdev_ops = { 284 .ndo_start_xmit = mctp_usb_start_xmit, 285 .ndo_open = mctp_usb_open, 286 .ndo_stop = mctp_usb_stop, 287 }; 288 289 static void mctp_usb_netdev_setup(struct net_device *dev) 290 { 291 dev->type = ARPHRD_MCTP; 292 293 dev->mtu = MCTP_USB_MTU_MIN; 294 dev->min_mtu = MCTP_USB_MTU_MIN; 295 dev->max_mtu = MCTP_USB_MTU_MAX; 296 297 dev->hard_header_len = sizeof(struct mctp_usb_hdr); 298 dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; 299 dev->flags = IFF_NOARP; 300 dev->netdev_ops = &mctp_usb_netdev_ops; 301 dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; 302 } 303 304 static int mctp_usb_probe(struct usb_interface *intf, 305 const struct usb_device_id *id) 306 { 307 struct usb_endpoint_descriptor *ep_in, *ep_out; 308 struct usb_host_interface *iface_desc; 309 struct net_device *netdev; 310 struct mctp_usb *dev; 311 int rc; 312 313 /* only one alternate */ 314 iface_desc = intf->cur_altsetting; 315 316 rc = usb_find_common_endpoints(iface_desc, &ep_in, &ep_out, NULL, NULL); 317 if (rc) { 318 dev_err(&intf->dev, "invalid endpoints on device?\n"); 319 return rc; 320 } 321 322 netdev = alloc_netdev(sizeof(*dev), "mctpusb%d", NET_NAME_ENUM, 323 mctp_usb_netdev_setup); 324 if (!netdev) 325 return -ENOMEM; 326 327 SET_NETDEV_DEV(netdev, &intf->dev); 328 dev = netdev_priv(netdev); 329 dev->netdev = netdev; 330 dev->usbdev = usb_get_dev(interface_to_usbdev(intf)); 331 dev->intf = intf; 332 usb_set_intfdata(intf, dev); 333 334 dev->ep_in = ep_in->bEndpointAddress; 335 dev->ep_out = ep_out->bEndpointAddress; 336 337 dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL); 338 dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL); 339 if (!dev->tx_urb || !dev->rx_urb) { 340 rc = -ENOMEM; 341 goto err_free_urbs; 342 } 343 344 INIT_DELAYED_WORK(&dev->rx_retry_work, mctp_usb_rx_retry_work); 345 346 rc = mctp_register_netdev(netdev, NULL, MCTP_PHYS_BINDING_USB); 347 if (rc) 348 goto err_free_urbs; 349 350 return 0; 351 352 err_free_urbs: 353 usb_free_urb(dev->tx_urb); 354 usb_free_urb(dev->rx_urb); 355 free_netdev(netdev); 356 return rc; 357 } 358 359 static void mctp_usb_disconnect(struct usb_interface *intf) 360 { 361 struct mctp_usb *dev = usb_get_intfdata(intf); 362 363 mctp_unregister_netdev(dev->netdev); 364 usb_free_urb(dev->tx_urb); 365 usb_free_urb(dev->rx_urb); 366 usb_put_dev(dev->usbdev); 367 free_netdev(dev->netdev); 368 } 369 370 static const struct usb_device_id mctp_usb_devices[] = { 371 { USB_INTERFACE_INFO(USB_CLASS_MCTP, 0x0, 0x1) }, 372 { 0 }, 373 }; 374 375 MODULE_DEVICE_TABLE(usb, mctp_usb_devices); 376 377 static struct usb_driver mctp_usb_driver = { 378 .name = "mctp-usb", 379 .id_table = mctp_usb_devices, 380 .probe = mctp_usb_probe, 381 .disconnect = mctp_usb_disconnect, 382 }; 383 384 module_usb_driver(mctp_usb_driver) 385 386 MODULE_LICENSE("GPL"); 387 MODULE_AUTHOR("Jeremy Kerr <jk@codeconstruct.com.au>"); 388 MODULE_DESCRIPTION("MCTP USB transport"); 389