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>
51 #include <linux/can.h>
52 #include <linux/can/version.h>
56 static __initdata const char banner[] = KERN_INFO "CAN: virtual CAN interface " VERSION "\n";
58 MODULE_DESCRIPTION("virtual CAN interface");
59 MODULE_LICENSE("Dual BSD/GPL");
60 MODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
62 #ifdef CONFIG_CAN_DEBUG_DEVICES
64 module_param(debug, int, S_IRUGO);
65 #define DBG(args...) (debug & 1 ? \
66 (printk(KERN_DEBUG "VCAN %s: ", __func__), \
68 #define DBG_FRAME(args...) (debug & 2 ? can_debug_cframe(args) : 0)
69 #define DBG_SKB(skb) (debug & 4 ? can_debug_skb(skb) : 0)
72 #define DBG_FRAME(args...)
76 /* Indicate if this VCAN driver should do a real loopback, or if this */
77 /* should be done in af_can.c */
82 static struct net_device *vcan_devs[NDEVICES];
84 static int vcan_open(struct net_device *dev)
86 DBG("%s: interface up\n", dev->name);
88 netif_start_queue(dev);
92 static int vcan_stop(struct net_device *dev)
94 DBG("%s: interface down\n", dev->name);
96 netif_stop_queue(dev);
102 static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
104 struct net_device_stats *stats = netdev_priv(dev);
106 stats->rx_bytes += skb->len;
108 skb->protocol = htons(ETH_P_CAN);
110 skb->ip_summed = CHECKSUM_UNNECESSARY;
112 DBG("received skbuff on interface %d\n", dev->ifindex);
120 static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
122 struct net_device_stats *stats = netdev_priv(dev);
124 DBG("sending skbuff on interface %s\n", dev->name);
126 DBG_FRAME("VCAN: transmit CAN frame", (struct can_frame *)skb->data);
129 stats->tx_bytes += skb->len;
132 if (*(struct sock **)skb->cb) { /* loopback required */
133 if (atomic_read(&skb->users) != 1) {
134 struct sk_buff *old_skb = skb;
135 skb = skb_clone(old_skb, GFP_ATOMIC);
136 DBG(" freeing old skbuff %p, using new skbuff %p\n",
145 vcan_rx(skb, dev); /* with packet counting */
147 /* no looped packets => no counting */
151 /* only count, when the CAN-core made a loopback */
152 if (*(struct sock **)skb->cb) {
154 stats->rx_bytes += skb->len;
161 static int vcan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
166 static int vcan_rebuild_header(struct sk_buff *skb)
168 DBG("skbuff %p\n", skb);
173 static int vcan_header(struct sk_buff *skb, struct net_device *dev,
174 unsigned short type, void *daddr, void *saddr,
177 DBG("skbuff %p, device %p\n", skb, dev);
183 static struct net_device_stats *vcan_get_stats(struct net_device *dev)
185 struct net_device_stats *stats = netdev_priv(dev);
189 static void vcan_init(struct net_device *dev)
191 DBG("dev %s\n", dev->name);
195 memset(dev->priv, 0, sizeof(struct net_device_stats));
197 dev->type = ARPHRD_CAN;
198 dev->mtu = sizeof(struct can_frame);
200 dev->flags = IFF_LOOPBACK;
203 dev->open = vcan_open;
204 dev->stop = vcan_stop;
205 dev->set_config = NULL;
206 dev->hard_start_xmit = vcan_tx;
207 dev->do_ioctl = vcan_ioctl;
208 dev->get_stats = vcan_get_stats;
209 dev->hard_header = vcan_header;
210 dev->rebuild_header = vcan_rebuild_header;
211 dev->hard_header_cache = NULL;
213 SET_MODULE_OWNER(dev);
216 static __init int vcan_init_module(void)
218 int i, ndev = 0, result;
222 for (i = 0; i < NDEVICES; i++) {
223 if (!(vcan_devs[i] = alloc_netdev(sizeof(struct net_device_stats),
224 "vcan%d", vcan_init)))
225 printk(KERN_ERR "vcan: error allocating net_device\n");
226 else if ((result = register_netdev(vcan_devs[i])) < 0) {
227 printk(KERN_ERR "vcan: error %d registering interface %s\n",
228 result, vcan_devs[i]->name);
229 free_netdev(vcan_devs[i]);
231 DBG("successfully registered interface %s\n",
236 return ndev ? 0 : -ENODEV;
239 static __exit void vcan_cleanup_module(void)
242 for (i = 0; i < NDEVICES; i++) {
243 unregister_netdev(vcan_devs[i]);
244 free_netdev(vcan_devs[i]);
248 module_init(vcan_init_module);
249 module_exit(vcan_cleanup_module);