2 * vcan.c - Virtual CAN interface
4 * Copyright (c) 2002-2005 Volkswagen Group Electronic Research
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, the following disclaimer and
12 * the referenced file 'COPYING'.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of Volkswagen nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * Alternatively, provided that this notice is retained in full, this
21 * software may be distributed under the terms of the GNU General
22 * Public License ("GPL") version 2 as distributed in the 'COPYING'
23 * file from the main directory of the linux kernel source.
25 * The provided data structures and external interfaces from this code
26 * are not restricted to be used by modules with a GPL compatible license.
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
41 * Send feedback to <socketcan-users@lists.berlios.de>
45 #include <linux/autoconf.h>
46 #include <linux/module.h>
47 #include <linux/init.h>
48 #include <linux/netdevice.h>
49 #include <linux/if_arp.h>
50 #include <linux/if_ether.h>
52 #include <linux/can.h>
53 #include <linux/can/version.h>
57 static __initdata const char banner[] = KERN_INFO "CAN: virtual CAN "
58 "interface " VERSION "\n";
60 MODULE_DESCRIPTION("virtual CAN interface");
61 MODULE_LICENSE("Dual BSD/GPL");
62 MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
64 #ifdef CONFIG_CAN_DEBUG_DEVICES
66 module_param(debug, int, S_IRUGO);
67 #define DBG(args...) (debug & 1 ? \
68 (printk(KERN_DEBUG "VCAN %s: ", __func__), \
70 #define DBG_FRAME(args...) (debug & 2 ? can_debug_cframe(args) : 0)
71 #define DBG_SKB(skb) (debug & 4 ? can_debug_skb(skb) : 0)
74 #define DBG_FRAME(args...)
78 /* Indicate if this VCAN driver should do a real loopback, or if this */
79 /* should be done in af_can.c */
82 #define STATSIZE sizeof(struct net_device_stats)
84 static int numdev = 4; /* default number of virtual CAN interfaces */
85 module_param(numdev, int, S_IRUGO);
86 MODULE_PARM_DESC(numdev, "Number of virtual CAN devices");
88 static struct net_device **vcan_devs; /* root pointer to netdevice structs */
90 static int vcan_open(struct net_device *dev)
92 DBG("%s: interface up\n", dev->name);
94 netif_start_queue(dev);
98 static int vcan_stop(struct net_device *dev)
100 DBG("%s: interface down\n", dev->name);
102 netif_stop_queue(dev);
108 static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
110 struct net_device_stats *stats = netdev_priv(dev);
112 stats->rx_bytes += skb->len;
114 skb->protocol = htons(ETH_P_CAN);
116 skb->ip_summed = CHECKSUM_UNNECESSARY;
118 DBG("received skbuff on interface %d\n", dev->ifindex);
126 static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
128 struct net_device_stats *stats = netdev_priv(dev);
131 DBG("sending skbuff on interface %s\n", dev->name);
133 DBG_FRAME("VCAN: transmit CAN frame", (struct can_frame *)skb->data);
136 stats->tx_bytes += skb->len;
138 loop = *(struct sock **)skb->cb != NULL; /* loopback required */
142 if (atomic_read(&skb->users) != 1) {
143 struct sk_buff *old_skb = skb;
144 skb = skb_clone(old_skb, GFP_ATOMIC);
145 DBG(" freeing old skbuff %p, using new skbuff %p\n",
154 vcan_rx(skb, dev); /* with packet counting */
156 /* no looped packets => no counting */
160 /* only count, when the CAN core did a loopback */
163 stats->rx_bytes += skb->len;
170 static int vcan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
175 static int vcan_rebuild_header(struct sk_buff *skb)
177 DBG("skbuff %p\n", skb);
182 static int vcan_header(struct sk_buff *skb, struct net_device *dev,
183 unsigned short type, void *daddr, void *saddr,
186 DBG("skbuff %p, device %p\n", skb, dev);
192 static struct net_device_stats *vcan_get_stats(struct net_device *dev)
194 struct net_device_stats *stats = netdev_priv(dev);
198 static void vcan_init(struct net_device *dev)
200 DBG("dev %s\n", dev->name);
204 memset(dev->priv, 0, STATSIZE);
206 dev->type = ARPHRD_CAN;
207 dev->mtu = sizeof(struct can_frame);
208 dev->flags = IFF_NOARP;
210 dev->flags |= IFF_LOOPBACK;
213 dev->open = vcan_open;
214 dev->stop = vcan_stop;
215 dev->set_config = NULL;
216 dev->hard_start_xmit = vcan_tx;
217 dev->do_ioctl = vcan_ioctl;
218 dev->get_stats = vcan_get_stats;
219 dev->hard_header = vcan_header;
220 dev->rebuild_header = vcan_rebuild_header;
221 dev->hard_header_cache = NULL;
223 SET_MODULE_OWNER(dev);
226 static __init int vcan_init_module(void)
228 int i, ndev = 0, result = 0;
233 numdev = 1; /* register at least one interface */
235 printk(KERN_INFO "vcan: registering %d virtual CAN interfaces.\n",
238 vcan_devs = kmalloc(numdev * sizeof(struct net_device *), GFP_KERNEL);
240 printk(KERN_ERR "vcan: Can't allocate vcan devices array!\n");
244 /* Clear the pointer array */
245 memset(vcan_devs, 0, numdev * sizeof(struct net_device *));
247 for (i = 0; i < numdev; i++) {
248 if (!(vcan_devs[i] = alloc_netdev(STATSIZE, "vcan%d",
250 printk(KERN_ERR "vcan: error allocating net_device\n");
253 } else if ((result = register_netdev(vcan_devs[i])) < 0) {
254 printk(KERN_ERR "vcan: error %d registering "
256 result, vcan_devs[i]->name);
257 free_netdev(vcan_devs[i]);
261 DBG("successfully registered interface %s\n",
271 for (i = 0; i < numdev; i++) {
273 unregister_netdev(vcan_devs[i]);
274 free_netdev(vcan_devs[i]);
283 static __exit void vcan_cleanup_module(void)
290 for (i = 0; i < numdev; i++) {
292 unregister_netdev(vcan_devs[i]);
293 free_netdev(vcan_devs[i]);
300 module_init(vcan_init_module);
301 module_exit(vcan_cleanup_module);