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:
parent
f058d548e8
commit
097aec1968
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user