Lines Matching +full:rx +full:- +full:status +full:- +full:len
1 // SPDX-License-Identifier: GPL-2.0
3 * mctp-usb.c - MCTP-over-USB (DMTF DSP0283) transport binding driver.
8 * Copyright (C) 2024-2025 Code Construct Pty Ltd
14 #include <linux/usb/mctp-usb.h>
40 struct sk_buff *skb = urb->context; in mctp_usb_out_complete()
41 struct net_device *netdev = skb->dev; in mctp_usb_out_complete()
42 int status; in mctp_usb_out_complete() local
44 status = urb->status; in mctp_usb_out_complete()
46 switch (status) { in mctp_usb_out_complete()
47 case -ENOENT: in mctp_usb_out_complete()
48 case -ECONNRESET: in mctp_usb_out_complete()
49 case -ESHUTDOWN: in mctp_usb_out_complete()
50 case -EPROTO: in mctp_usb_out_complete()
54 dev_dstats_tx_add(netdev, skb->len); in mctp_usb_out_complete()
59 netdev_dbg(netdev, "unexpected tx urb status: %d\n", status); in mctp_usb_out_complete()
75 plen = skb->len; in mctp_usb_start_xmit()
88 hdr->id = cpu_to_be16(MCTP_USB_DMTF_ID); in mctp_usb_start_xmit()
89 hdr->rsvd = 0; in mctp_usb_start_xmit()
90 hdr->len = plen + sizeof(*hdr); in mctp_usb_start_xmit()
92 urb = mctp_usb->tx_urb; in mctp_usb_start_xmit()
94 usb_fill_bulk_urb(urb, mctp_usb->usbdev, in mctp_usb_start_xmit()
95 usb_sndbulkpipe(mctp_usb->usbdev, mctp_usb->ep_out), in mctp_usb_start_xmit()
96 skb->data, skb->len, in mctp_usb_start_xmit()
118 * urb submission), we will schedule a rx queue in nonatomic context
128 skb = __netdev_alloc_skb(mctp_usb->netdev, MCTP_USB_XFER_SIZE, gfp); in mctp_usb_rx_queue()
130 rc = -ENOMEM; in mctp_usb_rx_queue()
134 usb_fill_bulk_urb(mctp_usb->rx_urb, mctp_usb->usbdev, in mctp_usb_rx_queue()
135 usb_rcvbulkpipe(mctp_usb->usbdev, mctp_usb->ep_in), in mctp_usb_rx_queue()
136 skb->data, MCTP_USB_XFER_SIZE, in mctp_usb_rx_queue()
139 rc = usb_submit_urb(mctp_usb->rx_urb, gfp); in mctp_usb_rx_queue()
141 netdev_dbg(mctp_usb->netdev, "rx urb submit failure: %d\n", rc); in mctp_usb_rx_queue()
143 if (rc == -ENOMEM) in mctp_usb_rx_queue()
150 schedule_delayed_work(&mctp_usb->rx_retry_work, RX_RETRY_DELAY); in mctp_usb_rx_queue()
156 struct sk_buff *skb = urb->context; in mctp_usb_in_complete()
157 struct net_device *netdev = skb->dev; in mctp_usb_in_complete()
160 unsigned int len; in mctp_usb_in_complete() local
161 int status; in mctp_usb_in_complete() local
163 status = urb->status; in mctp_usb_in_complete()
165 switch (status) { in mctp_usb_in_complete()
166 case -ENOENT: in mctp_usb_in_complete()
167 case -ECONNRESET: in mctp_usb_in_complete()
168 case -ESHUTDOWN: in mctp_usb_in_complete()
169 case -EPROTO: in mctp_usb_in_complete()
175 netdev_dbg(netdev, "unexpected rx urb status: %d\n", status); in mctp_usb_in_complete()
180 len = urb->actual_length; in mctp_usb_in_complete()
181 __skb_put(skb, len); in mctp_usb_in_complete()
193 if (be16_to_cpu(hdr->id) != MCTP_USB_DMTF_ID) { in mctp_usb_in_complete()
194 netdev_dbg(netdev, "rx: invalid id %04x\n", in mctp_usb_in_complete()
195 be16_to_cpu(hdr->id)); in mctp_usb_in_complete()
199 if (hdr->len < in mctp_usb_in_complete()
201 netdev_dbg(netdev, "rx: short packet (hdr) %d\n", in mctp_usb_in_complete()
202 hdr->len); in mctp_usb_in_complete()
207 pkt_len = hdr->len - sizeof(struct mctp_usb_hdr); in mctp_usb_in_complete()
208 if (pkt_len > skb->len) { in mctp_usb_in_complete()
210 "rx: short packet (xfer) %d, actual %d\n", in mctp_usb_in_complete()
211 hdr->len, skb->len); in mctp_usb_in_complete()
215 if (pkt_len < skb->len) { in mctp_usb_in_complete()
216 /* more packets may follow - clone to a new in mctp_usb_in_complete()
229 dev_dstats_rx_add(netdev, skb->len); in mctp_usb_in_complete()
231 skb->protocol = htons(ETH_P_MCTP); in mctp_usb_in_complete()
234 cb->halen = 0; in mctp_usb_in_complete()
251 if (READ_ONCE(mctp_usb->stopped)) in mctp_usb_rx_retry_work()
261 WRITE_ONCE(mctp_usb->stopped, false); in mctp_usb_open()
274 /* prevent RX submission retry */ in mctp_usb_stop()
275 WRITE_ONCE(mctp_usb->stopped, true); in mctp_usb_stop()
277 usb_kill_urb(mctp_usb->rx_urb); in mctp_usb_stop()
278 usb_kill_urb(mctp_usb->tx_urb); in mctp_usb_stop()
280 cancel_delayed_work_sync(&mctp_usb->rx_retry_work); in mctp_usb_stop()
293 dev->type = ARPHRD_MCTP; in mctp_usb_netdev_setup()
295 dev->mtu = MCTP_USB_MTU_MIN; in mctp_usb_netdev_setup()
296 dev->min_mtu = MCTP_USB_MTU_MIN; in mctp_usb_netdev_setup()
297 dev->max_mtu = MCTP_USB_MTU_MAX; in mctp_usb_netdev_setup()
299 dev->hard_header_len = sizeof(struct mctp_usb_hdr); in mctp_usb_netdev_setup()
300 dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; in mctp_usb_netdev_setup()
301 dev->flags = IFF_NOARP; in mctp_usb_netdev_setup()
302 dev->netdev_ops = &mctp_usb_netdev_ops; in mctp_usb_netdev_setup()
303 dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS; in mctp_usb_netdev_setup()
316 iface_desc = intf->cur_altsetting; in mctp_usb_probe()
320 dev_err(&intf->dev, "invalid endpoints on device?\n"); in mctp_usb_probe()
327 return -ENOMEM; in mctp_usb_probe()
329 SET_NETDEV_DEV(netdev, &intf->dev); in mctp_usb_probe()
331 dev->netdev = netdev; in mctp_usb_probe()
332 dev->usbdev = usb_get_dev(interface_to_usbdev(intf)); in mctp_usb_probe()
333 dev->intf = intf; in mctp_usb_probe()
336 dev->ep_in = ep_in->bEndpointAddress; in mctp_usb_probe()
337 dev->ep_out = ep_out->bEndpointAddress; in mctp_usb_probe()
339 dev->tx_urb = usb_alloc_urb(0, GFP_KERNEL); in mctp_usb_probe()
340 dev->rx_urb = usb_alloc_urb(0, GFP_KERNEL); in mctp_usb_probe()
341 if (!dev->tx_urb || !dev->rx_urb) { in mctp_usb_probe()
342 rc = -ENOMEM; in mctp_usb_probe()
346 INIT_DELAYED_WORK(&dev->rx_retry_work, mctp_usb_rx_retry_work); in mctp_usb_probe()
355 usb_free_urb(dev->tx_urb); in mctp_usb_probe()
356 usb_free_urb(dev->rx_urb); in mctp_usb_probe()
365 mctp_unregister_netdev(dev->netdev); in mctp_usb_disconnect()
366 usb_free_urb(dev->tx_urb); in mctp_usb_disconnect()
367 usb_free_urb(dev->rx_urb); in mctp_usb_disconnect()
368 usb_put_dev(dev->usbdev); in mctp_usb_disconnect()
369 free_netdev(dev->netdev); in mctp_usb_disconnect()
380 .name = "mctp-usb",