aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r--drivers/net/can/dev.c76
1 files changed, 62 insertions, 14 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 2868fe842a41..c1bb29f0322b 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -245,7 +245,7 @@ static void can_flush_echo_skb(struct net_device *dev)
245 struct net_device_stats *stats = &dev->stats; 245 struct net_device_stats *stats = &dev->stats;
246 int i; 246 int i;
247 247
248 for (i = 0; i < CAN_ECHO_SKB_MAX; i++) { 248 for (i = 0; i < priv->echo_skb_max; i++) {
249 if (priv->echo_skb[i]) { 249 if (priv->echo_skb[i]) {
250 kfree_skb(priv->echo_skb[i]); 250 kfree_skb(priv->echo_skb[i]);
251 priv->echo_skb[i] = NULL; 251 priv->echo_skb[i] = NULL;
@@ -262,10 +262,13 @@ static void can_flush_echo_skb(struct net_device *dev)
262 * of the device driver. The driver must protect access to 262 * of the device driver. The driver must protect access to
263 * priv->echo_skb, if necessary. 263 * priv->echo_skb, if necessary.
264 */ 264 */
265void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx) 265void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
266 unsigned int idx)
266{ 267{
267 struct can_priv *priv = netdev_priv(dev); 268 struct can_priv *priv = netdev_priv(dev);
268 269
270 BUG_ON(idx >= priv->echo_skb_max);
271
269 /* check flag whether this packet has to be looped back */ 272 /* check flag whether this packet has to be looped back */
270 if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) { 273 if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
271 kfree_skb(skb); 274 kfree_skb(skb);
@@ -311,10 +314,12 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
311 * is handled in the device driver. The driver must protect 314 * is handled in the device driver. The driver must protect
312 * access to priv->echo_skb, if necessary. 315 * access to priv->echo_skb, if necessary.
313 */ 316 */
314void can_get_echo_skb(struct net_device *dev, int idx) 317void can_get_echo_skb(struct net_device *dev, unsigned int idx)
315{ 318{
316 struct can_priv *priv = netdev_priv(dev); 319 struct can_priv *priv = netdev_priv(dev);
317 320
321 BUG_ON(idx >= priv->echo_skb_max);
322
318 if (priv->echo_skb[idx]) { 323 if (priv->echo_skb[idx]) {
319 netif_rx(priv->echo_skb[idx]); 324 netif_rx(priv->echo_skb[idx]);
320 priv->echo_skb[idx] = NULL; 325 priv->echo_skb[idx] = NULL;
@@ -327,10 +332,12 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
327 * 332 *
328 * The function is typically called when TX failed. 333 * The function is typically called when TX failed.
329 */ 334 */
330void can_free_echo_skb(struct net_device *dev, int idx) 335void can_free_echo_skb(struct net_device *dev, unsigned int idx)
331{ 336{
332 struct can_priv *priv = netdev_priv(dev); 337 struct can_priv *priv = netdev_priv(dev);
333 338
339 BUG_ON(idx >= priv->echo_skb_max);
340
334 if (priv->echo_skb[idx]) { 341 if (priv->echo_skb[idx]) {
335 kfree_skb(priv->echo_skb[idx]); 342 kfree_skb(priv->echo_skb[idx]);
336 priv->echo_skb[idx] = NULL; 343 priv->echo_skb[idx] = NULL;
@@ -359,17 +366,12 @@ void can_restart(unsigned long data)
359 can_flush_echo_skb(dev); 366 can_flush_echo_skb(dev);
360 367
361 /* send restart message upstream */ 368 /* send restart message upstream */
362 skb = dev_alloc_skb(sizeof(struct can_frame)); 369 skb = alloc_can_err_skb(dev, &cf);
363 if (skb == NULL) { 370 if (skb == NULL) {
364 err = -ENOMEM; 371 err = -ENOMEM;
365 goto restart; 372 goto restart;
366 } 373 }
367 skb->dev = dev; 374 cf->can_id |= CAN_ERR_RESTARTED;
368 skb->protocol = htons(ETH_P_CAN);
369 cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
370 memset(cf, 0, sizeof(struct can_frame));
371 cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
372 cf->can_dlc = CAN_ERR_DLC;
373 375
374 netif_rx(skb); 376 netif_rx(skb);
375 377
@@ -442,20 +444,66 @@ static void can_setup(struct net_device *dev)
442 dev->features = NETIF_F_NO_CSUM; 444 dev->features = NETIF_F_NO_CSUM;
443} 445}
444 446
447struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
448{
449 struct sk_buff *skb;
450
451 skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
452 if (unlikely(!skb))
453 return NULL;
454
455 skb->protocol = htons(ETH_P_CAN);
456 skb->pkt_type = PACKET_BROADCAST;
457 skb->ip_summed = CHECKSUM_UNNECESSARY;
458 *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
459 memset(*cf, 0, sizeof(struct can_frame));
460
461 return skb;
462}
463EXPORT_SYMBOL_GPL(alloc_can_skb);
464
465struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
466{
467 struct sk_buff *skb;
468
469 skb = alloc_can_skb(dev, cf);
470 if (unlikely(!skb))
471 return NULL;
472
473 (*cf)->can_id = CAN_ERR_FLAG;
474 (*cf)->can_dlc = CAN_ERR_DLC;
475
476 return skb;
477}
478EXPORT_SYMBOL_GPL(alloc_can_err_skb);
479
445/* 480/*
446 * Allocate and setup space for the CAN network device 481 * Allocate and setup space for the CAN network device
447 */ 482 */
448struct net_device *alloc_candev(int sizeof_priv) 483struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
449{ 484{
450 struct net_device *dev; 485 struct net_device *dev;
451 struct can_priv *priv; 486 struct can_priv *priv;
487 int size;
452 488
453 dev = alloc_netdev(sizeof_priv, "can%d", can_setup); 489 if (echo_skb_max)
490 size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) +
491 echo_skb_max * sizeof(struct sk_buff *);
492 else
493 size = sizeof_priv;
494
495 dev = alloc_netdev(size, "can%d", can_setup);
454 if (!dev) 496 if (!dev)
455 return NULL; 497 return NULL;
456 498
457 priv = netdev_priv(dev); 499 priv = netdev_priv(dev);
458 500
501 if (echo_skb_max) {
502 priv->echo_skb_max = echo_skb_max;
503 priv->echo_skb = (void *)priv +
504 ALIGN(sizeof_priv, sizeof(struct sk_buff *));
505 }
506
459 priv->state = CAN_STATE_STOPPED; 507 priv->state = CAN_STATE_STOPPED;
460 508
461 init_timer(&priv->restart_timer); 509 init_timer(&priv->restart_timer);
@@ -647,7 +695,7 @@ nla_put_failure:
647 return -EMSGSIZE; 695 return -EMSGSIZE;
648} 696}
649 697
650static int can_newlink(struct net_device *dev, 698static int can_newlink(struct net *src_net, struct net_device *dev,
651 struct nlattr *tb[], struct nlattr *data[]) 699 struct nlattr *tb[], struct nlattr *data[])
652{ 700{
653 return -EOPNOTSUPP; 701 return -EOPNOTSUPP;