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/config.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>
57 #define NAME "VCAN loopback interface for LLCF"
58 static __initdata const char banner[] = BANNER(NAME);
60 MODULE_DESCRIPTION(NAME);
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 /* This 'undef' makes the vcan a kind of NULL device. Since LLCF v0.6 */
79 /* the local loopback is implemented in af_can.c for all interfaces. */
84 static struct net_device *vcan_devs[NDEVICES];
86 static int vcan_open(struct net_device *dev)
88 DBG("%s: interface up\n", dev->name);
90 netif_start_queue(dev);
94 static int vcan_stop(struct net_device *dev)
96 DBG("%s: interface down\n", dev->name);
98 netif_stop_queue(dev);
104 static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
106 struct net_device_stats *stats = netdev_priv(dev);
108 stats->rx_bytes += skb->len;
110 skb->protocol = htons(ETH_P_CAN);
112 skb->ip_summed = CHECKSUM_UNNECESSARY;
114 DBG("received skbuff on interface %d\n", dev->ifindex);
123 static int vcan_tx(struct sk_buff *skb, struct net_device *dev)
125 struct net_device_stats *stats = netdev_priv(dev);
127 DBG("sending skbuff on interface %s\n", dev->name);
129 DBG_FRAME("VCAN: transmit CAN frame", (struct can_frame *)skb->data);
132 if (atomic_read(&skb->users) != 1) {
133 struct sk_buff *old_skb = skb;
134 skb = skb_clone(old_skb, GFP_ATOMIC);
135 DBG(" freeing old skbuff %p, using new skbuff %p\n",
146 stats->tx_bytes += skb->len;
151 stats->rx_bytes += skb->len;
157 static int vcan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
162 static int vcan_rebuild_header(struct sk_buff *skb)
164 DBG("called on skbuff %p\n", skb);
169 static int vcan_header(struct sk_buff *skb, struct net_device *dev,
170 unsigned short type, void *daddr, void *saddr,
173 DBG("called skbuff %p device %p\n", skb, dev);
179 static struct net_device_stats *vcan_get_stats(struct net_device *dev)
181 struct net_device_stats *stats = netdev_priv(dev);
185 static void vcan_init(struct net_device *dev)
187 DBG("dev %s\n", dev->name);
191 memset(dev->priv, 0, sizeof(struct net_device_stats));
193 dev->open = vcan_open;
194 dev->stop = vcan_stop;
195 dev->set_config = NULL;
196 dev->hard_start_xmit = vcan_tx;
197 dev->do_ioctl = vcan_ioctl;
198 dev->get_stats = vcan_get_stats;
200 dev->mtu = sizeof(struct can_frame);
201 dev->flags = IFF_LOOPBACK;
202 dev->hard_header = vcan_header;
203 dev->rebuild_header = vcan_rebuild_header;
204 dev->hard_header_cache = NULL;
205 dev->type = ARPHRD_LOOPBACK;
207 SET_MODULE_OWNER(dev);
210 static __init int vcan_init_module(void)
212 int i, ndev = 0, result;
216 for (i = 0; i < NDEVICES; i++) {
217 if (!(vcan_devs[i] = alloc_netdev(sizeof(struct net_device_stats),
218 "vcan%d", vcan_init)))
219 printk(KERN_ERR "vcan: error allocating net_device\n");
220 else if ((result = register_netdev(vcan_devs[i])) < 0) {
221 printk(KERN_ERR "vcan: error %d registering interface %s\n",
222 result, vcan_devs[i]->name);
223 free_netdev(vcan_devs[i]);
225 DBG("successfully registered interface %s\n",
230 return ndev ? 0 : -ENODEV;
233 static __exit void vcan_cleanup_module(void)
236 for (i = 0; i < NDEVICES; i++) {
237 unregister_netdev(vcan_devs[i]);
238 free_netdev(vcan_devs[i]);
242 module_init(vcan_init_module);
243 module_exit(vcan_cleanup_module);