aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can
diff options
context:
space:
mode:
authorOliver Hartkopp <socketcan@hartkopp.net>2012-06-13 14:56:59 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2012-06-19 15:40:20 -0400
commit41052ef6dfe90e7639103a010f49d13dadc55a28 (patch)
treef0e4a8230dd94ea76f1a7255c10fea6aa708a6f2 /drivers/net/can
parent1e0625facab2e871472472b7df87d8fbe6caf75a (diff)
vcan: add CAN FD support
- move the length calculation from dlc to real length (using canfd_frame) - allow to switch the driver between CAN and CAN FD (change of MTU) Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r--drivers/net/can/vcan.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index ea2d94285936..4f93c0be0053 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -70,13 +70,12 @@ MODULE_PARM_DESC(echo, "Echo sent frames (for testing). Default: 0 (Off)");
70 70
71static void vcan_rx(struct sk_buff *skb, struct net_device *dev) 71static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
72{ 72{
73 struct can_frame *cf = (struct can_frame *)skb->data; 73 struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
74 struct net_device_stats *stats = &dev->stats; 74 struct net_device_stats *stats = &dev->stats;
75 75
76 stats->rx_packets++; 76 stats->rx_packets++;
77 stats->rx_bytes += cf->can_dlc; 77 stats->rx_bytes += cfd->len;
78 78
79 skb->protocol = htons(ETH_P_CAN);
80 skb->pkt_type = PACKET_BROADCAST; 79 skb->pkt_type = PACKET_BROADCAST;
81 skb->dev = dev; 80 skb->dev = dev;
82 skb->ip_summed = CHECKSUM_UNNECESSARY; 81 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -86,7 +85,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
86 85
87static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) 86static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
88{ 87{
89 struct can_frame *cf = (struct can_frame *)skb->data; 88 struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
90 struct net_device_stats *stats = &dev->stats; 89 struct net_device_stats *stats = &dev->stats;
91 int loop; 90 int loop;
92 91
@@ -94,7 +93,7 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
94 return NETDEV_TX_OK; 93 return NETDEV_TX_OK;
95 94
96 stats->tx_packets++; 95 stats->tx_packets++;
97 stats->tx_bytes += cf->can_dlc; 96 stats->tx_bytes += cfd->len;
98 97
99 /* set flag whether this packet has to be looped back */ 98 /* set flag whether this packet has to be looped back */
100 loop = skb->pkt_type == PACKET_LOOPBACK; 99 loop = skb->pkt_type == PACKET_LOOPBACK;
@@ -108,7 +107,7 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
108 * CAN core already did the echo for us 107 * CAN core already did the echo for us
109 */ 108 */
110 stats->rx_packets++; 109 stats->rx_packets++;
111 stats->rx_bytes += cf->can_dlc; 110 stats->rx_bytes += cfd->len;
112 } 111 }
113 kfree_skb(skb); 112 kfree_skb(skb);
114 return NETDEV_TX_OK; 113 return NETDEV_TX_OK;
@@ -133,14 +132,28 @@ static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
133 return NETDEV_TX_OK; 132 return NETDEV_TX_OK;
134} 133}
135 134
135static int vcan_change_mtu(struct net_device *dev, int new_mtu)
136{
137 /* Do not allow changing the MTU while running */
138 if (dev->flags & IFF_UP)
139 return -EBUSY;
140
141 if (new_mtu != CAN_MTU && new_mtu != CANFD_MTU)
142 return -EINVAL;
143
144 dev->mtu = new_mtu;
145 return 0;
146}
147
136static const struct net_device_ops vcan_netdev_ops = { 148static const struct net_device_ops vcan_netdev_ops = {
137 .ndo_start_xmit = vcan_tx, 149 .ndo_start_xmit = vcan_tx,
150 .ndo_change_mtu = vcan_change_mtu,
138}; 151};
139 152
140static void vcan_setup(struct net_device *dev) 153static void vcan_setup(struct net_device *dev)
141{ 154{
142 dev->type = ARPHRD_CAN; 155 dev->type = ARPHRD_CAN;
143 dev->mtu = sizeof(struct can_frame); 156 dev->mtu = CAN_MTU;
144 dev->hard_header_len = 0; 157 dev->hard_header_len = 0;
145 dev->addr_len = 0; 158 dev->addr_len = 0;
146 dev->tx_queue_len = 0; 159 dev->tx_queue_len = 0;