If the RXACT flag is not cleared on the mscan while we try to set
MSCAN_INIT_MODE. 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 will also not be set and the mscan
controller will got stuck till the bus is restarted. To avoid this we switch the
order of sending SLPRQ and INITRQ to make sure that the controller ignore
activities on bus while going to sleep.

Signed-off-by: Luotao Fu <[email protected]>
---
 drivers/net/can/mscan/mscan.c |   21 +++++++++++----------
 1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index ad09c63..28bad46 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -128,33 +128,34 @@ static int mscan_set_mode(struct net_device *dev, u8 mode)
                }
 
                canctl1 = in_8(&regs->canctl1);
-               if ((mode & MSCAN_SLPRQ) && (canctl1 & MSCAN_SLPAK) == 0) {
+
+               if (!ret && (mode & MSCAN_INITRQ)
+                   && (canctl1 & MSCAN_INITAK) == 0) {
                        out_8(&regs->canctl0,
-                             in_8(&regs->canctl0) | MSCAN_SLPRQ);
+                             in_8(&regs->canctl0) | MSCAN_INITRQ);
                        for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
-                               if (in_8(&regs->canctl1) & MSCAN_SLPAK)
+                               if (in_8(&regs->canctl1) & MSCAN_INITAK)
                                        break;
-                               udelay(100);
                        }
                        if (i >= MSCAN_SET_MODE_RETRIES)
                                ret = -ENODEV;
                }
                if (!ret)
-                       priv->can.state = CAN_STATE_SLEEPING;
+                       priv->can.state = CAN_STATE_STOPPED;
 
-               if (!ret && (mode & MSCAN_INITRQ)
-                   && (canctl1 & MSCAN_INITAK) == 0) {
+               if ((mode & MSCAN_SLPRQ) && (canctl1 & MSCAN_SLPAK) == 0) {
                        out_8(&regs->canctl0,
-                             in_8(&regs->canctl0) | MSCAN_INITRQ);
+                             in_8(&regs->canctl0) | MSCAN_SLPRQ);
                        for (i = 0; i < MSCAN_SET_MODE_RETRIES; i++) {
-                               if (in_8(&regs->canctl1) & MSCAN_INITAK)
+                               if (in_8(&regs->canctl1) & MSCAN_SLPAK)
                                        break;
+                               udelay(100);
                        }
                        if (i >= MSCAN_SET_MODE_RETRIES)
                                ret = -ENODEV;
                }
                if (!ret)
-                       priv->can.state = CAN_STATE_STOPPED;
+                       priv->can.state = CAN_STATE_SLEEPING;
 
                if (!ret && (mode & MSCAN_CSWAI))
                        out_8(&regs->canctl0,
-- 
1.6.5

_______________________________________________
Socketcan-users mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-users

Reply via email to