miniPCI problem on Intel Xscale platform

Live forum: http://rt2x00.serialmonkey.com/viewtopic.php?t=4829

olovh

04-06-2008 12:14:29

Hi all,

I am trying to get a WLAN miniPCI card to work on a custom built computer. The card is based on Rt2561 chipset and the platform is an Intel X-scale, ixp425 using big endian. Kernel version is 2.6.20.3 and I have downloaded RT61 as CVS snapshot 2008-05-27. Firmware is 2561s version 0.8. I also have other cards using the same chip set, but the problem still persist using other cards.

The card is discovered on the PCI bus and communication seems to go well. Problem is that most of the time the system hangs with "BBP read R0 fail" when issuing "ifconfig wlan0 up".
Any ideas what might go wrong here? Greatful for any input.

Cheers,
Olov

Vern

05-06-2008 01:13:22

... and the platform is an Intel X-scale, ixp425 using big endian.[/quote2912nc8z] Really? I didn't know that had a big endian capability. Could you build with debug enabled and attach a gzipped copy of /var/log/debug to a posting here?

Thanks,

olovh

05-06-2008 11:06:33

The processor is actually bi-endian but configured to use big endian. As the system does not use conventional logging facilities all debug logs end up in /var/log/messages. Anyhow here is a new log with debug enabled for RT61 and with dmesg as well.

The thing is, most often the unit hangs when enabling wlan0, but some times it does not. Attached is also a log after enabling the interface when it didn't hang.

Common for the two logs is that we get "BBP read RX fail" where X is a number. Any ideas what this is and what might cause this? IRQ assignment problem, broken hardware, software drivers..?

thanks,
Olov

Vern

05-06-2008 19:52:51

Hi olovh,

Thanks for the logs. The attached patch endianizes 32 bit register accesses. It probably won't solve all the problems with big-endianess, but it should move things along a bit.

Could you apply it and attach a gzipped copy of the resulting (debug) log here?

Thanks,

olovh

09-06-2008 15:43:27


Thanks for the logs. [/quote3ls6zv1k] Thanks for the patch. )

I have tried the patch but it seems as it didn't solve any of the problems. With the patch it does not even want to load the firmware file. (
See the attached log which has been produced right upon "insmod rt61 debug=31". Note that the "running hotplug xxxxx" lines are lines added by me in the hotplug script to see that hotplug is running as assumed.

I have seen in changelog that there have been patches related to big endian, are there any known problems with big endian support? Maybe you have other ideas?

Many thanks,
Olov

Vern

09-06-2008 20:39:03

Hi olavh,

All the legacy drivers have code for big endian environments. As far as I can tell, none of it actually works.

Looking at your log, obviously something that I expected to zig has zagged. Before I gallop off in all directions at once, I've made a slight change to the initial patch - attached as endian2.patch.gz - that adds debug logic to print out exactly the content of the status register that makes the driver issue the message[code3rg5tlub]rt61: NICLoadFirmware: MCU is not ready[/code3rg5tlub]Hopefully that will help me to clarify my understanding of what's going on.

If you could try it and attach the resulting log to a posting here, that would be great.

Thanks,

olovh

10-06-2008 09:45:35

Hi,

here is the debug output from insmod. Seems as the status register is 0x0, hope this helps.

Cheers,
Olov

Vern

11-06-2008 18:37:56

Hi olovh,

Looks like I'm having trouble figuring out the right level of indirection to use. This version - endian3.patch.gz - changes the RTMP_IO_READ32 macro to endianize after storing the value rather than before.

Could you try it and post the log here? Also, since you're obviously a programmer, take a look at the RTMP_IO_READ32 and RTMP_IO_WRITE32 macros and see if anything jumps out.

Finally, can you do something like[code337vs4s9](touch ~/tmp/dummy_file.c; gcc -E -dM ~/tmp/dummy_file.c;\rm ~/tmp/dummy_file.c)|sort[/code337vs4s9]and attach the output to a posting here. It will provide information on what compile time constants we can use if needed to help support this platform.

Thanks,

olovh

13-06-2008 12:14:43

Hi Vern,

thanks for your efforts. Attached are the l

olovh

13-06-2008 13:29:34

Ooops, pressed the wrong button after attaching a file.. Sorry. Here's the complete message.. )
Well, thanks for you efforts.

Anyhow, with the suggested patches nothing really changes. As I understand the writel() and readl() functions handle endian conversion by themselves, so I would guess problem is elsewhere. Specially since firmware is correctly loaded without the endian patches. On the other hand, I am not an experienced driver developer, so I could be wrong. See link [url2mq50n2b]http://lxr.linux.no/linux+v2.6.20.3/include/asm-arm/io.h#L174[/url2mq50n2b].

Attached is also dmesg without endian patches. Note that firmware loading seem to go well then. At this occation.

thanks,
Olov

Vern

13-06-2008 19:42:52

Hi olovh,

Thanks for the logs.

I don't find any endianizing logic in the writel, readl expansions as supplied by kernel.org. I believe the reason is that a PCI device retains its endianness regardless of the host byte order. I think it is possible to do otherwise, but for reasons of manufacturing economy, vendors don't usually do so. If the kernel you're working with has been tweaked to do different, we may have problems. If it has, could you post a snippet of the expansions?

It looks like there may be a problem with the compiler constants. For example, looking at the compiler constants where the compile target is a PPC machine running in big endian mode, we get[codega7rdsjw]...
#define __BIG_ENDIAN__ 1
...
#define _BIG_ENDIAN 1
...[/codega7rdsjw]Looking at the gcc compiler constants you supplied, I don't see anything specifying big endianness. This means the driver is being compiled for a little endian target. So it may be worth while to double check this.

As an experiment, it also may be informative to go to rt_config.h and add[codega7rdsjw]#define BIG_ENDIAN TRUE[/codega7rdsjw]after line 41 and see what happens.

Googling around for code snippets, it really looks like endian1.patch has the right idea. endian4.patch.gz reverts to the original endianization, but includes the extra debug info for NICLoadFirmware().

Thanks,

edit
I was getting a not logged in message when I tried your link earlier. Now that I have gotten in, I see where indeed there's endian conversion in readl. Try my suggestion for BIG_ENDIAN above, but do not apply the patch. We'll see what happens.

Thanks again,

olovh

17-06-2008 07:42:59

That did the trick! )

Added -DBIG_ENDIAN to kernel EXTRA_CFLAGS which gave compiler error
rtmp.h1618 sorry, unimplemented inlining failed in call to 'NICEnableInterrupt' function body not available
and
rtmp.h1618 sorry, unimplemented inlining failed in call to 'NICEnableInterrupt' function body not available

after removing "inline" for NICEnableInterrupt and NICDisableInterrupt that is defined by "#ifdef BIG_ENDIAN" it compiled and worked!

Basically, I should have checked that BIG_ENDIAN was defined by myself and a suggested action for the driver is to remove the inline declarations in rtmp.h and rtmp_init.c.

Many thanks for a great help!

Vern

17-06-2008 18:15:03

Great!

I can't duplicate the "unimplemented inlining" compile error for rtmp.h in my own environment. There may be something else going on in your environment. I'm removing big endian inline compilation for those functions anyway, though, because I don't see why endianism should make a difference.

Looking thru the gcc constants you provided, I see that __ARMEB__ is present; and indeed is used in the kernel ARM source to determine if endian conversion is needed. So it looks like that's what's needed for automagically doing big endian ARM compilation.

These changes are implemented in endian6.patch.gz, which modifies the following files as follows
[list3o4vemq3]rt_config.h
Add __ARMEB__ to BIG_ENDIAN conditional definition.

rtmp.h
Remove big endian inlining for NICDisableInterrupt, NICDisableInterrupt prototypes.

rtmp_init.c
NICDisableInterrupt(), NICDisableInterrupt()
Remove big endian inlining from definitions.

NICLoadFirmware()
Include MCU_CNTL content in debug error output.[/listu3o4vemq3]

This should have the result that a simple "make", or "make debug" will build the driver correctly for the XSCALE ARM processor in big endian mode.

Could you try it? If everything works OK for you, I'll see about getting these changes into CVS.

Thanks,

Vern

24-06-2008 18:57:38

Well, this thing's been up for a week, downloaded three times, no complaints. So I'll treat it just like it was working.

Y'all were warned.