ATTENTION: Out-of-tree CAN driver maintainers!
Hello all,
in Linux 3.9 the layout of CAN frame in the socket buffer (struct sk_buff) is extended by a struct can_skb_priv.
This structure is placed 'before' the CAN frame data, which is done by skb_reserve(). All other things like skb->data and skb->len handling is not changed.
When you are already using the GPL exported alloc_can_skb() function
-> Good! can_alloc_skb() has been adapted -> no action needed for you.
When you are NOT using can_alloc_skb() and you still do not want to use it (hint, hint) you need to
1. include the new include file include/linux/can/skb.h
2. add the sizeof(struct can_skb_priv) to the allocated skb size
3. call can_skb_reserve(skb) after successfully allocating the skb
4. assign the device interface index in the struct can_skb_priv
N.B. The can_skb_reserve() action needs to be done before adding any data to the skb with skb_put().
The changes that have been done in slcan.c can be taken as an example:
drivers/net/can/slcan.c +7 -1
@@ -52,12 +52,13 @@#include <linux/if_ether.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/can.h> +#include <linux/can/skb.h> static __initconst const char banner[] =KERN_INFO "slcan: serial line CAN interface driver\n" ;MODULE_ALIAS_LDISC (N_SLCAN );MODULE_DESCRIPTION ("serial line CAN interface" );
@@ -181,20 +182,25 @@ tmp =hex_to_bin (sl->rbuff[dlc_pos++]);if (tmp <0 )return ; cf.data[i] |= tmp; } - skb =dev_alloc_skb (sizeof (struct can_frame )); + skb =dev_alloc_skb (sizeof (struct can_frame ) + +sizeof (struct can_skb_priv ));if (!skb)return ; skb->dev = sl->dev; skb->protocol =htons (ETH_P_CAN ); skb->pkt_type =PACKET_BROADCAST ; skb->ip_summed =CHECKSUM_UNNECESSARY ; + +can_skb_reserve (skb); +can_skb_prv (skb)->ifindex = sl->dev->ifindex; +memcpy (skb_put (skb,sizeof (struct can_frame )), &cf,sizeof (struct can_frame ));netif_rx_ni (skb); sl->dev->stats.rx_packets++; sl->dev->stats.rx_bytes += cf.can_dlc;
For out-of-tree drivers you probably need to put some
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0)
+#include <linux/can/skb.h>
+#endif
arround it.
Any questions? No questions? Good :-)
Regards,
Oliver
Marc Kleine-Budde
maintainerOn 01/29/2013 09:56 PM, Oliver Hartkopp wrote:
[...]
Quoted 1 line
For out-of-tree drivers you probably need to put some
.....should be mainlined :D
Signature · 4 lines
Pengutronix e.K. | Marc Kleine-Budde | Industrial Linux Solutions | Phone: +49-231-2826-924 | Vertretung West/Dortmund | Fax: +49-5121-206917-5555 | Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |