| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * CAN driver for "8 devices" USB2CAN converter |
|---|
| 3 | 4 | * |
|---|
| 4 | 5 | * Copyright (C) 2012 Bernd Krumboeck (krumboeck@universalnet.at) |
|---|
| 5 | | - * |
|---|
| 6 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 7 | | - * under the terms of the GNU General Public License as published |
|---|
| 8 | | - * by the Free Software Foundation; version 2 of the License. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 11 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 13 | | - * General Public License for more details. |
|---|
| 14 | | - * |
|---|
| 15 | | - * You should have received a copy of the GNU General Public License along |
|---|
| 16 | | - * with this program. |
|---|
| 17 | 6 | * |
|---|
| 18 | 7 | * This driver is inspired by the 3.2.0 version of drivers/net/can/usb/ems_usb.c |
|---|
| 19 | 8 | * and drivers/net/can/usb/esd_usb2.c |
|---|
| .. | .. |
|---|
| 99 | 88 | |
|---|
| 100 | 89 | /* status */ |
|---|
| 101 | 90 | #define USB_8DEV_STATUSMSG_OK 0x00 /* Normal condition. */ |
|---|
| 102 | | -#define USB_8DEV_STATUSMSG_OVERRUN 0x01 /* Overrun occured when sending */ |
|---|
| 91 | +#define USB_8DEV_STATUSMSG_OVERRUN 0x01 /* Overrun occurred when sending */ |
|---|
| 103 | 92 | #define USB_8DEV_STATUSMSG_BUSLIGHT 0x02 /* Error counter has reached 96 */ |
|---|
| 104 | 93 | #define USB_8DEV_STATUSMSG_BUSHEAVY 0x03 /* Error count. has reached 128 */ |
|---|
| 105 | 94 | #define USB_8DEV_STATUSMSG_BUSOFF 0x04 /* Device is in BUSOFF */ |
|---|
| .. | .. |
|---|
| 177 | 166 | /* command frame */ |
|---|
| 178 | 167 | struct __packed usb_8dev_cmd_msg { |
|---|
| 179 | 168 | u8 begin; |
|---|
| 180 | | - u8 channel; /* unkown - always 0 */ |
|---|
| 169 | + u8 channel; /* unknown - always 0 */ |
|---|
| 181 | 170 | u8 command; /* command to execute */ |
|---|
| 182 | 171 | u8 opt1; /* optional parameter / return value */ |
|---|
| 183 | 172 | u8 opt2; /* optional parameter 2 */ |
|---|
| .. | .. |
|---|
| 453 | 442 | |
|---|
| 454 | 443 | if (rx_errors) |
|---|
| 455 | 444 | stats->rx_errors++; |
|---|
| 456 | | - |
|---|
| 457 | | - cf->data[6] = txerr; |
|---|
| 458 | | - cf->data[7] = rxerr; |
|---|
| 445 | + if (priv->can.state != CAN_STATE_BUS_OFF) { |
|---|
| 446 | + cf->data[6] = txerr; |
|---|
| 447 | + cf->data[7] = rxerr; |
|---|
| 448 | + } |
|---|
| 459 | 449 | |
|---|
| 460 | 450 | priv->bec.txerr = txerr; |
|---|
| 461 | 451 | priv->bec.rxerr = rxerr; |
|---|
| .. | .. |
|---|
| 681 | 671 | atomic_inc(&priv->active_tx_urbs); |
|---|
| 682 | 672 | |
|---|
| 683 | 673 | err = usb_submit_urb(urb, GFP_ATOMIC); |
|---|
| 684 | | - if (unlikely(err)) |
|---|
| 685 | | - goto failed; |
|---|
| 686 | | - else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS) |
|---|
| 674 | + if (unlikely(err)) { |
|---|
| 675 | + can_free_echo_skb(netdev, context->echo_index); |
|---|
| 676 | + |
|---|
| 677 | + usb_unanchor_urb(urb); |
|---|
| 678 | + usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); |
|---|
| 679 | + |
|---|
| 680 | + atomic_dec(&priv->active_tx_urbs); |
|---|
| 681 | + |
|---|
| 682 | + if (err == -ENODEV) |
|---|
| 683 | + netif_device_detach(netdev); |
|---|
| 684 | + else |
|---|
| 685 | + netdev_warn(netdev, "failed tx_urb %d\n", err); |
|---|
| 686 | + stats->tx_dropped++; |
|---|
| 687 | + } else if (atomic_read(&priv->active_tx_urbs) >= MAX_TX_URBS) |
|---|
| 687 | 688 | /* Slow down tx path */ |
|---|
| 688 | 689 | netif_stop_queue(netdev); |
|---|
| 689 | 690 | |
|---|
| .. | .. |
|---|
| 701 | 702 | netdev_warn(netdev, "couldn't find free context"); |
|---|
| 702 | 703 | |
|---|
| 703 | 704 | return NETDEV_TX_BUSY; |
|---|
| 704 | | - |
|---|
| 705 | | -failed: |
|---|
| 706 | | - can_free_echo_skb(netdev, context->echo_index); |
|---|
| 707 | | - |
|---|
| 708 | | - usb_unanchor_urb(urb); |
|---|
| 709 | | - usb_free_coherent(priv->udev, size, buf, urb->transfer_dma); |
|---|
| 710 | | - |
|---|
| 711 | | - atomic_dec(&priv->active_tx_urbs); |
|---|
| 712 | | - |
|---|
| 713 | | - if (err == -ENODEV) |
|---|
| 714 | | - netif_device_detach(netdev); |
|---|
| 715 | | - else |
|---|
| 716 | | - netdev_warn(netdev, "failed tx_urb %d\n", err); |
|---|
| 717 | 705 | |
|---|
| 718 | 706 | nomembuf: |
|---|
| 719 | 707 | usb_free_urb(urb); |
|---|