Skip to contentSkip to conversation

can sja1000: Only create requested error messages

RFC PATCH New Oliver Hartkopp 1 participant 1 message Dec 7, 2013

Subsystems (2)
lore
Share & tools
lore

Oliver Hartkopp

author maintainer
#0 lore raw

RFC PATCH 1/1 can sja1000: Only create requested error messages

This is a proof of concept for the SJA1000 only.

Idea: Only create error message skbuffs when there is a request from a CAN application which sets a filter for error messages.

Drawback: can.ko has to be available in the system to access the CAN filter structures. This is usually the case. Alternatively the filter structures could be made in linux/include/can/core.h instead of only providing a new function can_dev_has_error_filter() there.
Don't know if this is 'nice design' then ?!?

Regards,
Oliver

---

drivers/net/can/dev.c +7 -0
index bda1888..a5ea838 100644
@@ -25,6 +25,7 @@
 #include <linux/can.h>
 #include <linux/can/dev.h>
 #include <linux/can/skb.h>
+#include <linux/can/core.h> /* only for can_dev_error_has_filter() */
 #include <linux/can/netlink.h>
 #include <linux/can/led.h>
 #include <net/rtnetlink.h>
@@ -537,6 +538,12 @@ struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
 }
 EXPORT_SYMBOL_GPL(alloc_can_err_skb);
 
+bool can_need_error_skb(struct net_device *dev)
+{
+	return can_dev_has_error_filter(dev);
+}
+EXPORT_SYMBOL_GPL(can_need_error_skb);
+
 /*
  * Allocate and setup space for the CAN network device
  */
drivers/net/can/sja1000/sja1000.c +74 -45

162 lines not on this page · raw message

include/linux/can/core.h +1 -0
index 78c6c52..2b6e01a 100644
@@ -57,5 +57,6 @@ extern void can_rx_unregister(struct net_device *dev, canid_t can_id,
 
 extern int can_send(struct sk_buff *skb, int loop);
 extern int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
+extern bool can_dev_has_error_filter(struct net_device *dev);
 
 #endif /* CAN_CORE_H */
include/linux/can/dev.h +1 -0
index fb0ab65..5c72b20 100644
@@ -126,5 +126,6 @@ void can_free_echo_skb(struct net_device *dev, unsigned int idx);
 struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf);
 struct sk_buff *alloc_can_err_skb(struct net_device *dev,
 				  struct can_frame **cf);
+bool can_need_error_skb(struct net_device *dev);
 
 #endif /* CAN_DEV_H */
net/can/af_can.c +14 -0
index d249874..cf6d701 100644
@@ -328,6 +328,20 @@ EXPORT_SYMBOL(can_send);
  * af_can rx path
  */
 
+bool can_dev_has_error_filter(struct net_device *dev)
+{
+	if (dev) {
+		struct dev_rcv_lists *rcvlist;
+
+		rcvlist = (struct dev_rcv_lists *)dev->ml_priv;
+		if (&rcvlist->rx[RX_ERR] != NULL ||
+		    &can_rx_alldev_list.rx[RX_ERR] != NULL)
+			return true;
+	}
+	return false;
+}
+EXPORT_SYMBOL(can_dev_has_error_filter);
+
 static struct dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev)
 {
 	if (!dev)