projects
/
elmcan.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
08ace76
)
Convert RX path to NAPI via can_rx_offload_*
author
norly
<ny-git@enpas.org>
Sat, 5 Feb 2022 03:50:56 +0000
(
04:50
+0100)
committer
norly
<ny-git@enpas.org>
Sat, 5 Feb 2022 04:07:09 +0000
(
05:07
+0100)
module/elmcan.c
patch
|
blob
|
history
diff --git
a/module/elmcan.c
b/module/elmcan.c
index e07ecbc6b00879252c78b6e291bf6a05c4765215..cd57cad9db3a86c24ed02b98b782a03579a40c69 100644
(file)
--- a/
module/elmcan.c
+++ b/
module/elmcan.c
@@
-30,12
+30,14
@@
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/tty.h>
#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/tty.h>
+#include <linux/version.h>
#include <linux/workqueue.h>
#include <linux/can.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/led.h>
#include <linux/workqueue.h>
#include <linux/can.h>
#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/led.h>
+#include <linux/can/rx-offload.h>
MODULE_ALIAS_LDISC(N_ELMCAN);
MODULE_DESCRIPTION("ELM327 based CAN interface");
MODULE_ALIAS_LDISC(N_ELMCAN);
MODULE_DESCRIPTION("ELM327 based CAN interface");
@@
-56,6
+58,8
@@
MODULE_PARM_DESC(accept_flaky_uart, "Don't bail at the first invalid character.
#define N_ELMCAN 29
#endif
#define N_ELMCAN 29
#endif
+#define ELM327_NAPI_WEIGHT 4
+
#define ELM327_SIZE_RXBUF 256
#define ELM327_SIZE_TXBUF 32
#define ELM327_SIZE_RXBUF 256
#define ELM327_SIZE_TXBUF 32
@@
-85,6
+89,8
@@
struct elmcan {
/* This must be the first member when using alloc_candev() */
struct can_priv can;
/* This must be the first member when using alloc_candev() */
struct can_priv can;
+ struct can_rx_offload offload;
+
/* TTY and netdev devices that we're bridging */
struct tty_struct *tty;
struct net_device *dev;
/* TTY and netdev devices that we're bridging */
struct tty_struct *tty;
struct net_device *dev;
@@
-313,11
+319,16
@@
static void elm327_feed_frame_to_netdev(struct elmcan *elm,
memcpy(cf, frame, sizeof(struct can_frame));
memcpy(cf, frame, sizeof(struct can_frame));
- elm->dev->stats.rx_packets++;
- elm->dev->stats.rx_bytes += frame->can_dlc;
- netif_rx_ni(skb);
+ /* Queue for NAPI pickup.
+ * rx-offload will update stats and LEDs for us.
+ */
+ if (can_rx_offload_queue_tail(&elm->offload, skb))
+ elm->dev->stats.rx_fifo_errors++;
- can_led_event(elm->dev, CAN_LED_EVENT_RX);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,15,0)
+ /* Wake NAPI */
+ can_rx_offload_irq_finish(&elm->offload);
+#endif
}
/***********************************************************************
}
/***********************************************************************
@@
-762,6
+773,16
@@
static void elm327_parse_rxbuf(struct elmcan *elm)
* (takes elm->lock) *
***********************************************************************/
* (takes elm->lock) *
***********************************************************************/
+/* Dummy needed to use can_rx_offload */
+static struct sk_buff *elmcan_mailbox_read(struct can_rx_offload *offload,
+ unsigned int n, u32 *timestamp,
+ bool drop)
+{
+ WARN_ON(1); /* This function is a dummy, so don't call it! */
+
+ return ERR_PTR(-ENOBUFS);
+}
+
static int elmcan_netdev_open(struct net_device *dev)
{
struct elmcan *elm = netdev_priv(dev);
static int elmcan_netdev_open(struct net_device *dev)
{
struct elmcan *elm = netdev_priv(dev);
@@
-789,6
+810,15
@@
static int elmcan_netdev_open(struct net_device *dev)
elm327_init(elm);
spin_unlock_bh(&elm->lock);
elm327_init(elm);
spin_unlock_bh(&elm->lock);
+ elm->offload.mailbox_read = elmcan_mailbox_read;
+ err = can_rx_offload_add_fifo(dev, &elm->offload, ELM327_NAPI_WEIGHT);
+ if (err) {
+ close_candev(dev);
+ return err;
+ }
+
+ can_rx_offload_enable(&elm->offload);
+
can_led_event(dev, CAN_LED_EVENT_OPEN);
elm->can.state = CAN_STATE_ERROR_ACTIVE;
netif_start_queue(dev);
can_led_event(dev, CAN_LED_EVENT_OPEN);
elm->can.state = CAN_STATE_ERROR_ACTIVE;
netif_start_queue(dev);
@@
-800,6
+830,8
@@
static int elmcan_netdev_close(struct net_device *dev)
{
struct elmcan *elm = netdev_priv(dev);
{
struct elmcan *elm = netdev_priv(dev);
+ netif_stop_queue(dev);
+
spin_lock_bh(&elm->lock);
if (elm->tty) {
/* Interrupt whatever we're doing right now */
spin_lock_bh(&elm->lock);
if (elm->tty) {
/* Interrupt whatever we're doing right now */
@@
-817,8
+849,9
@@
static int elmcan_netdev_close(struct net_device *dev)
spin_unlock_bh(&elm->lock);
}
spin_unlock_bh(&elm->lock);
}
+ can_rx_offload_disable(&elm->offload);
elm->can.state = CAN_STATE_STOPPED;
elm->can.state = CAN_STATE_STOPPED;
-
netif_stop_queue(dev
);
+
can_rx_offload_del(&elm->offload
);
close_candev(dev);
can_led_event(dev, CAN_LED_EVENT_STOP);
close_candev(dev);
can_led_event(dev, CAN_LED_EVENT_STOP);