If the RXACT flag is not cleared on the mscan, the slprq will eventually fail. This could be the situation when some opposite is keeping resending frames because of some communication errors. This way we will the initrq or cswai will also not be set and the mscan controller will got stuck till the bus is restarted. To avoid this we kick out setting the err value beyong a slprq failure to let the controller proceed. This is hacky since calling e.g. initrq while the mscan is really doing stuffs might disturb the bus communication. For now we however don't have other possiblities to work around the behaviour of mscan mentioned above.
Signed-off-by: Luotao Fu <[email protected]> --- drivers/net/can/mscan/mscan.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index ad09c63..b38a920 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -137,13 +137,21 @@ static int mscan_set_mode(struct net_device *dev, u8 mode) udelay(100); } if (i >= MSCAN_SET_MODE_RETRIES) - ret = -ENODEV; + /* XXX: sometimes while there are irregular activities + * on bus, like somebody keeps retransmitting. The mscan + * will fail to enter sleep mode. We proceed to init or + * wait mode in this case any how, since otherwise the + * controller will get stuck. The sleep mode is for now + * never set alone, so there should be no further + * impact caused by not catching this error */ + dev_warn(dev->dev.parent, + "SLPRQ timeout reached, " + "failed to enter sleep mode!\n"); + else + priv->can.state = CAN_STATE_SLEEPING; } - if (!ret) - priv->can.state = CAN_STATE_SLEEPING; - if (!ret && (mode & MSCAN_INITRQ) - && (canctl1 & MSCAN_INITAK) == 0) { + if ((mode & MSCAN_INITRQ) && (canctl1 & MSCAN_INITAK) == 0) { out_8(®s->canctl0, in_8(®s->canctl0) | MSCAN_INITRQ); for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) { @@ -156,7 +164,7 @@ static int mscan_set_mode(struct net_device *dev, u8 mode) if (!ret) priv->can.state = CAN_STATE_STOPPED; - if (!ret && (mode & MSCAN_CSWAI)) + if (mode & MSCAN_CSWAI) out_8(®s->canctl0, in_8(®s->canctl0) | MSCAN_CSWAI); -- 1.6.5 _______________________________________________ Socketcan-users mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-users
