1149032Ssimon/* vcan.c - Virtual CAN interface
2148871Scperciva *
3148871Scperciva * Copyright (c) 2002-2017 Volkswagen Group Electronic Research
4148871Scperciva * All rights reserved.
5148871Scperciva *
6148871Scperciva * Redistribution and use in source and binary forms, with or without
7148871Scperciva * modification, are permitted provided that the following conditions
8148871Scperciva * are met:
9148871Scperciva * 1. Redistributions of source code must retain the above copyright
10148871Scperciva *    notice, this list of conditions and the following disclaimer.
11148871Scperciva * 2. Redistributions in binary form must reproduce the above copyright
12148871Scperciva *    notice, this list of conditions and the following disclaimer in the
13148871Scperciva *    documentation and/or other materials provided with the distribution.
14148871Scperciva * 3. Neither the name of Volkswagen nor the names of its contributors
15148871Scperciva *    may be used to endorse or promote products derived from this software
16148871Scperciva *    without specific prior written permission.
17148871Scperciva *
18148871Scperciva * Alternatively, provided that this notice is retained in full, this
19148871Scperciva * software may be distributed under the terms of the GNU General
20148871Scperciva * Public License ("GPL") version 2, in which case the provisions of the
21148871Scperciva * GPL apply INSTEAD OF those given above.
22148871Scperciva *
23148871Scperciva * The provided data structures and external interfaces from this code
24148871Scperciva * are not restricted to be used by modules with a GPL compatible license.
25148871Scperciva *
26148871Scperciva * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27148871Scperciva * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28296638Sjgh * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29148871Scperciva * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30148871Scperciva * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31148871Scperciva * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32148871Scperciva * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33148871Scperciva * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34148871Scperciva * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35148871Scperciva * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36148871Scperciva * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
37148871Scperciva * DAMAGE.
38148871Scperciva *
39148871Scperciva */
40158523Scperciva
41148871Scperciva#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
42148871Scperciva
43149027Scperciva#include <linux/ethtool.h>
44148871Scperciva#include <linux/module.h>
45148871Scperciva#include <linux/init.h>
46148871Scperciva#include <linux/netdevice.h>
47148871Scperciva#include <linux/if_arp.h>
48148871Scperciva#include <linux/if_ether.h>
49149032Ssimon#include <linux/can.h>
50149032Ssimon#include <linux/can/can-ml.h>
51149032Ssimon#include <linux/can/dev.h>
52148871Scperciva#include <linux/can/skb.h>
53174961Scperciva#include <linux/slab.h>
54174961Scperciva#include <net/rtnetlink.h>
55174961Scperciva
56174961Scperciva#define DRV_NAME "vcan"
57174961Scperciva
58148871ScpercivaMODULE_DESCRIPTION("virtual CAN interface");
59148871ScpercivaMODULE_LICENSE("Dual BSD/GPL");
60148871ScpercivaMODULE_AUTHOR("Urs Thuermann <urs.thuermann@volkswagen.de>");
61148871ScpercivaMODULE_ALIAS_RTNL_LINK(DRV_NAME);
62162806Sru
63148871Scperciva/* CAN test feature:
64148871Scperciva * Enable the echo on driver level for testing the CAN core echo modes.
65148871Scperciva * See Documentation/networking/can.rst for details.
66148871Scperciva */
67148871Scperciva
68183041Sdangerstatic bool echo; /* echo testing. Default: 0 (Off) */
69148871Scpercivamodule_param(echo, bool, 0444);
70148871ScpercivaMODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
71148871Scperciva
72148871Scpercivastatic void vcan_rx(struct sk_buff *skb, struct net_device *dev)
73148871Scperciva{
74148871Scperciva	struct net_device_stats *stats = &dev->stats;
75148871Scperciva
76148871Scperciva	stats->rx_packets++;
77148871Scperciva	stats->rx_bytes += can_skb_get_data_len(skb);
78148871Scperciva
79158523Scperciva	skb->pkt_type  = PACKET_BROADCAST;
80162806Sru	skb->dev       = dev;
81158523Scperciva	skb->ip_summed = CHECKSUM_UNNECESSARY;
82158523Scperciva
83158523Scperciva	netif_rx(skb);
84158523Scperciva}
85158523Scperciva
86158523Scpercivastatic netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
87148871Scperciva{
88148871Scperciva	struct net_device_stats *stats = &dev->stats;
89148871Scperciva	unsigned int len;
90148871Scperciva	int loop;
91149032Ssimon
92148871Scperciva	if (can_dropped_invalid_skb(dev, skb))
93148871Scperciva		return NETDEV_TX_OK;
94148871Scperciva
95148871Scperciva	len = can_skb_get_data_len(skb);
96211397Sjoel	stats->tx_packets++;
97148871Scperciva	stats->tx_bytes += len;
98148871Scperciva
99148871Scperciva	/* set flag whether this packet has to be looped back */
100148871Scperciva	loop = skb->pkt_type == PACKET_LOOPBACK;
101148871Scperciva
102148871Scperciva	skb_tx_timestamp(skb);
103162806Sru
104148871Scperciva	if (!echo) {
105162806Sru		/* no echo handling available inside this driver */
106148871Scperciva		if (loop) {
107149032Ssimon			/* only count the packets here, because the
108148871Scperciva			 * CAN core already did the echo for us
109239078Seadler			 */
110239078Seadler			stats->rx_packets++;
111239078Seadler			stats->rx_bytes += len;
112239078Seadler		}
113239078Seadler		consume_skb(skb);
114239078Seadler		return NETDEV_TX_OK;
115148871Scperciva	}
116148871Scperciva
117148871Scperciva	/* perform standard echo handling for CAN network interfaces */
118148871Scperciva
119148871Scperciva	if (loop) {
120148871Scperciva		skb = can_create_echo_skb(skb);
121148871Scperciva		if (!skb)
122148871Scperciva			return NETDEV_TX_OK;
123148871Scperciva
124148871Scperciva		/* receive with packet counting */
125148871Scperciva		vcan_rx(skb, dev);
126148871Scperciva	} else {
127148871Scperciva		/* no looped packets => no counting */
128148871Scperciva		consume_skb(skb);
129154443Scperciva	}
130154443Scperciva	return NETDEV_TX_OK;
131148871Scperciva}
132148871Scperciva
133148871Scpercivastatic int vcan_change_mtu(struct net_device *dev, int new_mtu)
134148871Scperciva{
135148871Scperciva	/* Do not allow changing the MTU while running */
136148871Scperciva	if (dev->flags & IFF_UP)
137148871Scperciva		return -EBUSY;
138148871Scperciva
139148871Scperciva	if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU &&
140148871Scperciva	    !can_is_canxl_dev_mtu(new_mtu))
141148871Scperciva		return -EINVAL;
142148871Scperciva
143148871Scperciva	dev->mtu = new_mtu;
144148871Scperciva	return 0;
145148871Scperciva}
146148871Scperciva
147148871Scpercivastatic const struct net_device_ops vcan_netdev_ops = {
148148871Scperciva	.ndo_start_xmit = vcan_tx,
149148871Scperciva	.ndo_change_mtu = vcan_change_mtu,
150148871Scperciva};
151148871Scperciva
152148871Scpercivastatic const struct ethtool_ops vcan_ethtool_ops = {
153148871Scperciva	.get_ts_info = ethtool_op_get_ts_info,
154148871Scperciva};
155148871Scperciva
156148871Scpercivastatic void vcan_setup(struct net_device *dev)
157148871Scperciva{
158148871Scperciva	dev->type		= ARPHRD_CAN;
159148871Scperciva	dev->mtu		= CANFD_MTU;
160148871Scperciva	dev->hard_header_len	= 0;
161148871Scperciva	dev->addr_len		= 0;
162148871Scperciva	dev->tx_queue_len	= 0;
163148871Scperciva	dev->flags		= IFF_NOARP;
164148871Scperciva	can_set_ml_priv(dev, netdev_priv(dev));
165148871Scperciva
166148871Scperciva	/* set flags according to driver capabilities */
167148871Scperciva	if (echo)
168148871Scperciva		dev->flags |= IFF_ECHO;
169148871Scperciva
170148871Scperciva	dev->netdev_ops		= &vcan_netdev_ops;
171148871Scperciva	dev->ethtool_ops	= &vcan_ethtool_ops;
172250604Sjoel	dev->needs_free_netdev	= true;
173250604Sjoel}
174250604Sjoel
175148871Scpercivastatic struct rtnl_link_ops vcan_link_ops __read_mostly = {
176148871Scperciva	.kind = DRV_NAME,
177148871Scperciva	.priv_size = sizeof(struct can_ml_priv),
178148871Scperciva	.setup = vcan_setup,
179148871Scperciva};
180148871Scperciva
181241024Sissyl0static __init int vcan_init_module(void)
182241024Sissyl0{
183241024Sissyl0	pr_info("Virtual CAN interface driver\n");
184241024Sissyl0
185241024Sissyl0	if (echo)
186241024Sissyl0		pr_info("enabled echo on driver level.\n");
187241024Sissyl0
188241026Sissyl0	return rtnl_link_register(&vcan_link_ops);
189241024Sissyl0}
190241024Sissyl0
191241024Sissyl0static __exit void vcan_cleanup_module(void)
192241024Sissyl0{
193241024Sissyl0	rtnl_link_unregister(&vcan_link_ops);
194241024Sissyl0}
195241024Sissyl0
196241024Sissyl0module_init(vcan_init_module);
197241024Sissyl0module_exit(vcan_cleanup_module);
198148871Scperciva