Hi, I'm playing with 2.6.31 + mscan driver on a mpc5200B board the last days, have slightly backported the mscan driver to meet the can frame work in 2.6.31. Now I ran into a quite funny situation:
The board is connected to a host, which has an IXXAT PCI can card (2.6.26 and an unknown SocketCAN version, which is more or less recent, since it provides sysfs entries). The host is set to a baudrate of 250kbit, while the target comes up with 125kbit. As soon as the host and target are up and running, I send a frame with cansend from the host. After that both sides go into bus passive, which is the expected behaviour. However the board seems not to be able to get out there any more. Turning off the interface -> change the baudrate to 250K -> turning on the interface went through without errors. However the board seems to stuck and neither sending nor receiving will work any more. I instrumented the mscan_set_mode() call with the attached patch and noticed that the RXACT is never cleared in this case any more and the initrq will eventually never reach. a small screenshot to make it a little more clear: ## Usually changing bitrate should read like this @target: /sbin/ip link set can1 type can bitrate 250000 changing bit rate to can1 [ 105.854706] ctl0: 0x10 [ 105.857231] ctl0: 0x2 ## sleep mode request is set [ 105.863075] ctl0: 0x3 ## init mode request is set [ 105.888505] mpc52xx_can f0000980.can: setting BTR0=0x0a BTR1=0x18 ## after the mscan got stuck resetting bitrate reads like this: @target: /sbin/ip link set can1 type can bitrate 250000 changing bit rate to can1 [ 303.130686] ctl0: 0x50 [ 303.160088] ctl0: 0x52 [ 303.162512] ctl0: 0x52 [ 303.206860] mpc52xx_can f0000980.can: setting BTR0=0x0a BTR1=0x18 Seems RXACT is never cleared on the mscan side. Setting to init_mode will then eventually fail and the controller stucks in sleep mode. I can solve the problem by pulling the target from can bus and so cause an bus-off to restart the stuff or I restart the can controller on the host side. However it still feels like a bug. Two questions: 1. why is the failed initrq uncatched? I doubled checked with an mscan driver from an reeeeal old socketcan patch(-r466) + 2.6.23, it will fail on spinning wait for slpak and quit there with an -ENODEV. Why is it not happening any more? 2. Any hint for a possible fix the problem described above or is it more a conceptional question / hardware problem with mscan? Cheers Luotao Fu -- Pengutronix e.K. | Dipl.-Ing. Luotao Fu | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c
index ad09c63..269e4b4 100644
--- a/drivers/net/can/mscan/mscan.c
+++ b/drivers/net/can/mscan/mscan.c
@@ -128,6 +128,9 @@ static int mscan_set_mode(struct net_device *dev, u8 mode)
}
canctl1 = in_8(®s->canctl1);
+
+ printk("ctl0: 0x%x\n", in_8(®s->canctl0));
+
if ((mode & MSCAN_SLPRQ) && (canctl1 & MSCAN_SLPAK) == 0) {
out_8(®s->canctl0,
in_8(®s->canctl0) | MSCAN_SLPRQ);
@@ -142,6 +145,8 @@ static int mscan_set_mode(struct net_device *dev, u8 mode)
if (!ret)
priv->can.state = CAN_STATE_SLEEPING;
+ printk("ctl0: 0x%x\n", in_8(®s->canctl0));
+
if (!ret && (mode & MSCAN_INITRQ)
&& (canctl1 & MSCAN_INITAK) == 0) {
out_8(®s->canctl0,
@@ -156,6 +161,8 @@ static int mscan_set_mode(struct net_device *dev, u8 mode)
if (!ret)
priv->can.state = CAN_STATE_STOPPED;
+ printk("ctl0: 0x%x\n", in_8(®s->canctl0));
+
if (!ret && (mode & MSCAN_CSWAI))
out_8(®s->canctl0,
in_8(®s->canctl0) | MSCAN_CSWAI);
signature.asc
Description: Digital signature
_______________________________________________ Socketcan-users mailing list [email protected] https://lists.berlios.de/mailman/listinfo/socketcan-users
