aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/usb
diff options
context:
space:
mode:
authorAhmed S. Darwish <ahmed.darwish@valeo.com>2015-01-26 00:27:19 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2015-01-28 07:39:37 -0500
commit3b07a444ee48a8081d2ed3f0abeeabd038404ac1 (patch)
treeea72a3af95e8f495b736d3c684d464c708673462 /drivers/net/can/usb
parentff660f75be36e6db75d45dc742a4a468c5a9c20d (diff)
can: kvaser_usb: Update interface state before exiting on OOM
Update all of the can interface's state and error counters before trying any skb allocation that can actually fail with -ENOMEM. Suggested-by: Marc Kleine-Budde <mkl@pengutronix.de> Signed-off-by: Ahmed S. Darwish <ahmed.darwish@valeo.com> Acked-by: Andri Yngvason <andri.yngvason@marel.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/usb')
-rw-r--r--drivers/net/can/usb/kvaser_usb.c181
1 files changed, 105 insertions, 76 deletions
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 7af379ca861b..f57ce556c678 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -273,6 +273,10 @@ struct kvaser_msg {
273 } u; 273 } u;
274} __packed; 274} __packed;
275 275
276struct kvaser_usb_error_summary {
277 u8 channel, status, txerr, rxerr, error_factor;
278};
279
276struct kvaser_usb_tx_urb_context { 280struct kvaser_usb_tx_urb_context {
277 struct kvaser_usb_net_priv *priv; 281 struct kvaser_usb_net_priv *priv;
278 u32 echo_index; 282 u32 echo_index;
@@ -615,6 +619,54 @@ static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
615 priv->tx_contexts[i].echo_index = MAX_TX_URBS; 619 priv->tx_contexts[i].echo_index = MAX_TX_URBS;
616} 620}
617 621
622static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
623 const struct kvaser_usb_error_summary *es)
624{
625 struct net_device_stats *stats;
626 enum can_state new_state;
627
628 stats = &priv->netdev->stats;
629 new_state = priv->can.state;
630
631 netdev_dbg(priv->netdev, "Error status: 0x%02x\n", es->status);
632
633 if (es->status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) {
634 priv->can.can_stats.bus_off++;
635 new_state = CAN_STATE_BUS_OFF;
636 } else if (es->status & M16C_STATE_BUS_PASSIVE) {
637 if (priv->can.state != CAN_STATE_ERROR_PASSIVE)
638 priv->can.can_stats.error_passive++;
639 new_state = CAN_STATE_ERROR_PASSIVE;
640 } else if (es->status & M16C_STATE_BUS_ERROR) {
641 if ((priv->can.state < CAN_STATE_ERROR_WARNING) &&
642 ((es->txerr >= 96) || (es->rxerr >= 96))) {
643 priv->can.can_stats.error_warning++;
644 new_state = CAN_STATE_ERROR_WARNING;
645 } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) &&
646 ((es->txerr < 96) && (es->rxerr < 96))) {
647 new_state = CAN_STATE_ERROR_ACTIVE;
648 }
649 }
650
651 if (!es->status)
652 new_state = CAN_STATE_ERROR_ACTIVE;
653
654 if (priv->can.restart_ms &&
655 (priv->can.state >= CAN_STATE_BUS_OFF) &&
656 (new_state < CAN_STATE_BUS_OFF)) {
657 priv->can.can_stats.restarts++;
658 }
659
660 if (es->error_factor) {
661 priv->can.can_stats.bus_error++;
662 stats->rx_errors++;
663 }
664
665 priv->bec.txerr = es->txerr;
666 priv->bec.rxerr = es->rxerr;
667 priv->can.state = new_state;
668}
669
618static void kvaser_usb_rx_error(const struct kvaser_usb *dev, 670static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
619 const struct kvaser_msg *msg) 671 const struct kvaser_msg *msg)
620{ 672{
@@ -622,30 +674,30 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
622 struct sk_buff *skb; 674 struct sk_buff *skb;
623 struct net_device_stats *stats; 675 struct net_device_stats *stats;
624 struct kvaser_usb_net_priv *priv; 676 struct kvaser_usb_net_priv *priv;
625 unsigned int new_state; 677 struct kvaser_usb_error_summary es = { };
626 u8 channel, status, txerr, rxerr, error_factor; 678 enum can_state old_state;
627 679
628 switch (msg->id) { 680 switch (msg->id) {
629 case CMD_CAN_ERROR_EVENT: 681 case CMD_CAN_ERROR_EVENT:
630 channel = msg->u.error_event.channel; 682 es.channel = msg->u.error_event.channel;
631 status = msg->u.error_event.status; 683 es.status = msg->u.error_event.status;
632 txerr = msg->u.error_event.tx_errors_count; 684 es.txerr = msg->u.error_event.tx_errors_count;
633 rxerr = msg->u.error_event.rx_errors_count; 685 es.rxerr = msg->u.error_event.rx_errors_count;
634 error_factor = msg->u.error_event.error_factor; 686 es.error_factor = msg->u.error_event.error_factor;
635 break; 687 break;
636 case CMD_LOG_MESSAGE: 688 case CMD_LOG_MESSAGE:
637 channel = msg->u.log_message.channel; 689 es.channel = msg->u.log_message.channel;
638 status = msg->u.log_message.data[0]; 690 es.status = msg->u.log_message.data[0];
639 txerr = msg->u.log_message.data[2]; 691 es.txerr = msg->u.log_message.data[2];
640 rxerr = msg->u.log_message.data[3]; 692 es.rxerr = msg->u.log_message.data[3];
641 error_factor = msg->u.log_message.data[1]; 693 es.error_factor = msg->u.log_message.data[1];
642 break; 694 break;
643 case CMD_CHIP_STATE_EVENT: 695 case CMD_CHIP_STATE_EVENT:
644 channel = msg->u.chip_state_event.channel; 696 es.channel = msg->u.chip_state_event.channel;
645 status = msg->u.chip_state_event.status; 697 es.status = msg->u.chip_state_event.status;
646 txerr = msg->u.chip_state_event.tx_errors_count; 698 es.txerr = msg->u.chip_state_event.tx_errors_count;
647 rxerr = msg->u.chip_state_event.rx_errors_count; 699 es.rxerr = msg->u.chip_state_event.rx_errors_count;
648 error_factor = 0; 700 es.error_factor = 0;
649 break; 701 break;
650 default: 702 default:
651 dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n", 703 dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n",
@@ -653,116 +705,93 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
653 return; 705 return;
654 } 706 }
655 707
656 if (channel >= dev->nchannels) { 708 if (es.channel >= dev->nchannels) {
657 dev_err(dev->udev->dev.parent, 709 dev_err(dev->udev->dev.parent,
658 "Invalid channel number (%d)\n", channel); 710 "Invalid channel number (%d)\n", es.channel);
659 return; 711 return;
660 } 712 }
661 713
662 priv = dev->nets[channel]; 714 priv = dev->nets[es.channel];
663 stats = &priv->netdev->stats; 715 stats = &priv->netdev->stats;
664 716
717 /* Update all of the can interface's state and error counters before
718 * trying any skb allocation that can actually fail with -ENOMEM.
719 */
720 old_state = priv->can.state;
721 kvaser_usb_rx_error_update_can_state(priv, &es);
722
665 skb = alloc_can_err_skb(priv->netdev, &cf); 723 skb = alloc_can_err_skb(priv->netdev, &cf);
666 if (!skb) { 724 if (!skb) {
667 stats->rx_dropped++; 725 stats->rx_dropped++;
668 return; 726 return;
669 } 727 }
670 728
671 new_state = priv->can.state; 729 if (es.status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) {
672
673 netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status);
674
675 if (status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) {
676 cf->can_id |= CAN_ERR_BUSOFF; 730 cf->can_id |= CAN_ERR_BUSOFF;
677 731
678 priv->can.can_stats.bus_off++;
679 if (!priv->can.restart_ms) 732 if (!priv->can.restart_ms)
680 kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP); 733 kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP);
681
682 netif_carrier_off(priv->netdev); 734 netif_carrier_off(priv->netdev);
683 735 } else if (es.status & M16C_STATE_BUS_PASSIVE) {
684 new_state = CAN_STATE_BUS_OFF; 736 if (old_state != CAN_STATE_ERROR_PASSIVE) {
685 } else if (status & M16C_STATE_BUS_PASSIVE) {
686 if (priv->can.state != CAN_STATE_ERROR_PASSIVE) {
687 cf->can_id |= CAN_ERR_CRTL; 737 cf->can_id |= CAN_ERR_CRTL;
688 738
689 if (txerr || rxerr) 739 if (es.txerr || es.rxerr)
690 cf->data[1] = (txerr > rxerr) 740 cf->data[1] = (es.txerr > es.rxerr)
691 ? CAN_ERR_CRTL_TX_PASSIVE 741 ? CAN_ERR_CRTL_TX_PASSIVE
692 : CAN_ERR_CRTL_RX_PASSIVE; 742 : CAN_ERR_CRTL_RX_PASSIVE;
693 else 743 else
694 cf->data[1] = CAN_ERR_CRTL_TX_PASSIVE | 744 cf->data[1] = CAN_ERR_CRTL_TX_PASSIVE |
695 CAN_ERR_CRTL_RX_PASSIVE; 745 CAN_ERR_CRTL_RX_PASSIVE;
696
697 priv->can.can_stats.error_passive++;
698 } 746 }
699 747 } else if (es.status & M16C_STATE_BUS_ERROR) {
700 new_state = CAN_STATE_ERROR_PASSIVE; 748 if ((old_state < CAN_STATE_ERROR_WARNING) &&
701 } else if (status & M16C_STATE_BUS_ERROR) { 749 ((es.txerr >= 96) || (es.rxerr >= 96))) {
702 if ((priv->can.state < CAN_STATE_ERROR_WARNING) &&
703 ((txerr >= 96) || (rxerr >= 96))) {
704 cf->can_id |= CAN_ERR_CRTL; 750 cf->can_id |= CAN_ERR_CRTL;
705 cf->data[1] = (txerr > rxerr) 751 cf->data[1] = (es.txerr > es.rxerr)
706 ? CAN_ERR_CRTL_TX_WARNING 752 ? CAN_ERR_CRTL_TX_WARNING
707 : CAN_ERR_CRTL_RX_WARNING; 753 : CAN_ERR_CRTL_RX_WARNING;
708 754 } else if ((old_state > CAN_STATE_ERROR_ACTIVE) &&
709 priv->can.can_stats.error_warning++; 755 ((es.txerr < 96) && (es.rxerr < 96))) {
710 new_state = CAN_STATE_ERROR_WARNING;
711 } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) &&
712 ((txerr < 96) && (rxerr < 96))) {
713 cf->can_id |= CAN_ERR_PROT; 756 cf->can_id |= CAN_ERR_PROT;
714 cf->data[2] = CAN_ERR_PROT_ACTIVE; 757 cf->data[2] = CAN_ERR_PROT_ACTIVE;
715
716 new_state = CAN_STATE_ERROR_ACTIVE;
717 } 758 }
718 } 759 }
719 760
720 if (!status) { 761 if (!es.status) {
721 cf->can_id |= CAN_ERR_PROT; 762 cf->can_id |= CAN_ERR_PROT;
722 cf->data[2] = CAN_ERR_PROT_ACTIVE; 763 cf->data[2] = CAN_ERR_PROT_ACTIVE;
723
724 new_state = CAN_STATE_ERROR_ACTIVE;
725 } 764 }
726 765
727 if (priv->can.restart_ms && 766 if (priv->can.restart_ms &&
728 (priv->can.state >= CAN_STATE_BUS_OFF) && 767 (old_state >= CAN_STATE_BUS_OFF) &&
729 (new_state < CAN_STATE_BUS_OFF)) { 768 (priv->can.state < CAN_STATE_BUS_OFF)) {
730 cf->can_id |= CAN_ERR_RESTARTED; 769 cf->can_id |= CAN_ERR_RESTARTED;
731 netif_carrier_on(priv->netdev); 770 netif_carrier_on(priv->netdev);
732
733 priv->can.can_stats.restarts++;
734 } 771 }
735 772
736 if (error_factor) { 773 if (es.error_factor) {
737 priv->can.can_stats.bus_error++;
738 stats->rx_errors++;
739
740 cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT; 774 cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
741 775
742 if (error_factor & M16C_EF_ACKE) 776 if (es.error_factor & M16C_EF_ACKE)
743 cf->data[3] |= (CAN_ERR_PROT_LOC_ACK); 777 cf->data[3] |= (CAN_ERR_PROT_LOC_ACK);
744 if (error_factor & M16C_EF_CRCE) 778 if (es.error_factor & M16C_EF_CRCE)
745 cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ | 779 cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
746 CAN_ERR_PROT_LOC_CRC_DEL); 780 CAN_ERR_PROT_LOC_CRC_DEL);
747 if (error_factor & M16C_EF_FORME) 781 if (es.error_factor & M16C_EF_FORME)
748 cf->data[2] |= CAN_ERR_PROT_FORM; 782 cf->data[2] |= CAN_ERR_PROT_FORM;
749 if (error_factor & M16C_EF_STFE) 783 if (es.error_factor & M16C_EF_STFE)
750 cf->data[2] |= CAN_ERR_PROT_STUFF; 784 cf->data[2] |= CAN_ERR_PROT_STUFF;
751 if (error_factor & M16C_EF_BITE0) 785 if (es.error_factor & M16C_EF_BITE0)
752 cf->data[2] |= CAN_ERR_PROT_BIT0; 786 cf->data[2] |= CAN_ERR_PROT_BIT0;
753 if (error_factor & M16C_EF_BITE1) 787 if (es.error_factor & M16C_EF_BITE1)
754 cf->data[2] |= CAN_ERR_PROT_BIT1; 788 cf->data[2] |= CAN_ERR_PROT_BIT1;
755 if (error_factor & M16C_EF_TRE) 789 if (es.error_factor & M16C_EF_TRE)
756 cf->data[2] |= CAN_ERR_PROT_TX; 790 cf->data[2] |= CAN_ERR_PROT_TX;
757 } 791 }
758 792
759 cf->data[6] = txerr; 793 cf->data[6] = es.txerr;
760 cf->data[7] = rxerr; 794 cf->data[7] = es.rxerr;
761
762 priv->bec.txerr = txerr;
763 priv->bec.rxerr = rxerr;
764
765 priv->can.state = new_state;
766 795
767 stats->rx_packets++; 796 stats->rx_packets++;
768 stats->rx_bytes += cf->can_dlc; 797 stats->rx_bytes += cf->can_dlc;
@@ -786,6 +815,9 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
786 } 815 }
787 816
788 if (msg->u.rx_can.flag & MSG_FLAG_OVERRUN) { 817 if (msg->u.rx_can.flag & MSG_FLAG_OVERRUN) {
818 stats->rx_over_errors++;
819 stats->rx_errors++;
820
789 skb = alloc_can_err_skb(priv->netdev, &cf); 821 skb = alloc_can_err_skb(priv->netdev, &cf);
790 if (!skb) { 822 if (!skb) {
791 stats->rx_dropped++; 823 stats->rx_dropped++;
@@ -795,9 +827,6 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
795 cf->can_id |= CAN_ERR_CRTL; 827 cf->can_id |= CAN_ERR_CRTL;
796 cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; 828 cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
797 829
798 stats->rx_over_errors++;
799 stats->rx_errors++;
800
801 stats->rx_packets++; 830 stats->rx_packets++;
802 stats->rx_bytes += cf->can_dlc; 831 stats->rx_bytes += cf->can_dlc;
803 netif_rx(skb); 832 netif_rx(skb);