summaryrefslogtreecommitdiff
path: root/drivers/net/can/at91_can.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/can/at91_can.c')
-rw-r--r--drivers/net/can/at91_can.c71
1 files changed, 38 insertions, 33 deletions
diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
index 2071011ee812..5b611657b41f 100644
--- a/drivers/net/can/at91_can.c
+++ b/drivers/net/can/at91_can.c
@@ -753,59 +753,64 @@ static int at91_poll_rx(struct net_device *dev, int quota)
static int at91_poll_err(struct net_device *dev, int quota, u32 reg_sr)
{
+ struct net_device_stats *stats = &dev->stats;
struct at91_priv *priv = netdev_priv(dev);
struct sk_buff *skb;
- struct can_frame *cf;
+ struct can_frame *cf = NULL;
- if (quota == 0)
- return 0;
+ priv->can.can_stats.bus_error++;
- skb = alloc_can_err_skb(dev, &cf);
- if (unlikely(!skb))
- return 0;
+ if (quota) {
+ skb = alloc_can_err_skb(dev, &cf);
+ if (cf)
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ }
- /* CRC error */
if (reg_sr & AT91_IRQ_CERR) {
- netdev_dbg(dev, "CERR irq\n");
- dev->stats.rx_errors++;
- priv->can.can_stats.bus_error++;
- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ netdev_dbg(dev, "CRC error\n");
+
+ stats->rx_errors++;
+ if (cf)
+ cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ;
}
- /* Stuffing Error */
if (reg_sr & AT91_IRQ_SERR) {
- netdev_dbg(dev, "SERR irq\n");
- dev->stats.rx_errors++;
- priv->can.can_stats.bus_error++;
- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
- cf->data[2] |= CAN_ERR_PROT_STUFF;
+ netdev_dbg(dev, "Stuff error\n");
+
+ stats->rx_errors++;
+ if (cf)
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
}
- /* Acknowledgement Error */
if (reg_sr & AT91_IRQ_AERR) {
- netdev_dbg(dev, "AERR irq\n");
- dev->stats.tx_errors++;
- cf->can_id |= CAN_ERR_ACK;
+ netdev_dbg(dev, "NACK error\n");
+
+ stats->tx_errors++;
+ if (cf) {
+ cf->can_id |= CAN_ERR_ACK;
+ cf->data[2] |= CAN_ERR_PROT_TX;
+ }
}
- /* Form error */
if (reg_sr & AT91_IRQ_FERR) {
- netdev_dbg(dev, "FERR irq\n");
- dev->stats.rx_errors++;
- priv->can.can_stats.bus_error++;
- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
- cf->data[2] |= CAN_ERR_PROT_FORM;
+ netdev_dbg(dev, "Format error\n");
+
+ stats->rx_errors++;
+ if (cf)
+ cf->data[2] |= CAN_ERR_PROT_FORM;
}
- /* Bit Error */
if (reg_sr & AT91_IRQ_BERR) {
- netdev_dbg(dev, "BERR irq\n");
- dev->stats.tx_errors++;
- priv->can.can_stats.bus_error++;
- cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
- cf->data[2] |= CAN_ERR_PROT_BIT;
+ netdev_dbg(dev, "Bit error\n");
+
+ stats->tx_errors++;
+ if (cf)
+ cf->data[2] |= CAN_ERR_PROT_TX | CAN_ERR_PROT_BIT;
}
+ if (!cf)
+ return 0;
+
netif_receive_skb(skb);
return 1;