aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/usb
diff options
context:
space:
mode:
authorAhmed S. Darwish <ahmed.darwish@valeo.com>2015-01-26 00:29:15 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2015-01-28 07:39:37 -0500
commit96d7f10634e66b27e23854c774fbcc0a2a654e82 (patch)
treef21dfcbeb5b0211caebc34f61df1a7929713ee6e /drivers/net/can/usb
parent3b07a444ee48a8081d2ed3f0abeeabd038404ac1 (diff)
can: kvaser_usb: Consolidate and unify state change handling
Replace most of the can interface's state and error counters handling with the new can-dev can_change_state() mechanism. Suggested-by: Andri Yngvason <andri.yngvason@marel.com> 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.c113
1 files changed, 49 insertions, 64 deletions
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index f57ce556c678..ddc29549aded 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -620,39 +620,44 @@ static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
620} 620}
621 621
622static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *priv, 622static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *priv,
623 const struct kvaser_usb_error_summary *es) 623 const struct kvaser_usb_error_summary *es,
624 struct can_frame *cf)
624{ 625{
625 struct net_device_stats *stats; 626 struct net_device_stats *stats;
626 enum can_state new_state; 627 enum can_state cur_state, new_state, tx_state, rx_state;
627
628 stats = &priv->netdev->stats;
629 new_state = priv->can.state;
630 628
631 netdev_dbg(priv->netdev, "Error status: 0x%02x\n", es->status); 629 netdev_dbg(priv->netdev, "Error status: 0x%02x\n", es->status);
632 630
633 if (es->status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { 631 stats = &priv->netdev->stats;
634 priv->can.can_stats.bus_off++; 632 new_state = cur_state = priv->can.state;
633
634 if (es->status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET))
635 new_state = CAN_STATE_BUS_OFF; 635 new_state = CAN_STATE_BUS_OFF;
636 } else if (es->status & M16C_STATE_BUS_PASSIVE) { 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; 637 new_state = CAN_STATE_ERROR_PASSIVE;
640 } else if (es->status & M16C_STATE_BUS_ERROR) { 638 else if (es->status & M16C_STATE_BUS_ERROR) {
641 if ((priv->can.state < CAN_STATE_ERROR_WARNING) && 639 if ((es->txerr >= 256) || (es->rxerr >= 256))
642 ((es->txerr >= 96) || (es->rxerr >= 96))) { 640 new_state = CAN_STATE_BUS_OFF;
643 priv->can.can_stats.error_warning++; 641 else if ((es->txerr >= 128) || (es->rxerr >= 128))
642 new_state = CAN_STATE_ERROR_PASSIVE;
643 else if ((es->txerr >= 96) || (es->rxerr >= 96))
644 new_state = CAN_STATE_ERROR_WARNING; 644 new_state = CAN_STATE_ERROR_WARNING;
645 } else if ((priv->can.state > CAN_STATE_ERROR_ACTIVE) && 645 else if (cur_state > CAN_STATE_ERROR_ACTIVE)
646 ((es->txerr < 96) && (es->rxerr < 96))) {
647 new_state = CAN_STATE_ERROR_ACTIVE; 646 new_state = CAN_STATE_ERROR_ACTIVE;
648 }
649 } 647 }
650 648
651 if (!es->status) 649 if (!es->status)
652 new_state = CAN_STATE_ERROR_ACTIVE; 650 new_state = CAN_STATE_ERROR_ACTIVE;
653 651
652 if (new_state != cur_state) {
653 tx_state = (es->txerr >= es->rxerr) ? new_state : 0;
654 rx_state = (es->txerr <= es->rxerr) ? new_state : 0;
655
656 can_change_state(priv->netdev, cf, tx_state, rx_state);
657 }
658
654 if (priv->can.restart_ms && 659 if (priv->can.restart_ms &&
655 (priv->can.state >= CAN_STATE_BUS_OFF) && 660 (cur_state >= CAN_STATE_BUS_OFF) &&
656 (new_state < CAN_STATE_BUS_OFF)) { 661 (new_state < CAN_STATE_BUS_OFF)) {
657 priv->can.can_stats.restarts++; 662 priv->can.can_stats.restarts++;
658 } 663 }
@@ -664,18 +669,17 @@ static void kvaser_usb_rx_error_update_can_state(struct kvaser_usb_net_priv *pri
664 669
665 priv->bec.txerr = es->txerr; 670 priv->bec.txerr = es->txerr;
666 priv->bec.rxerr = es->rxerr; 671 priv->bec.rxerr = es->rxerr;
667 priv->can.state = new_state;
668} 672}
669 673
670static void kvaser_usb_rx_error(const struct kvaser_usb *dev, 674static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
671 const struct kvaser_msg *msg) 675 const struct kvaser_msg *msg)
672{ 676{
673 struct can_frame *cf; 677 struct can_frame *cf, tmp_cf = { .can_id = CAN_ERR_FLAG, .can_dlc = CAN_ERR_DLC };
674 struct sk_buff *skb; 678 struct sk_buff *skb;
675 struct net_device_stats *stats; 679 struct net_device_stats *stats;
676 struct kvaser_usb_net_priv *priv; 680 struct kvaser_usb_net_priv *priv;
677 struct kvaser_usb_error_summary es = { }; 681 struct kvaser_usb_error_summary es = { };
678 enum can_state old_state; 682 enum can_state old_state, new_state;
679 683
680 switch (msg->id) { 684 switch (msg->id) {
681 case CMD_CAN_ERROR_EVENT: 685 case CMD_CAN_ERROR_EVENT:
@@ -715,59 +719,40 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
715 stats = &priv->netdev->stats; 719 stats = &priv->netdev->stats;
716 720
717 /* Update all of the can interface's state and error counters before 721 /* Update all of the can interface's state and error counters before
718 * trying any skb allocation that can actually fail with -ENOMEM. 722 * trying any memory allocation that can actually fail with -ENOMEM.
723 *
724 * We send a temporary stack-allocated error can frame to
725 * can_change_state() for the very same reason.
726 *
727 * TODO: Split can_change_state() responsibility between updating the
728 * can interface's state and counters, and the setting up of can error
729 * frame ID and data to userspace. Remove stack allocation afterwards.
719 */ 730 */
720 old_state = priv->can.state; 731 old_state = priv->can.state;
721 kvaser_usb_rx_error_update_can_state(priv, &es); 732 kvaser_usb_rx_error_update_can_state(priv, &es, &tmp_cf);
733 new_state = priv->can.state;
722 734
723 skb = alloc_can_err_skb(priv->netdev, &cf); 735 skb = alloc_can_err_skb(priv->netdev, &cf);
724 if (!skb) { 736 if (!skb) {
725 stats->rx_dropped++; 737 stats->rx_dropped++;
726 return; 738 return;
727 } 739 }
728 740 memcpy(cf, &tmp_cf, sizeof(*cf));
729 if (es.status & (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) { 741
730 cf->can_id |= CAN_ERR_BUSOFF; 742 if (new_state != old_state) {
731 743 if (es.status &
732 if (!priv->can.restart_ms) 744 (M16C_STATE_BUS_OFF | M16C_STATE_BUS_RESET)) {
733 kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP); 745 if (!priv->can.restart_ms)
734 netif_carrier_off(priv->netdev); 746 kvaser_usb_simple_msg_async(priv, CMD_STOP_CHIP);
735 } else if (es.status & M16C_STATE_BUS_PASSIVE) { 747 netif_carrier_off(priv->netdev);
736 if (old_state != CAN_STATE_ERROR_PASSIVE) {
737 cf->can_id |= CAN_ERR_CRTL;
738
739 if (es.txerr || es.rxerr)
740 cf->data[1] = (es.txerr > es.rxerr)
741 ? CAN_ERR_CRTL_TX_PASSIVE
742 : CAN_ERR_CRTL_RX_PASSIVE;
743 else
744 cf->data[1] = CAN_ERR_CRTL_TX_PASSIVE |
745 CAN_ERR_CRTL_RX_PASSIVE;
746 }
747 } else if (es.status & M16C_STATE_BUS_ERROR) {
748 if ((old_state < CAN_STATE_ERROR_WARNING) &&
749 ((es.txerr >= 96) || (es.rxerr >= 96))) {
750 cf->can_id |= CAN_ERR_CRTL;
751 cf->data[1] = (es.txerr > es.rxerr)
752 ? CAN_ERR_CRTL_TX_WARNING
753 : CAN_ERR_CRTL_RX_WARNING;
754 } else if ((old_state > CAN_STATE_ERROR_ACTIVE) &&
755 ((es.txerr < 96) && (es.rxerr < 96))) {
756 cf->can_id |= CAN_ERR_PROT;
757 cf->data[2] = CAN_ERR_PROT_ACTIVE;
758 } 748 }
759 }
760
761 if (!es.status) {
762 cf->can_id |= CAN_ERR_PROT;
763 cf->data[2] = CAN_ERR_PROT_ACTIVE;
764 }
765 749
766 if (priv->can.restart_ms && 750 if (priv->can.restart_ms &&
767 (old_state >= CAN_STATE_BUS_OFF) && 751 (old_state >= CAN_STATE_BUS_OFF) &&
768 (priv->can.state < CAN_STATE_BUS_OFF)) { 752 (new_state < CAN_STATE_BUS_OFF)) {
769 cf->can_id |= CAN_ERR_RESTARTED; 753 cf->can_id |= CAN_ERR_RESTARTED;
770 netif_carrier_on(priv->netdev); 754 netif_carrier_on(priv->netdev);
755 }
771 } 756 }
772 757
773 if (es.error_factor) { 758 if (es.error_factor) {