aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/dev.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/can/dev.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/can/dev.c')
-rw-r--r--drivers/net/can/dev.c85
1 files changed, 71 insertions, 14 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index 2868fe842a41..d0f8c7e67e7d 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/slab.h>
22#include <linux/netdevice.h> 23#include <linux/netdevice.h>
23#include <linux/if_arp.h> 24#include <linux/if_arp.h>
24#include <linux/can.h> 25#include <linux/can.h>
@@ -245,7 +246,7 @@ static void can_flush_echo_skb(struct net_device *dev)
245 struct net_device_stats *stats = &dev->stats; 246 struct net_device_stats *stats = &dev->stats;
246 int i; 247 int i;
247 248
248 for (i = 0; i < CAN_ECHO_SKB_MAX; i++) { 249 for (i = 0; i < priv->echo_skb_max; i++) {
249 if (priv->echo_skb[i]) { 250 if (priv->echo_skb[i]) {
250 kfree_skb(priv->echo_skb[i]); 251 kfree_skb(priv->echo_skb[i]);
251 priv->echo_skb[i] = NULL; 252 priv->echo_skb[i] = NULL;
@@ -262,10 +263,13 @@ static void can_flush_echo_skb(struct net_device *dev)
262 * of the device driver. The driver must protect access to 263 * of the device driver. The driver must protect access to
263 * priv->echo_skb, if necessary. 264 * priv->echo_skb, if necessary.
264 */ 265 */
265void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx) 266void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev,
267 unsigned int idx)
266{ 268{
267 struct can_priv *priv = netdev_priv(dev); 269 struct can_priv *priv = netdev_priv(dev);
268 270
271 BUG_ON(idx >= priv->echo_skb_max);
272
269 /* check flag whether this packet has to be looped back */ 273 /* check flag whether this packet has to be looped back */
270 if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) { 274 if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
271 kfree_skb(skb); 275 kfree_skb(skb);
@@ -311,10 +315,12 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb);
311 * is handled in the device driver. The driver must protect 315 * is handled in the device driver. The driver must protect
312 * access to priv->echo_skb, if necessary. 316 * access to priv->echo_skb, if necessary.
313 */ 317 */
314void can_get_echo_skb(struct net_device *dev, int idx) 318void can_get_echo_skb(struct net_device *dev, unsigned int idx)
315{ 319{
316 struct can_priv *priv = netdev_priv(dev); 320 struct can_priv *priv = netdev_priv(dev);
317 321
322 BUG_ON(idx >= priv->echo_skb_max);
323
318 if (priv->echo_skb[idx]) { 324 if (priv->echo_skb[idx]) {
319 netif_rx(priv->echo_skb[idx]); 325 netif_rx(priv->echo_skb[idx]);
320 priv->echo_skb[idx] = NULL; 326 priv->echo_skb[idx] = NULL;
@@ -327,10 +333,12 @@ EXPORT_SYMBOL_GPL(can_get_echo_skb);
327 * 333 *
328 * The function is typically called when TX failed. 334 * The function is typically called when TX failed.
329 */ 335 */
330void can_free_echo_skb(struct net_device *dev, int idx) 336void can_free_echo_skb(struct net_device *dev, unsigned int idx)
331{ 337{
332 struct can_priv *priv = netdev_priv(dev); 338 struct can_priv *priv = netdev_priv(dev);
333 339
340 BUG_ON(idx >= priv->echo_skb_max);
341
334 if (priv->echo_skb[idx]) { 342 if (priv->echo_skb[idx]) {
335 kfree_skb(priv->echo_skb[idx]); 343 kfree_skb(priv->echo_skb[idx]);
336 priv->echo_skb[idx] = NULL; 344 priv->echo_skb[idx] = NULL;
@@ -359,17 +367,12 @@ void can_restart(unsigned long data)
359 can_flush_echo_skb(dev); 367 can_flush_echo_skb(dev);
360 368
361 /* send restart message upstream */ 369 /* send restart message upstream */
362 skb = dev_alloc_skb(sizeof(struct can_frame)); 370 skb = alloc_can_err_skb(dev, &cf);
363 if (skb == NULL) { 371 if (skb == NULL) {
364 err = -ENOMEM; 372 err = -ENOMEM;
365 goto restart; 373 goto restart;
366 } 374 }
367 skb->dev = dev; 375 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 376
374 netif_rx(skb); 377 netif_rx(skb);
375 378
@@ -442,20 +445,66 @@ static void can_setup(struct net_device *dev)
442 dev->features = NETIF_F_NO_CSUM; 445 dev->features = NETIF_F_NO_CSUM;
443} 446}
444 447
448struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf)
449{
450 struct sk_buff *skb;
451
452 skb = netdev_alloc_skb(dev, sizeof(struct can_frame));
453 if (unlikely(!skb))
454 return NULL;
455
456 skb->protocol = htons(ETH_P_CAN);
457 skb->pkt_type = PACKET_BROADCAST;
458 skb->ip_summed = CHECKSUM_UNNECESSARY;
459 *cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
460 memset(*cf, 0, sizeof(struct can_frame));
461
462 return skb;
463}
464EXPORT_SYMBOL_GPL(alloc_can_skb);
465
466struct sk_buff *alloc_can_err_skb(struct net_device *dev, struct can_frame **cf)
467{
468 struct sk_buff *skb;
469
470 skb = alloc_can_skb(dev, cf);
471 if (unlikely(!skb))
472 return NULL;
473
474 (*cf)->can_id = CAN_ERR_FLAG;
475 (*cf)->can_dlc = CAN_ERR_DLC;
476
477 return skb;
478}
479EXPORT_SYMBOL_GPL(alloc_can_err_skb);
480
445/* 481/*
446 * Allocate and setup space for the CAN network device 482 * Allocate and setup space for the CAN network device
447 */ 483 */
448struct net_device *alloc_candev(int sizeof_priv) 484struct net_device *alloc_candev(int sizeof_priv, unsigned int echo_skb_max)
449{ 485{
450 struct net_device *dev; 486 struct net_device *dev;
451 struct can_priv *priv; 487 struct can_priv *priv;
488 int size;
452 489
453 dev = alloc_netdev(sizeof_priv, "can%d", can_setup); 490 if (echo_skb_max)
491 size = ALIGN(sizeof_priv, sizeof(struct sk_buff *)) +
492 echo_skb_max * sizeof(struct sk_buff *);
493 else
494 size = sizeof_priv;
495
496 dev = alloc_netdev(size, "can%d", can_setup);
454 if (!dev) 497 if (!dev)
455 return NULL; 498 return NULL;
456 499
457 priv = netdev_priv(dev); 500 priv = netdev_priv(dev);
458 501
502 if (echo_skb_max) {
503 priv->echo_skb_max = echo_skb_max;
504 priv->echo_skb = (void *)priv +
505 ALIGN(sizeof_priv, sizeof(struct sk_buff *));
506 }
507
459 priv->state = CAN_STATE_STOPPED; 508 priv->state = CAN_STATE_STOPPED;
460 509
461 init_timer(&priv->restart_timer); 510 init_timer(&priv->restart_timer);
@@ -526,6 +575,7 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
526 [IFLA_CAN_BITTIMING_CONST] 575 [IFLA_CAN_BITTIMING_CONST]
527 = { .len = sizeof(struct can_bittiming_const) }, 576 = { .len = sizeof(struct can_bittiming_const) },
528 [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, 577 [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
578 [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) },
529}; 579};
530 580
531static int can_changelink(struct net_device *dev, 581static int can_changelink(struct net_device *dev,
@@ -544,6 +594,8 @@ static int can_changelink(struct net_device *dev,
544 if (dev->flags & IFF_UP) 594 if (dev->flags & IFF_UP)
545 return -EBUSY; 595 return -EBUSY;
546 cm = nla_data(data[IFLA_CAN_CTRLMODE]); 596 cm = nla_data(data[IFLA_CAN_CTRLMODE]);
597 if (cm->flags & ~priv->ctrlmode_supported)
598 return -EOPNOTSUPP;
547 priv->ctrlmode &= ~cm->mask; 599 priv->ctrlmode &= ~cm->mask;
548 priv->ctrlmode |= cm->flags; 600 priv->ctrlmode |= cm->flags;
549 } 601 }
@@ -599,6 +651,8 @@ static size_t can_get_size(const struct net_device *dev)
599 size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ 651 size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
600 size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */ 652 size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */
601 size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */ 653 size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */
654 if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */
655 size += sizeof(struct can_berr_counter);
602 if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ 656 if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */
603 size += sizeof(struct can_bittiming_const); 657 size += sizeof(struct can_bittiming_const);
604 658
@@ -609,6 +663,7 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
609{ 663{
610 struct can_priv *priv = netdev_priv(dev); 664 struct can_priv *priv = netdev_priv(dev);
611 struct can_ctrlmode cm = {.flags = priv->ctrlmode}; 665 struct can_ctrlmode cm = {.flags = priv->ctrlmode};
666 struct can_berr_counter bec;
612 enum can_state state = priv->state; 667 enum can_state state = priv->state;
613 668
614 if (priv->do_get_state) 669 if (priv->do_get_state)
@@ -619,6 +674,8 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
619 NLA_PUT(skb, IFLA_CAN_BITTIMING, 674 NLA_PUT(skb, IFLA_CAN_BITTIMING,
620 sizeof(priv->bittiming), &priv->bittiming); 675 sizeof(priv->bittiming), &priv->bittiming);
621 NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock); 676 NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock);
677 if (priv->do_get_berr_counter && !priv->do_get_berr_counter(dev, &bec))
678 NLA_PUT(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec);
622 if (priv->bittiming_const) 679 if (priv->bittiming_const)
623 NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST, 680 NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST,
624 sizeof(*priv->bittiming_const), priv->bittiming_const); 681 sizeof(*priv->bittiming_const), priv->bittiming_const);
@@ -647,7 +704,7 @@ nla_put_failure:
647 return -EMSGSIZE; 704 return -EMSGSIZE;
648} 705}
649 706
650static int can_newlink(struct net_device *dev, 707static int can_newlink(struct net *src_net, struct net_device *dev,
651 struct nlattr *tb[], struct nlattr *data[]) 708 struct nlattr *tb[], struct nlattr *data[])
652{ 709{
653 return -EOPNOTSUPP; 710 return -EOPNOTSUPP;