Re: Ethernet driver question

Hi HH

Not really, i couldn't understand that code very much. At first i wanted to add support for configuring the ethernet switch. But i found the code too messy so i prefered backporting Jeroe Vreeken's driver instead. If you want to modify the ethernet driver, i would recommend you to try with the current AMiLDA driver. It will be easier and it already includes more functionality.

Re: Ethernet driver question

Nope, it doesn't do the same. It creates 5 (or 6 if you're using the BGA version) interfaces which stand for each of the ethernet ports the CPU has. They can be optionally connected to a physical port. You can say "connect ports 1 to 3 to CPU port 1, then ports 4-6 to CPU port 2" and so on. The original driver just hardcodes the number of interfaces to 2 and the switch configuration is also hardcoded. Nothing much to do there.

Re: Ethernet driver question

I think I understand. Now I am doing some classic reverse-engineering. I disassembled the entire Hawking vmlinux.bin kernel. I compiled the 2.4.18 Edimax file drivers/net/am5120sw/swdrv.c and disassembled it. Comparing the two listings shows some interesting things.

The Hawking firmware turns on the Bridge Testing Mode (BTM bit 2) in the CPUp_conf register (sw offset 0x24). That seems very strange. Any idea what that bit does? I will have to run a test to see if they leave it on after the router is initialized.

Another interesting thing: in swdriv_init() the Hawking code sets the GFP_DMA flag in calls to kmalloc, but the Edimax source code does not! I think I'm getting closer.

Re: Ethernet driver question

Re: Ethernet driver question

That was me I made the kmalloc changes and now I can ping outside the router, but only if I do an "ifconfig" after the eth1 interface is up. Weird. Not "down" and "up" again, just plain "ifconfig". Then ping starts to work. It seems random. One thing that still happens is a kernel oops right after I type in "reboot". Seeing a live ping response is encouraging, however, because it wasn't working at all before the change.

Re: Ethernet driver question

Finally I fixed the problem in the 2.4.18 Edimax code. In drivers/net/am5120sw/if5120.h the constant BUF_ADDR_MASK needed to be changed from 0x00FFFFFF to 0x01FFFFFF. This value should essentially be (ramsize - 1). I found this by doing a painstaking comparison of the object code I compiled from the Edimax source with the binary vmlinux.bin kernel from the actual Hawking vendor firmware. The code itself was fine but this constant was wrong for 32 MB of RAM.

It's amazing what you can find by reverse engineering binary code

Changing MAX_DMA_ADDRESS in include/asm-mips/dma.h, or adding the GFP_DMA flag to the kmalloc calls in drivers/net/am5120sw/swdrv.c did not help because the adm5120 drivers were obtaining memory from kmalloc above the 16 MB line anyway, and when an address above 16 MB is masked with 0x00FFFFFF then the address is broken. That explains the random nature of the failures I was seeing. If a page was obtained below the 16 MB line it would work, but if a page was obtained above the 16 MB line then it was lost forever after the address was masked with the incorrect value.

In the AMiLDA code I tried changing ADM5120_DMA_MASK (in drivers/net/adm5120sw.h) from 0x00FFFFFF to 0x01FFFFFF but the network still doesn't work when 32 MB of RAM is defined. I'm not sure where else to look in the AMiLDA code but I think the cause of the problem is similar to the Edimax driver problem.

Re: Ethernet driver question

Re: Ethernet driver question

HH wrote:

Finally I fixed the problem in the 2.4.18 Edimax code. In drivers/net/am5120sw/if5120.h the constant BUF_ADDR_MASK needed to be changed from 0x00FFFFFF to 0x01FFFFFF. This value should essentially be (ramsize - 1). I found this by doing a painstaking comparison of the object code I compiled from the Edimax source with the binary vmlinux.bin kernel from the actual Hawking vendor firmware. The code itself was fine but this constant was wrong for 32 MB of RAM.

It's amazing what you can find by reverse engineering binary code :)

Changing MAX_DMA_ADDRESS in include/asm-mips/dma.h, or adding the GFP_DMA flag to the kmalloc calls in drivers/net/am5120sw/swdrv.c did not help because the adm5120 drivers were obtaining memory from kmalloc above the 16 MB line anyway, and when an address above 16 MB is masked with 0x00FFFFFF then the address is broken. That explains the random nature of the failures I was seeing. If a page was obtained below the 16 MB line it would work, but if a page was obtained above the 16 MB line then it was lost forever after the address was masked with the incorrect value.

In the AMiLDA code I tried changing ADM5120_DMA_MASK (in drivers/net/adm5120sw.h) from 0x00FFFFFF to 0x01FFFFFF but the network still doesn't work when 32 MB of RAM is defined. :( I'm not sure where else to look in the AMiLDA code but I think the cause of the problem is similar to the Edimax driver problem.

Hi,I modified drivers/net/adm5120sw.h as you said and it works! (from 0x00FFFFFF to 0x01FFFFFF and memsize of prom.c)My kernel was patched by linux-2.4.32-adm.patch.