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