| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* SocketCAN driver for Microchip CAN BUS Analyzer Tool |
|---|
| 2 | 3 | * |
|---|
| 3 | 4 | * Copyright (C) 2017 Mobica Limited |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 6 | | - * under the terms of the GNU General Public License as published |
|---|
| 7 | | - * by the Free Software Foundation; version 2 of the License. |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 10 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 12 | | - * General Public License for more details. |
|---|
| 13 | | - * |
|---|
| 14 | | - * You should have received a copy of the GNU General Public License along |
|---|
| 15 | | - * with this program. |
|---|
| 16 | 5 | * |
|---|
| 17 | 6 | * This driver is inspired by the 4.6.2 version of net/can/usb/usb_8dev.c |
|---|
| 18 | 7 | */ |
|---|
| .. | .. |
|---|
| 39 | 28 | #define MCBA_CTX_FREE MCBA_MAX_TX_URBS |
|---|
| 40 | 29 | |
|---|
| 41 | 30 | /* RX buffer must be bigger than msg size since at the |
|---|
| 42 | | - * beggining USB messages are stacked. |
|---|
| 31 | + * beginning USB messages are stacked. |
|---|
| 43 | 32 | */ |
|---|
| 44 | 33 | #define MCBA_USB_RX_BUFF_SIZE 64 |
|---|
| 45 | 34 | #define MCBA_USB_TX_BUFF_SIZE (sizeof(struct mcba_usb_msg)) |
|---|
| 46 | | - |
|---|
| 47 | | -/* MCBA endpoint numbers */ |
|---|
| 48 | | -#define MCBA_USB_EP_IN 1 |
|---|
| 49 | | -#define MCBA_USB_EP_OUT 1 |
|---|
| 50 | 35 | |
|---|
| 51 | 36 | /* Microchip command id */ |
|---|
| 52 | 37 | #define MBCA_CMD_RECEIVE_MESSAGE 0xE3 |
|---|
| .. | .. |
|---|
| 61 | 46 | |
|---|
| 62 | 47 | #define MCBA_VER_REQ_USB 1 |
|---|
| 63 | 48 | #define MCBA_VER_REQ_CAN 2 |
|---|
| 49 | + |
|---|
| 50 | +/* Drive the CAN_RES signal LOW "0" to activate R24 and R25 */ |
|---|
| 51 | +#define MCBA_VER_TERMINATION_ON 0 |
|---|
| 52 | +#define MCBA_VER_TERMINATION_OFF 1 |
|---|
| 64 | 53 | |
|---|
| 65 | 54 | #define MCBA_SIDL_EXID_MASK 0x8 |
|---|
| 66 | 55 | #define MCBA_DLC_MASK 0xf |
|---|
| .. | .. |
|---|
| 95 | 84 | atomic_t free_ctx_cnt; |
|---|
| 96 | 85 | void *rxbuf[MCBA_MAX_RX_URBS]; |
|---|
| 97 | 86 | dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS]; |
|---|
| 87 | + int rx_pipe; |
|---|
| 88 | + int tx_pipe; |
|---|
| 98 | 89 | }; |
|---|
| 99 | 90 | |
|---|
| 100 | 91 | /* CAN frame */ |
|---|
| .. | .. |
|---|
| 283 | 274 | |
|---|
| 284 | 275 | memcpy(buf, usb_msg, MCBA_USB_TX_BUFF_SIZE); |
|---|
| 285 | 276 | |
|---|
| 286 | | - usb_fill_bulk_urb(urb, priv->udev, |
|---|
| 287 | | - usb_sndbulkpipe(priv->udev, MCBA_USB_EP_OUT), buf, |
|---|
| 288 | | - MCBA_USB_TX_BUFF_SIZE, mcba_usb_write_bulk_callback, |
|---|
| 289 | | - ctx); |
|---|
| 277 | + usb_fill_bulk_urb(urb, priv->udev, priv->tx_pipe, buf, MCBA_USB_TX_BUFF_SIZE, |
|---|
| 278 | + mcba_usb_write_bulk_callback, ctx); |
|---|
| 290 | 279 | |
|---|
| 291 | 280 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
|---|
| 292 | 281 | usb_anchor_urb(urb, &priv->tx_submitted); |
|---|
| .. | .. |
|---|
| 379 | 368 | xmit_failed: |
|---|
| 380 | 369 | can_free_echo_skb(priv->netdev, ctx->ndx); |
|---|
| 381 | 370 | mcba_usb_free_ctx(ctx); |
|---|
| 382 | | - dev_kfree_skb(skb); |
|---|
| 383 | 371 | stats->tx_dropped++; |
|---|
| 384 | 372 | |
|---|
| 385 | 373 | return NETDEV_TX_OK; |
|---|
| .. | .. |
|---|
| 485 | 473 | priv->usb_ka_first_pass = false; |
|---|
| 486 | 474 | } |
|---|
| 487 | 475 | |
|---|
| 488 | | - if (msg->termination_state) |
|---|
| 476 | + if (msg->termination_state == MCBA_VER_TERMINATION_ON) |
|---|
| 489 | 477 | priv->can.termination = MCBA_TERMINATION_ENABLED; |
|---|
| 490 | 478 | else |
|---|
| 491 | 479 | priv->can.termination = MCBA_TERMINATION_DISABLED; |
|---|
| .. | .. |
|---|
| 622 | 610 | resubmit_urb: |
|---|
| 623 | 611 | |
|---|
| 624 | 612 | usb_fill_bulk_urb(urb, priv->udev, |
|---|
| 625 | | - usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_OUT), |
|---|
| 613 | + priv->rx_pipe, |
|---|
| 626 | 614 | urb->transfer_buffer, MCBA_USB_RX_BUFF_SIZE, |
|---|
| 627 | 615 | mcba_usb_read_bulk_callback, priv); |
|---|
| 628 | 616 | |
|---|
| .. | .. |
|---|
| 667 | 655 | urb->transfer_dma = buf_dma; |
|---|
| 668 | 656 | |
|---|
| 669 | 657 | usb_fill_bulk_urb(urb, priv->udev, |
|---|
| 670 | | - usb_rcvbulkpipe(priv->udev, MCBA_USB_EP_IN), |
|---|
| 658 | + priv->rx_pipe, |
|---|
| 671 | 659 | buf, MCBA_USB_RX_BUFF_SIZE, |
|---|
| 672 | 660 | mcba_usb_read_bulk_callback, priv); |
|---|
| 673 | 661 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
|---|
| .. | .. |
|---|
| 805 | 793 | }; |
|---|
| 806 | 794 | |
|---|
| 807 | 795 | if (term == MCBA_TERMINATION_ENABLED) |
|---|
| 808 | | - usb_msg.termination = 1; |
|---|
| 796 | + usb_msg.termination = MCBA_VER_TERMINATION_ON; |
|---|
| 809 | 797 | else |
|---|
| 810 | | - usb_msg.termination = 0; |
|---|
| 798 | + usb_msg.termination = MCBA_VER_TERMINATION_OFF; |
|---|
| 811 | 799 | |
|---|
| 812 | 800 | mcba_usb_xmit_cmd(priv, (struct mcba_usb_msg *)&usb_msg); |
|---|
| 813 | 801 | |
|---|
| .. | .. |
|---|
| 819 | 807 | { |
|---|
| 820 | 808 | struct net_device *netdev; |
|---|
| 821 | 809 | struct mcba_priv *priv; |
|---|
| 822 | | - int err = -ENOMEM; |
|---|
| 810 | + int err; |
|---|
| 823 | 811 | struct usb_device *usbdev = interface_to_usbdev(intf); |
|---|
| 812 | + struct usb_endpoint_descriptor *in, *out; |
|---|
| 813 | + |
|---|
| 814 | + err = usb_find_common_endpoints(intf->cur_altsetting, &in, &out, NULL, NULL); |
|---|
| 815 | + if (err) { |
|---|
| 816 | + dev_err(&intf->dev, "Can't find endpoints\n"); |
|---|
| 817 | + return err; |
|---|
| 818 | + } |
|---|
| 824 | 819 | |
|---|
| 825 | 820 | netdev = alloc_candev(sizeof(struct mcba_priv), MCBA_MAX_TX_URBS); |
|---|
| 826 | 821 | if (!netdev) { |
|---|
| .. | .. |
|---|
| 866 | 861 | goto cleanup_free_candev; |
|---|
| 867 | 862 | } |
|---|
| 868 | 863 | |
|---|
| 864 | + priv->rx_pipe = usb_rcvbulkpipe(priv->udev, in->bEndpointAddress); |
|---|
| 865 | + priv->tx_pipe = usb_sndbulkpipe(priv->udev, out->bEndpointAddress); |
|---|
| 866 | + |
|---|
| 869 | 867 | devm_can_led_init(netdev); |
|---|
| 870 | 868 | |
|---|
| 871 | 869 | /* Start USB dev only if we have successfully registered CAN device */ |
|---|