* This driver started as a derivative of linux/drivers/net/can/slcan.c
* and my thanks go to the original authors for their inspiration, even
* after almost none of their code is left.
+ *
+ * elmcan.c Author : Max Staudt <max-linux@enpas.org>
+ * slcan.c Author : Oliver Hartkopp <socketcan@hartkopp.net>
+ * slip.c Authors : Laurence Culhane <loz@holmes.demon.co.uk>
+ * Fred N. van Kempen <waltje@uwalt.nl.mugnet.org>
*/
-#define pr_fmt(fmt) "[elmcan] " fmt
+#define pr_fmt(fmt) "elmcan: " fmt
#include <linux/init.h>
#include <linux/module.h>
#include <linux/can/led.h>
#include <linux/can/rx-offload.h>
-MODULE_ALIAS_LDISC(N_DEVELOPMENT);
-MODULE_DESCRIPTION("ELM327 based CAN interface");
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Max Staudt <max-linux@enpas.org>");
-
/* Line discipline ID number.
* N_DEVELOPMENT will likely be defined from Linux 5.18 onwards:
* https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git/commit/?h=tty-next&id=c2faf737abfb10f88f2d2612d573e9edc3c42c37
struct can_frame *frame;
struct sk_buff *skb;
+ elm->hw_failure = true;
+
+ elm->can.can_stats.bus_off++;
+ netif_stop_queue(elm->dev);
+ elm->can.state = CAN_STATE_BUS_OFF;
+ can_bus_off(elm->dev);
+
+ netdev_err(elm->dev, "ELM327 misbehaved. Blocking further communication.\n");
+
skb = alloc_can_err_skb(elm->dev, &frame);
if (!skb)
return;
- frame->data[5] = 'R';
- frame->data[6] = 'I';
- frame->data[7] = 'P';
-
+ frame->can_id |= CAN_ERR_BUSOFF;
elm327_feed_frame_to_netdev(elm, skb);
-
- netdev_err(elm->dev, "ELM327 misbehaved. Blocking further communication.\n");
-
- elm->hw_failure = true;
- can_bus_off(elm->dev);
}
/* Compare a buffer to a fixed string */
module_init(elmcan_init);
module_exit(elmcan_exit);
+
+MODULE_ALIAS_LDISC(N_DEVELOPMENT);
+MODULE_DESCRIPTION("ELM327 based CAN interface");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Max Staudt <max-linux@enpas.org>");