socketcan: usb bulk mode for rx (#584)

This commit is contained in:
Greg Hogan 2023-10-03 17:44:10 -07:00 committed by GitHub
parent 5778c0ae5d
commit 0ca5ad773f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 74 deletions

View File

@ -1,8 +1,7 @@
VERSION=0.0.1
obj-m+=panda.o
link:
sudo dkms add `pwd`
all: build install
build:
sudo dkms build panda/$(VERSION)
@ -10,9 +9,16 @@ build:
install:
sudo dkms install panda/$(VERSION)
all: build install
remove:
sudo dkms remove panda/$(VERSION) --all
uninstall:
sudo dkms uninstall panda/$(VERSION)
sudo dkms remove panda/$(VERSION) --all
clean: remove
link:
sudo dkms add `pwd`
unload:
sudo rmmod panda

View File

@ -7,12 +7,11 @@ This will allow the panda to work with tools such as `can-utils`
- `apt-get install dkms gcc linux-headers-$(uname -r) make sudo`
## Installation
- `make link` (only needed the first time. It will report an error on subsequent attempts to link)
- `make all`
- `make install`
- `make link` (optional, setup to build/install when kernel is updated)
## Uninstall
- `make uninstall`
- `make clean`
## Usage

View File

@ -107,8 +107,7 @@ static inline void panda_init_ctx(struct panda_inf_priv *priv)
atomic_set(&priv->free_ctx_cnt, ARRAY_SIZE(priv->tx_context));
}
static inline struct panda_usb_ctx *panda_usb_get_free_ctx(struct panda_inf_priv *priv,
struct can_frame *cf)
static inline struct panda_usb_ctx *panda_usb_get_free_ctx(struct panda_inf_priv *priv, struct can_frame *cf)
{
int i = 0;
struct panda_usb_ctx *ctx = NULL;
@ -124,7 +123,7 @@ static inline struct panda_usb_ctx *panda_usb_get_free_ctx(struct panda_inf_priv
}
}
printk("CTX num %d\n", atomic_read(&priv->free_ctx_cnt));
//printk("CTX num %d\n", atomic_read(&priv->free_ctx_cnt));
if (!atomic_read(&priv->free_ctx_cnt)) {
/* That was the last free ctx. Slow down tx path */
printk("SENDING TOO FAST\n");
@ -148,8 +147,6 @@ static inline void panda_usb_free_ctx(struct panda_usb_ctx *ctx)
netif_wake_queue(ctx->priv->netdev);
}
static void panda_urb_unlink(struct panda_inf_priv *priv)
{
usb_kill_anchored_urbs(&priv->priv_dev->rx_submitted);
@ -173,8 +170,7 @@ static void panda_usb_write_bulk_callback(struct urb *urb)
netdev = ctx->priv->netdev;
/* free up our allocated buffer */
usb_free_coherent(urb->dev, urb->transfer_buffer_length,
urb->transfer_buffer, urb->transfer_dma);
usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma);
if (!netif_device_present(netdev))
return;
@ -191,10 +187,7 @@ static void panda_usb_write_bulk_callback(struct urb *urb)
panda_usb_free_ctx(ctx);
}
static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv,
struct panda_usb_can_msg *usb_msg,
struct panda_usb_ctx *ctx)
static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv, struct panda_usb_can_msg *usb_msg, struct panda_usb_ctx *ctx)
{
struct urb *urb;
u8 *buf;
@ -205,9 +198,7 @@ static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv,
if (!urb)
return -ENOMEM;
buf = usb_alloc_coherent(priv->priv_dev->udev,
PANDA_USB_TX_BUFF_SIZE, GFP_ATOMIC,
&urb->transfer_dma);
buf = usb_alloc_coherent(priv->priv_dev->udev, PANDA_USB_TX_BUFF_SIZE, GFP_ATOMIC, &urb->transfer_dma);
if (!buf) {
err = -ENOMEM;
goto nomembuf;
@ -247,8 +238,7 @@ static netdev_tx_t panda_usb_xmit(struct panda_inf_priv *priv,
return err;
}
static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev,
struct panda_usb_can_msg *msg)
static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev, struct panda_usb_can_msg *msg)
{
struct can_frame *cf;
struct sk_buff *skb;
@ -262,7 +252,7 @@ static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev,
printk("Got something on an unused interface %d\n", bus_num);
return;
}
printk("Recv bus %d\n", bus_num);
//printk("Recv bus %d\n", bus_num);
stats = &priv_inf->netdev->stats;
//u16 sid;
@ -298,7 +288,7 @@ static void panda_usb_process_can_rx(struct panda_dev_priv *priv_dev,
netif_rx(skb);
}
static void panda_usb_read_int_callback(struct urb *urb)
static void panda_usb_read_bulk_callback(struct urb *urb)
{
struct panda_dev_priv *priv_dev = urb->context;
int retval;
@ -332,10 +322,10 @@ static void panda_usb_read_int_callback(struct urb *urb)
}
resubmit_urb:
usb_fill_int_urb(urb, priv_dev->udev,
usb_rcvintpipe(priv_dev->udev, 1),
usb_fill_bulk_urb(urb, priv_dev->udev,
usb_rcvbulkpipe(priv_dev->udev, 1),
urb->transfer_buffer, PANDA_USB_RX_BUFF_SIZE,
panda_usb_read_int_callback, priv_dev, 5);
panda_usb_read_bulk_callback, priv_dev);
retval = usb_submit_urb(urb, GFP_ATOMIC);
@ -343,9 +333,10 @@ static void panda_usb_read_int_callback(struct urb *urb)
for (inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++)
if (priv_dev->interfaces[inf_num])
netif_device_detach(priv_dev->interfaces[inf_num]->netdev);
}else if (retval)
} else if (retval) {
dev_err(priv_dev->dev, "failed resubmitting read bulk urb: %d\n", retval);
}
}
static int panda_usb_start(struct panda_dev_priv *priv_dev)
@ -358,9 +349,9 @@ static int panda_usb_start(struct panda_dev_priv *priv_dev)
for (inf_num = 0; inf_num < PANDA_NUM_CAN_INTERFACES; inf_num++)
panda_init_ctx(priv_dev->interfaces[inf_num]);
err = usb_set_interface(priv_dev->udev, 0, 1);
err = usb_set_interface(priv_dev->udev, 0, 0);
if (err) {
dev_err(priv_dev->dev, "Can not set alternate setting to 1, error: %i", err);
dev_err(priv_dev->dev, "Can not set alternate setting to 0, error: %i", err);
return err;
}
@ -370,18 +361,17 @@ static int panda_usb_start(struct panda_dev_priv *priv_dev)
return -ENOMEM;
}
buf = usb_alloc_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE,
GFP_KERNEL, &urb->transfer_dma);
buf = usb_alloc_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE, GFP_KERNEL, &urb->transfer_dma);
if (!buf) {
dev_err(priv_dev->dev, "No memory left for USB buffer\n");
usb_free_urb(urb);
return -ENOMEM;
}
usb_fill_int_urb(urb, priv_dev->udev,
usb_rcvintpipe(priv_dev->udev, 1),
usb_fill_bulk_urb(urb, priv_dev->udev,
usb_rcvbulkpipe(priv_dev->udev, 1),
buf, PANDA_USB_RX_BUFF_SIZE,
panda_usb_read_int_callback, priv_dev, 5);
panda_usb_read_bulk_callback, priv_dev);
urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
usb_anchor_urb(urb, &priv_dev->rx_submitted);
@ -389,8 +379,7 @@ static int panda_usb_start(struct panda_dev_priv *priv_dev)
err = usb_submit_urb(urb, GFP_KERNEL);
if (err) {
usb_unanchor_urb(urb);
usb_free_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE,
buf, urb->transfer_dma);
usb_free_coherent(priv_dev->udev, PANDA_USB_RX_BUFF_SIZE, buf, urb->transfer_dma);
usb_free_urb(urb);
dev_err(priv_dev->dev, "Failed in start, while submitting urb.\n");
return err;
@ -439,8 +428,7 @@ static int panda_usb_close(struct net_device *netdev)
return 0;
}
static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb,
struct net_device *netdev)
static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
struct panda_inf_priv *priv_inf = netdev_priv(netdev);
struct can_frame *cf = (struct can_frame *)skb->data;
@ -462,8 +450,7 @@ static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb,
can_put_echo_skb(skb, priv_inf->netdev, ctx->ndx, NULL);
if (cf->can_id & CAN_EFF_FLAG) {
usb_msg.rir = cpu_to_le32(((cf->can_id & 0x1FFFFFFF) << 3) |
PANDA_CAN_TRANSMIT | PANDA_CAN_EXTENDED);
usb_msg.rir = cpu_to_le32(((cf->can_id & 0x1FFFFFFF) << 3) | PANDA_CAN_TRANSMIT | PANDA_CAN_EXTENDED);
} else {
usb_msg.rir = cpu_to_le32(((cf->can_id & 0x7FF) << 21) | PANDA_CAN_TRANSMIT);
}
@ -475,7 +462,7 @@ static netdev_tx_t panda_usb_start_xmit(struct sk_buff *skb,
//if (cf->can_id & CAN_RTR_FLAG)
// usb_msg.dlc |= PANDA_DLC_RTR_MASK;
netdev_err(netdev, "Received data from socket. canid: %x; len: %d\n", cf->can_id, cf->can_dlc);
// printk("Received data from socket. bus: %x; canid: %x; len: %d\n", priv_inf->mcu_can_ifnum, cf->can_id, cf->can_dlc);
err = panda_usb_xmit(priv_inf, &usb_msg, ctx);
if (err)
@ -498,8 +485,7 @@ static const struct net_device_ops panda_netdev_ops = {
.ndo_start_xmit = panda_usb_start_xmit,
};
static int panda_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
static int panda_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct net_device *netdev;
struct panda_inf_priv *priv_inf;
@ -574,9 +560,10 @@ static int panda_usb_probe(struct usb_interface *intf,
if (priv_inf) {
unregister_candev(priv_inf->netdev);
free_candev(priv_inf->netdev);
}else
} else {
break;
}
}
kfree(priv_dev);
@ -598,9 +585,10 @@ static void panda_usb_disconnect(struct usb_interface *intf)
netdev_info(priv_inf->netdev, "device disconnected\n");
unregister_candev(priv_inf->netdev);
free_candev(priv_inf->netdev);
}else
} else {
break;
}
}
panda_urb_unlink(priv_inf);
kfree(priv_dev);