2
0
mirror of https://github.com/edk2-porting/linux-next.git synced 2025-01-15 00:54:03 +08:00

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>
This commit is contained in:
Thomas Gleixner 2014-04-11 08:13:13 +00:00 committed by Marc Kleine-Budde
parent f058d548e8
commit 097aec1968

View File

@ -171,6 +171,7 @@ enum c_can_lec_type {
LEC_BIT0_ERROR, LEC_BIT0_ERROR,
LEC_CRC_ERROR, LEC_CRC_ERROR,
LEC_UNUSED, LEC_UNUSED,
LEC_MASK = LEC_UNUSED,
}; };
/* /*
@ -897,12 +898,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota)
return pkts; return pkts;
} }
static inline int c_can_has_and_handle_berr(struct c_can_priv *priv)
{
return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) &&
(priv->current_status & LEC_UNUSED);
}
static int c_can_handle_state_change(struct net_device *dev, static int c_can_handle_state_change(struct net_device *dev,
enum c_can_bus_error_types error_type) enum c_can_bus_error_types error_type)
{ {
@ -998,6 +993,9 @@ static int c_can_handle_bus_err(struct net_device *dev,
if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR)
return 0; return 0;
if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING))
return 0;
/* propagate the error condition to the CAN stack */ /* propagate the error condition to the CAN stack */
skb = alloc_can_err_skb(dev, &cf); skb = alloc_can_err_skb(dev, &cf);
if (unlikely(!skb)) if (unlikely(!skb))
@ -1057,7 +1055,6 @@ static int c_can_handle_bus_err(struct net_device *dev,
static int c_can_poll(struct napi_struct *napi, int quota) static int c_can_poll(struct napi_struct *napi, int quota)
{ {
u16 irqstatus; u16 irqstatus;
int lec_type = 0;
int work_done = 0; int work_done = 0;
struct net_device *dev = napi->dev; struct net_device *dev = napi->dev;
struct c_can_priv *priv = netdev_priv(dev); struct c_can_priv *priv = netdev_priv(dev);
@ -1116,9 +1113,8 @@ static int c_can_poll(struct napi_struct *napi, int quota)
priv->last_status = priv->current_status; priv->last_status = priv->current_status;
/* handle lec errors on the bus */ /* handle lec errors on the bus */
lec_type = c_can_has_and_handle_berr(priv); work_done += c_can_handle_bus_err(dev,
if (lec_type) priv->current_status & LEC_MASK);
work_done += c_can_handle_bus_err(dev, lec_type);
} else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) &&
(irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) {
/* handle events corresponding to receive message objects */ /* handle events corresponding to receive message objects */