diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2014-04-11 04:13:13 -0400 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2014-04-24 16:08:56 -0400 |
commit | 097aec19689d8f2f76fd0c1becacf32801ae94c7 (patch) | |
tree | 3d42c12965531640ec9d2a6e70e17a10d5a583dc | |
parent | f058d548e8071a1d148d6ebd94888d011c3ca71e (diff) |
can: c_can: Fix berr reporting
Reading the LEC type with
return (mode & ENABLED) && (status & LEC_MASK);
is not guaranteed to return (status & LEC_MASK) if the enabled bit in
mode is set. It's guaranteed to return 0 or !=0.
Remove the inline function and call unconditionally into the
berr_handling code and return early when the reporting is disabled.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Alexander Stein <alexander.stein@systec-electronic.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r-- | drivers/net/can/c_can/c_can.c | 16 |
1 files changed, 6 insertions, 10 deletions
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 246bcf92558c..9ef45b037a0c 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -171,6 +171,7 @@ enum c_can_lec_type { | |||
171 | LEC_BIT0_ERROR, | 171 | LEC_BIT0_ERROR, |
172 | LEC_CRC_ERROR, | 172 | LEC_CRC_ERROR, |
173 | LEC_UNUSED, | 173 | LEC_UNUSED, |
174 | LEC_MASK = LEC_UNUSED, | ||
174 | }; | 175 | }; |
175 | 176 | ||
176 | /* | 177 | /* |
@@ -897,12 +898,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) | |||
897 | return pkts; | 898 | return pkts; |
898 | } | 899 | } |
899 | 900 | ||
900 | static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) | ||
901 | { | ||
902 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && | ||
903 | (priv->current_status & LEC_UNUSED); | ||
904 | } | ||
905 | |||
906 | static int c_can_handle_state_change(struct net_device *dev, | 901 | static int c_can_handle_state_change(struct net_device *dev, |
907 | enum c_can_bus_error_types error_type) | 902 | enum c_can_bus_error_types error_type) |
908 | { | 903 | { |
@@ -998,6 +993,9 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
998 | if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) | 993 | if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) |
999 | return 0; | 994 | return 0; |
1000 | 995 | ||
996 | if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) | ||
997 | return 0; | ||
998 | |||
1001 | /* propagate the error condition to the CAN stack */ | 999 | /* propagate the error condition to the CAN stack */ |
1002 | skb = alloc_can_err_skb(dev, &cf); | 1000 | skb = alloc_can_err_skb(dev, &cf); |
1003 | if (unlikely(!skb)) | 1001 | if (unlikely(!skb)) |
@@ -1057,7 +1055,6 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
1057 | static int c_can_poll(struct napi_struct *napi, int quota) | 1055 | static int c_can_poll(struct napi_struct *napi, int quota) |
1058 | { | 1056 | { |
1059 | u16 irqstatus; | 1057 | u16 irqstatus; |
1060 | int lec_type = 0; | ||
1061 | int work_done = 0; | 1058 | int work_done = 0; |
1062 | struct net_device *dev = napi->dev; | 1059 | struct net_device *dev = napi->dev; |
1063 | struct c_can_priv *priv = netdev_priv(dev); | 1060 | struct c_can_priv *priv = netdev_priv(dev); |
@@ -1116,9 +1113,8 @@ static int c_can_poll(struct napi_struct *napi, int quota) | |||
1116 | priv->last_status = priv->current_status; | 1113 | priv->last_status = priv->current_status; |
1117 | 1114 | ||
1118 | /* handle lec errors on the bus */ | 1115 | /* handle lec errors on the bus */ |
1119 | lec_type = c_can_has_and_handle_berr(priv); | 1116 | work_done += c_can_handle_bus_err(dev, |
1120 | if (lec_type) | 1117 | priv->current_status & LEC_MASK); |
1121 | work_done += c_can_handle_bus_err(dev, lec_type); | ||
1122 | } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && | 1118 | } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && |
1123 | (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { | 1119 | (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { |
1124 | /* handle events corresponding to receive message objects */ | 1120 | /* handle events corresponding to receive message objects */ |