Nand flash driver for bcm47xx wnr3500lv2

@ffainelli

Not so easy to apply this patch to newer kernel though, or is it?

Not sure why you want to check that a PCI bus is detected? The NAND controller is memory mapped into the SoC's address space, that is, it is always there, but the BCMA bus makes it that it can be discoverable by scanning for specific registers.

Porting to a newer kernel should not be too hard, especially if you take out drivers/mtd/nand/bcm47xx_nand.c which would be the file that would likely see the most API adjustments since the MTD layer was heavily reworked.

Because when I compiled it myself on older kernel the driver failed because no PCI bus was detected! pci_find_bus(0, 0) returned NULL.

see at line 2297:

Also the logs seem to show he does not have those PCI problem since he has:

bcma: bus0: Core 0 found: ChipCommon (manuf 0x4BF, id 0x800, rev 0x26, class 0x0)

I think @a.limousin is probably not far from having it working. You would need to add debug (by adding printk into the c code ) to make sure that the driver is loaded and see why it does not go up to "Found a AMD NAND flash"

Which I did not have on older kernel. I will do some tests with kernel 4.14 in one week or so.

@a.limousin

To start can you add printk(KERN_ERR "Our NAND driver is loaded!");

on line 2288 of brcmnand_47xx.c

recompile and run the kernel to see if the driver is really loaded?

Ok I will test within 15 days

I had not modify the Makefile to take into account the driver.

Now I am stuck on this error. I found this structure at dd-wrt in linux-4.14 / drivers / mtd / maps / bcm947xx-flash.c

How to correct this error?

In file included from drivers/mtd/bcm947xx/devices/bcmsflash.c:44:0:
./brcm/include/bcmnvram.h:221:9: note: #pragma message: NVRAM_SPACE=0x8000
 #pragma message (VAR_NAME_VALUE(NVRAM_SPACE))
         ^~~~~~~
drivers/mtd/bcm947xx/devices/bcmsflash.c: In function 'add_cfenvram':
drivers/mtd/bcm947xx/devices/bcmsflash.c:82:28: error: 'cfe_nvrampart' undeclared (first use in this function); did you mean 'cfe_boardpart'?
  if (bcmsflash.mtd.name && cfe_nvrampart.name)
                            ^~~~~~~~~~~~~
                            cfe_boardpart
drivers/mtd/bcm947xx/devices/bcmsflash.c:82:28: note: each undeclared identifier is reported only once for each function it appears in
drivers/mtd/bcm947xx/devices/bcmsflash.c: In function 'bcmsflash_mtd_read':
drivers/mtd/bcm947xx/devices/bcmsflash.c:120:22: error: 'struct mtd_info' has no member named 'mlock'; did you mean '_lock'?
  BCMSFLASH_LOCK(mtd->mlock);

I gave upon trying to port the existing broadcom driver and am currently trying to fit in a new driver next to the bcm4706 one.

I've had some progress: chip id and ordinary reads seem to work for now.
Currently I am debugging why some spare reads yield invalid data which in turn confuses the bad block identification.

The nand controller seems very sensitive to how often and how you access it, often it responds with sending bogus data.

Once I get something up and running more smoothly and need further testing I will let you know.

Oh and the PCI issue is not a problem, access is done using memory mapped I/O.

Ok great, thanks so much!

I've decided to pause this project as I can't figure out why reads keep getting corrupted with my ported driver.
I've put up my work at https://github.com/ErikAndren/linux-kernel-wnr3500lv2-nand

Feel free to pick up the work if anyone is interested.
I'll try to help out best as I can.

thank you very much. good job.
we will continue to work on it. It's very difficult for me

I'm trying a new strategy: first boot on a USB drive, then have an easier development on the nand driver with access to the serial consol and possibility to insmod and rmmod very fast and do other tests.

As the current kernel does not power up USB host I've soldered this wire to power up my usb drive:

3500lv2
3500lv22

I now need to reconfigure a good kernel with USB drive suport, ext4 support, rootwait and root=/dev/sda. And get my hands back on tftp.

This will also have the advantage to be able to see if the wifi driver works or not before we go any further.

I can confirm that it's possible to boot openwrt on a USB drive with this soldering trick! And I can confirm that by default wifi does not work:

BusyBox v1.28.3 () built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 18.06.1, r7258-5eb055306f
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:/# 
root@OpenWrt:/# 
root@OpenWrt:/# ifconfig -a
br-lan    Link encap:Ethernet  HWaddr 00:90:4C:01:E0:01  
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fdc0:54f5:3dad::1/60 Scope:Global
          inet6 addr: fe80::290:4cff:fe01:e001/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:1414 (1.3 KiB)

eth0      Link encap:Ethernet  HWaddr 00:90:4C:01:E0:01  
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:10 errors:0 dropped:0 overruns:0 frame:0
          TX packets:15 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1152 (1.1 KiB)  TX bytes:1930 (1.8 KiB)
          Interrupt:4 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:64 errors:0 dropped:0 overruns:0 frame:0
          TX packets:64 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4352 (4.2 KiB)  TX bytes:4352 (4.2 KiB)

On the other hand the Ethernet/switch networking works correctly:

port 8 is the router, port 0 is wan, and port 1-4 are lan.

Hello,

I have spent some time making the WNR5300LV2 work with @a.limousin.

Since the DD-WRT version is (partialy) working I started from there. The Idea was to use the DD-WRT's 3.10 Kernel withing the build of the last OpenWRT.

Once the external kernel build succeed, the nand support has been tested by loading the system with an initrd in order to have common tools: ash, network support. On this first step the nandflash driver has been tested.

Some configuration after, OpenWRT did boot the nand over the squashfs generated, on this step I have been able to check the full support for Network, Wifi, LED.

To go further, I needed to have a the ability to store the configuration. I patched the kernel 3.10 with overlayfs and rename the MTD partition accordingly in order to have the overlay partition configure at startup.

At this point the system was stable but the write partition still was on tmpfs. The nandflash driver do not manage the OOB metadata require to have a jffs2 partition on the NAND for the overlayfs.

Since then I have been looking the brcmnand_47xx.c driver, that was not working for read.
I finally found something that make the driver working:

diff --git a/src/linux/universal/linux-3.10/drivers/mtd/bcm947xx/nand/brcmnand_47xx.c b/src/linux/universal/linux-3.10/drivers/mtd/bcm947xx/nand/brcmnand_47xx.c
index 996dbf0..7538051 100644
--- a/src/linux/universal/linux-3.10/drivers/mtd/bcm947xx/nand/brcmnand_47xx.c
+++ b/src/linux/universal/linux-3.10/drivers/mtd/bcm947xx/nand/brcmnand_47xx.c
@@ -783,7 +785,7 @@ brcmnand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_c
 
        ret = brcmnand_do_read_ops(mtd, from, &chip->ops);
 
-       *retlen = ops.retlen;
+       *retlen = chip->ops.retlen;
 
        brcmnand_release_device(mtd);

After that I have been able to create a partition on the brcmnand driver in order to have the rootfs_data with OOB and jffs2.

For now I am stuck with this issue : JFFS2 driver writes some information on the OOB, like the magic bitmask: 0x19 0x85, but they do not appear on the nand data itself. Unfortunately the mount_root binary is looking for the magic bitmask on the data.

In order to try a bit further, I tweaked the mount_root binary to accept 0xFFFFFFFF data as JFFS2, This has given some result for testing but it is not stable as the JFFS2 gets CRC errors, and sometime goes on infinite loop and the board reboot.

[   14.870000] jffs2: error: (807) jffs2_do_read_inode_internal: CRC failed for read_inode of inode 120 at physical 0
[   14.880000] jffs2: Returned error for crccheck of ino #120. Expect badness...

I am missing some knowledge on OOB NAND driver and JFFS2. The firmware from netgear has a JFFS2 partition when I boot from it, so there must be something missing somewhere.

This is a small summary, I can give more details, just ask.

Regards,

@leo5593
Thank's

Ok so if I understand you well you try to run a dd-wrt kernel with an openwrt filesystem, and did not try to port drivers to openwrt kernel as we attempted before? This will probably bring some issues, won't it?

Hi,

To be precise, I build the 3.10 kernel within the make of the openwrt image.
I did had some build issues that were corrected.
The nand filesystem apart, the system is working well with this configuration, network and wifi.

@leo5593

Thank's a lot for your replies!

What do you call "the 3.10 kernel"? Do you mean kernel comming from dd-wrt source tree?

Which openwrt filesystem did you use? BarrierBreaker (14.04) was based on 3.10, but It's starting to be pretty old.

Yes the kernel from DD-WRT with the latest version of OpenWRT : 18.06

From the previous post :

The Idea was to use the DD-WRT's 3.10 Kernel within the build of the last OpenWRT

OK sorry about that, I read too fast.
No sure if it is feasible to get a fully working openwrt 18.06 with and old kernel like 3.10 ?