aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/can/dev.c6
-rw-r--r--drivers/net/can/sja1000/sja1000.c25
-rw-r--r--include/linux/can/dev.h2
-rw-r--r--include/linux/can/netlink.h18
4 files changed, 44 insertions, 7 deletions
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
index f08f1202ff00..904aa369f80e 100644
--- a/drivers/net/can/dev.c
+++ b/drivers/net/can/dev.c
@@ -574,6 +574,7 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
574 [IFLA_CAN_BITTIMING_CONST] 574 [IFLA_CAN_BITTIMING_CONST]
575 = { .len = sizeof(struct can_bittiming_const) }, 575 = { .len = sizeof(struct can_bittiming_const) },
576 [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) }, 576 [IFLA_CAN_CLOCK] = { .len = sizeof(struct can_clock) },
577 [IFLA_CAN_BERR_COUNTER] = { .len = sizeof(struct can_berr_counter) },
577}; 578};
578 579
579static int can_changelink(struct net_device *dev, 580static int can_changelink(struct net_device *dev,
@@ -649,6 +650,8 @@ static size_t can_get_size(const struct net_device *dev)
649 size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */ 650 size += nla_total_size(sizeof(u32)); /* IFLA_CAN_RESTART_MS */
650 size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */ 651 size += sizeof(struct can_bittiming); /* IFLA_CAN_BITTIMING */
651 size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */ 652 size += sizeof(struct can_clock); /* IFLA_CAN_CLOCK */
653 if (priv->do_get_berr_counter) /* IFLA_CAN_BERR_COUNTER */
654 size += sizeof(struct can_berr_counter);
652 if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */ 655 if (priv->bittiming_const) /* IFLA_CAN_BITTIMING_CONST */
653 size += sizeof(struct can_bittiming_const); 656 size += sizeof(struct can_bittiming_const);
654 657
@@ -659,6 +662,7 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
659{ 662{
660 struct can_priv *priv = netdev_priv(dev); 663 struct can_priv *priv = netdev_priv(dev);
661 struct can_ctrlmode cm = {.flags = priv->ctrlmode}; 664 struct can_ctrlmode cm = {.flags = priv->ctrlmode};
665 struct can_berr_counter bec;
662 enum can_state state = priv->state; 666 enum can_state state = priv->state;
663 667
664 if (priv->do_get_state) 668 if (priv->do_get_state)
@@ -669,6 +673,8 @@ static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
669 NLA_PUT(skb, IFLA_CAN_BITTIMING, 673 NLA_PUT(skb, IFLA_CAN_BITTIMING,
670 sizeof(priv->bittiming), &priv->bittiming); 674 sizeof(priv->bittiming), &priv->bittiming);
671 NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock); 675 NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock);
676 if (priv->do_get_berr_counter && !priv->do_get_berr_counter(dev, &bec))
677 NLA_PUT(skb, IFLA_CAN_BERR_COUNTER, sizeof(bec), &bec);
672 if (priv->bittiming_const) 678 if (priv->bittiming_const)
673 NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST, 679 NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST,
674 sizeof(*priv->bittiming_const), priv->bittiming_const); 680 sizeof(*priv->bittiming_const), priv->bittiming_const);
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index ace103a44833..145b1a731a53 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -130,8 +130,12 @@ static void set_normal_mode(struct net_device *dev)
130 /* check reset bit */ 130 /* check reset bit */
131 if ((status & MOD_RM) == 0) { 131 if ((status & MOD_RM) == 0) {
132 priv->can.state = CAN_STATE_ERROR_ACTIVE; 132 priv->can.state = CAN_STATE_ERROR_ACTIVE;
133 /* enable all interrupts */ 133 /* enable interrupts */
134 priv->write_reg(priv, REG_IER, IRQ_ALL); 134 if (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)
135 priv->write_reg(priv, REG_IER, IRQ_ALL);
136 else
137 priv->write_reg(priv, REG_IER,
138 IRQ_ALL & ~IRQ_BEI);
135 return; 139 return;
136 } 140 }
137 141
@@ -203,6 +207,17 @@ static int sja1000_set_bittiming(struct net_device *dev)
203 return 0; 207 return 0;
204} 208}
205 209
210static int sja1000_get_berr_counter(const struct net_device *dev,
211 struct can_berr_counter *bec)
212{
213 struct sja1000_priv *priv = netdev_priv(dev);
214
215 bec->txerr = priv->read_reg(priv, REG_TXERR);
216 bec->rxerr = priv->read_reg(priv, REG_RXERR);
217
218 return 0;
219}
220
206/* 221/*
207 * initialize SJA1000 chip: 222 * initialize SJA1000 chip:
208 * - reset chip 223 * - reset chip
@@ -437,6 +452,8 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
437 CAN_ERR_CRTL_TX_PASSIVE : 452 CAN_ERR_CRTL_TX_PASSIVE :
438 CAN_ERR_CRTL_RX_PASSIVE; 453 CAN_ERR_CRTL_RX_PASSIVE;
439 } 454 }
455 cf->data[6] = txerr;
456 cf->data[7] = rxerr;
440 } 457 }
441 458
442 priv->can.state = state; 459 priv->can.state = state;
@@ -567,7 +584,9 @@ struct net_device *alloc_sja1000dev(int sizeof_priv)
567 priv->can.bittiming_const = &sja1000_bittiming_const; 584 priv->can.bittiming_const = &sja1000_bittiming_const;
568 priv->can.do_set_bittiming = sja1000_set_bittiming; 585 priv->can.do_set_bittiming = sja1000_set_bittiming;
569 priv->can.do_set_mode = sja1000_set_mode; 586 priv->can.do_set_mode = sja1000_set_mode;
570 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; 587 priv->can.do_get_berr_counter = sja1000_get_berr_counter;
588 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
589 CAN_CTRLMODE_BERR_REPORTING;
571 590
572 if (sizeof_priv) 591 if (sizeof_priv)
573 priv->priv = (void *)priv + sizeof(struct sja1000_priv); 592 priv->priv = (void *)priv + sizeof(struct sja1000_priv);
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
index c8c660a79f90..6e5a7f00223d 100644
--- a/include/linux/can/dev.h
+++ b/include/linux/can/dev.h
@@ -47,6 +47,8 @@ struct can_priv {
47 int (*do_set_mode)(struct net_device *dev, enum can_mode mode); 47 int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
48 int (*do_get_state)(const struct net_device *dev, 48 int (*do_get_state)(const struct net_device *dev,
49 enum can_state *state); 49 enum can_state *state);
50 int (*do_get_berr_counter)(const struct net_device *dev,
51 struct can_berr_counter *bec);
50 52
51 unsigned int echo_skb_max; 53 unsigned int echo_skb_max;
52 struct sk_buff **echo_skb; 54 struct sk_buff **echo_skb;
diff --git a/include/linux/can/netlink.h b/include/linux/can/netlink.h
index c818335fbb13..3250de935e1a 100644
--- a/include/linux/can/netlink.h
+++ b/include/linux/can/netlink.h
@@ -70,6 +70,14 @@ enum can_state {
70}; 70};
71 71
72/* 72/*
73 * CAN bus error counters
74 */
75struct can_berr_counter {
76 __u16 txerr;
77 __u16 rxerr;
78};
79
80/*
73 * CAN controller mode 81 * CAN controller mode
74 */ 82 */
75struct can_ctrlmode { 83struct can_ctrlmode {
@@ -77,10 +85,11 @@ struct can_ctrlmode {
77 __u32 flags; 85 __u32 flags;
78}; 86};
79 87
80#define CAN_CTRLMODE_LOOPBACK 0x1 /* Loopback mode */ 88#define CAN_CTRLMODE_LOOPBACK 0x01 /* Loopback mode */
81#define CAN_CTRLMODE_LISTENONLY 0x2 /* Listen-only mode */ 89#define CAN_CTRLMODE_LISTENONLY 0x02 /* Listen-only mode */
82#define CAN_CTRLMODE_3_SAMPLES 0x4 /* Triple sampling mode */ 90#define CAN_CTRLMODE_3_SAMPLES 0x04 /* Triple sampling mode */
83#define CAN_CTRLMODE_ONE_SHOT 0x8 /* One-Shot mode */ 91#define CAN_CTRLMODE_ONE_SHOT 0x08 /* One-Shot mode */
92#define CAN_CTRLMODE_BERR_REPORTING 0x10 /* Bus-error reporting */
84 93
85/* 94/*
86 * CAN device statistics 95 * CAN device statistics
@@ -106,6 +115,7 @@ enum {
106 IFLA_CAN_CTRLMODE, 115 IFLA_CAN_CTRLMODE,
107 IFLA_CAN_RESTART_MS, 116 IFLA_CAN_RESTART_MS,
108 IFLA_CAN_RESTART, 117 IFLA_CAN_RESTART,
118 IFLA_CAN_BERR_COUNTER,
109 __IFLA_CAN_MAX 119 __IFLA_CAN_MAX
110}; 120};
111 121