2012-02-13

[IPNC][DM368] BBT problem after patch to new ECC layout (Bad block table not found for chip 0))

This is follow-up section of another NAND ECC topic  NAND ECC issue - ECC layout incompatible between RBL/UBL and U-Boot/Linux

After patching new ECC table, we found that "Bad block table not found for chip 0" keeps showing even if "Bad block table written to 0x07ffc000" follows every time boot up. It means that the BBT is not written correctly, in both u-boot and linux kernel.

After (painfully) tracing ECC and BBT relevant source code in u-boot, I found the root cause is the incorrect location of writing BBT/mirror patterns.

1. look at following illustration which capture from TI's wiki (http://processors.wiki.ti.com/index.php/DM365_Nand_ECC_layout)


in the file drivers/mtd/nand/nand_bbt.c, there are two nand_bbt_descr structure, bbt_main_descr and bbt_mirror_descr which contain the information how bbt is placed and searched.

originally, the structures are like below (2010-12 u-boot release, I compared with the latest one,Dec 2011, and there isn't meaningful difference regarding ECC and BBT).
===

static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
static struct nand_bbt_descr bbt_main_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8,
.len = 4,
.veroffs = 12,
.maxblocks = 4,
.pattern = bbt_pattern
};
static struct nand_bbt_descr bbt_mirror_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8,
.len = 4,
.veroffs = 12, .maxblocks = 4,
.pattern = mirror_pattern
};


===

2. in check_pattern()@nand_bbt.c, we know that the structure member
offs - the offset from start of oob of block, to place the bbt_pattern
len - the length of bbt pattern
veroffs - the offset from the start of oob of block, to place the bbt version number

Apparently the setting was wrong after deploying the new ECC layout (the upper table in the picture) because the bbt pattern, starting from the 8th byte of OOB, is conflict with ECC.

I change it to 16th and veroffs at 32th, and BBT is back again!  The corresponding portion in Linux source should be changed too. In appro's ipnc release, the change can be made at ti-davinci/arch/arm/mach-davinci/board-dm368-ipnc.c

[DM368][IPNC] NAND ECC issue - ECC layout incompatible between RBL/UBL and U-Boot/Linux

There is a big trouble when we need to update u-boot from u-boot because of some fatal bug in u-boot GPIO configuration. I was surprised that TI doesn't synchronize ECC layout between RBL/UBL and U-Boot/Linux.

The result is that even we can write the new U-Boot from the existing one, UBL decided those modified NAND blocks invalid due to ECC inconsist so the new U-Boot image won't be loaded. Same situation occurs when we want to update UBL from U-Boot.

Fortunately, TI does provide solution to sync ECC layout at wiki (http://processors.wiki.ti.com/index.php/DM365_Nand_ECC_layout)
The steps are fairly simple as below:
1. patch u-boot code
===

diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 4ca738e..4ba12ce 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -278,5 +278,13 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat,
 static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = {
 #if defined(CONFIG_SYS_NAND_PAGE_2K)
  .eccbytes = 40,
+        .eccpos = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+                   22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+                   38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+                   54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+                   },
+        .oobfree = {{2, 4}, {16, 6}, {32, 6}, {48, 6}},
+#if 0
  .eccpos = {
   24, 25, 26, 27, 28,
   29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
@@ -288,6 +296,7 @@ static struct nand_ecclayout nand_davinci_4bit_layout_oobfirst = {
  .oobfree = {
   {.offset = 2, .length = 22, },
  },
+#endif
 #elif defined(CONFIG_SYS_NAND_PAGE_4K)
  .eccbytes = 80,
  .eccpos = {

====

2. patch Linux kernel
===
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c
index 5d3946e..4bce9db 100644
--- a/arch/arm/mach-davinci/board-dm365-evm.c
+++ b/arch/arm/mach-davinci/board-dm365-evm.c
@@ -89,5 +89,17 @@ static struct mtd_partition davinci_nand_partitions[] = {
  /* two blocks with bad block table (and mirror) at the end */
 };
 
+static struct nand_ecclayout dm365_evm_nand_ecclayout = {
+ .eccbytes = 40,
+ .eccpos  = {6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+     22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+     38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+     54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
+ },
+ .oobfree = {{2, 4}, {16, 6}, {32, 6}, {48, 6} },
+};
+
 static struct davinci_nand_pdata davinci_nand_data = {
  .mask_chipsel  = BIT(14),
  .parts   = davinci_nand_partitions,
@@ -96,6 +108,7 @@ static struct davinci_nand_pdata davinci_nand_data = {
  .ecc_mode  = NAND_ECC_HW,
  .options  = NAND_USE_FLASH_BBT,
  .ecc_bits  = 4,
+ .ecclayout  = &dm365_evm_nand_ecclayout,
 };
 
 static struct resource davinci_nand_resources[] = {
diff --git a/arch/arm/mach-davinci/include/mach/nand.h b/arch/arm/mach-davinci/include/mach/nand.h
index b2ad809..7c6be2b 100644
--- a/arch/arm/mach-davinci/include/mach/nand.h
+++ b/arch/arm/mach-davinci/include/mach/nand.h
@@ -83,6 +83,9 @@ struct davinci_nand_pdata {  /* platform_data */
  /* Main and mirror bbt descriptor overrides */
  struct nand_bbt_descr *bbt_td;
  struct nand_bbt_descr *bbt_md;
+
+    /*Nand ECC layout*/
+    struct nand_ecclayout   *ecclayout;
 };
 
 #endif /* __ARCH_ARM_DAVINCI_NAND_H */
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
index 06ee8c8..4e4ed73 100644
--- a/drivers/mtd/nand/davinci_nand.c
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -762,7 +762,10 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
    goto syndrome_done;
   }
   if (chunks == 4) {
-   info->ecclayout = hwecc4_2048;
+   if (pdata->ecclayout != NULL)
+    info->ecclayout = *(pdata->ecclayout);
+   else
+    info->ecclayout = hwecc4_2048;
    info->chip.ecc.mode = NAND_ECC_HW_OOB_FIRST;
    goto syndrome_done;
   }

===

3. Update U-Boot. If we got the UART or SD boot reserved, it would be easy to just update the new U-Boot image. We were not that lucky in this case so there is chicken-n-egg problem. First, we think it is feasible to load the new U-Boot image to a different memory address and jump to this address to program new U-Boot. 

To make the new U-Boot image resides at different memory address (instead of default 0x81080000), we change the setting at (u-boot root)/board/davinci/dm365evm/config.mk, and got a new (ECC patched) u-boot image say uboot.82
===
CONFIG_SYS_TEXT_BASE = 0x82000000
===
Then we load uboot.82 to ram address 0x82000000 using tftpboot or load from USB. "go 0x82000000" can  execute new u-boot image with writing new ECC layout capability.

4. If step 3 failed, because of some reasons (We did fail because of incorrect DRAM setting so memory copy sometimes fail), there is another hack to fix this problem - we replaced the ECC layout table at RAM of current U-Boot!


Thanks that the size of ECC layout structure (static struct nand_ecclayout) remains the same so the replacement can be done by just modifying the content of the old table in RAM. By searching pattern 0x00000006, 0x00000007... starting from 0x81080000, there is only one occurrence in RAM. After carefully calculating the offset, it's easy to change it to new layout based on Step 1 description. Now, Great!, we can not only do U-Boot update but also UBL from current U-Boot!


Followups


There is side effect after patching with the new ECC table. you can find that the BBT(Bad Block Table) cannot be found and updated. I will use another post to discuss and fix this issue.
[IPNC][DM368] BBT problem after patch to new ECC layout (Bad block table not found for chip 0)


Note:
to update u-boot from u-boot, we have to prepare image header for the new uboot image in RAM.
using RAM location 0x82000000 as example, the steps are
1. clear ram buffer

mw.l 0x82000000 0xffffffff 0x60000

2. prepare header (at 1st page, 2k in my case)


mw.l 0x82000000 0xa1aced66
mw.l 0x82000004 0x81080000
mw.l 0x82000008 0x000000a0
mw.l 0x8200000c 0x0000000a
mw.l 0x82000010 0x00000001
mw.l 0x82000014 0x81080000


the definition reference:
typedef struct _NANDBOOT_HEADER_
{ 
 Uint32 magicNum;            // Expected magic number 
 Uint32 entryPoint;          // Entry point of the user application 
 Uint32 numPage;             // Number of pages where boot loader is stored 
 Uint32 block;               // Starting block number where User boot loader is stored
 Uint32 page;                // Starting page number where boot-loader is stored 
 Uint32 ldAddress;           // Starting RAM address where image is to copied - XIP Mode 
 Uint32 forceContigImage;    // Force blocks to be contiguous (used for UBL image since RBL can't deal with skipping bad blocks) 
 Uint32 startBlock;          // Starting block number to attempt placing copies of image 
 Uint32 endBlock;            // Ending block number to stop copy placement 
}
NANDBOOT_HeaderObj,*NANDBOOT_HeaderHandle;


3. load uboot (with new ecc layout, start at 0x81080000) to ram

tftpboot 0x82000800 uboot.newecc


4. write to NAND (where 0x140000 is starting block in my case)
nand write 0x82000000 0x140000 0x60000 





2011-11-29

[DM368][IPNC][UBL] GPIO and Pinmux Initialization

[Prolog]
In order to adapt my new hardware board, I have to change many of GPIO settings in Appro's IPNC SDK. I thought the major GPIO setting code would reside at linux arch, but it was wrong. Surprisely,  most of the setting including pinmux and GPIO direction is done at UBL!


[Main]
Restore your memory to school life...yeah, the good old time. All lectures taught you that the settings should be made where it needed during boot process. i.e. GPIO should be only configured  at the stage it will be used during boot straps.


UBL apparently is not a good place to perform GPIO configuration. TI even doesn't provide UBL source code with dvsdk! 


1. the code to set GPIO@ubl is at flash_utils/DM36x/Common/src/device.c, DEVICE_init()
==========

  DEVICE_pinmuxControl(0,0xFFFFFFFF,0x00FD0000);  // All Video Inputs  DEVICE_pinmuxControl(1,0xFFFFFFFF,0x00145555);  // All Video Outputs  DEVICE_pinmuxControl(2,0xFFFFFFFF,0x000000DA);  // EMIFA  DEVICE_pinmuxControl(3,0xFFFFFFFF,0x60000000);  // SPI0, SPI1, UART1, I2C, SD0, SD1, McBSP0, CLKOUTs 00180000  DEVICE_pinmuxControl(4,0xFFFFFFFF,0x5555D555);  // MMC/SD0 instead of MS, SPI0 55555555    GPIO->DIR23 &= 0xfeffffff;  GPIO->CLRDATA23 = 0x01000000;

==========


Moreover, you can find the system and peripheral clocks are set in  DEVICE_PLL1Init() and DEVICE_PLL2Init(), which I think can be move some to u-boot or even linux.


2. I decide to follow what textbook said - minimize the configure in ubl and u-boot and leave board specific changes to linux boot code. the benefit is obvious - I don't have to change code and recompile ubl (and maybe even better: u-boot as well) if hardware is changed. 


to be compatible with most DM368 hardware, I set most pin to GPIO, except MMC/SD0, VIN, UART0, UART1, I2C, CLKOUT0. The changes is listed below: 
==========

 //MMC/SD0, GIO49-43, YIN7-0, VD, HD, C_WE_FIELD  DEVICE_pinmuxControl(0,0xFFFFFFFF,0x00000000);   //GIO79-92 DEVICE_pinmuxControl(1,0xFFFFFFFF,0x00430000); 
//CMNT: GIO57-78 and EM_A[1] is configured by AECFG setting. leave it as-is and change in u-boot or os// CE0(GIO56) set to GPIO Interfacing to a Non-CE Don't Care NAND Flash  DEVICE_pinmuxControl(2,0x00000080,0x00000080);
//consider to enable emac for emac-boot  DEVICE_pinmuxControl(3,0xFFFFFFFF,0x61580000);  //UART1_TX, UART0, I2C
  DEVICE_pinmuxControl(4,0xFFFFFFFF,0x0030c000);  //CLKOUT0, UART1_RX


==========

There is also patch of NAND CE for Non-CE Don't card NAND flash. The CE is configured to GPIO and driven low manually.



GPIO->DIR23 &= 0xFEFFFFFF; //DIR56(bit24) set to output (L)
GPIO->CLRDATA23 = 0x01000000; //nand_ce low


The binary file can be downloaded at dm36x ubl gpio bin (uart0 and uart1 message). please be noted that you may want to revise GPIOs which are used by UART0 or UART1 in either u-boot or linux because they are all configured as UART in this binary.


[Option]
1. Turn on PINMUX to Ethernet in U-boot 
board_eth_init@dm365evm.c

//CMNT: manipulate eth pinmux only, PINMUX3[18:0]
// writel((readl(PINMUX3) | 0x1affff), PINMUX3); //RR CMNT: [18:0]-eth, [20:19]-UART0, [31:21] GIO26-20
writel(((readl(PINMUX3) & 0xfff80000) | 0x2ffff), PINMUX3); //CMNT: [18:0]-eth, [20:19]-UART0, [31:21] GIO26-20
2. Extend PHY reset time at board_eth_init@dm365evm.c from 1ms to 10ms, according DAVICOM PHY specification
udelay(10000);



[Epilog]

Unfortunately, GPIO settings in Linux vary from versions. The worse is that the setting scatters in different files. If you want to do it all at one place, you can put them in board_init()@board-dm368-ipnc.c. 
The Pinmux definition files have to be changed as well - check 
arch/arm/plat-davinci/mux.c
arch/arm/mach-davinci/mux_cfg.c
include/arch/arm/mach-davinci/mux.h 

2011-08-29

[DM368][IPNC] Upgrade udev on IPNC-DM368

[Prolog]

the reason I would like to upgrade udev on IPNC-DM368 is that the latest Appro package (Ver_2.00.26, kernel 2.6.18) doesn't contain 'udevadmin', which is used to control the runtime behavior of udev, request kernel events, manage queue, and debug udev.

Appro's package includes some of udev helper functions such as udevtrigger and udevinfo. However, udevadmin is what I want to follow Embedded Linux Primer, 2nd edition, ch19.

[Main]

1. Get the udev package from kernel tree. The latest version which supports kernel 2.6.18 is udev-127.

2. Unpack the tarball

3. Configure the make envionment
CC=/opt/mv_pro_5.0.0/montavista/pro/devkit/arm/v5t_le/bin/arm_v5t_le-gcc ./configure --host=armv5tl-montavista-linux-gnueabi --prefix=/home/usr/work/udev-127/filesys


4. make & make install

5. udevd and udevadm were generated under directory ./udev


[Epilog]

Easy work! as long as the CC is set correctly, there will be no problem to finish the job.

[Extend readings]

CH19, Embedded Linux Primer, 2nd Edition






2011-08-17

[DM368][IPNC] Using GDB on IPNC

[Prolog]

To dig into Appro's application, I decided to enable gdb on IPNC platform. There are two useful page provided by TI's wiki and they let me enable gdb on IPNC in one hour.
==============================
==============================

[Main]
1. get the latest gdb from gdb download page

2. configure and make gdb and gdbserver

for gdb
==============================
host# ./configure --host=i686-pc-linux-gnu --target=armv5tl-montavista-linux-gnueabi --prefix=/opt/mv_pro_5.0.0/montavista/pro/devkit/arm/v5t_le
host# make
host# make install
==============================

for gdbserver
==============================
host# cd gdb/gdbserver
host# CC=/opt/mv_pro_5.0.0/montavista/pro/devkit/arm/v5t_le/bin/arm_v5t_le-gcc ./configure  --host=armv5tl-montavista-linux-gnueabi --prefix=/home/user/workdir/filesys
host# make && make install
==============================

there was an error during "make install". the screen showed
==============================
cannot stat 'libinproctrace.so': No such file or directory
==============================

after quick google search, it can be fixed by modifying "gdb/gdbserver/Makefile.in"
==============================
original:
if [ x$IPA_DEPFILES != x ]; then \
fixed:
if [ x${IPA_DEPFILES} != x ]; then \
==============================


3. Running gdbserver at target
==============================
target# gdbserver 192.168.100.1:1000 ./sample
==============================



4. Running gdb at host
==============================
host# /opt/mv_pro_5.0.0/montavista/pro/devkit/arm/v5t_le/bin/armv5tl-montavista-linux-gnueabi-gdb ./sample
==============================

at gdb prompt
==============================
(gdb) set solib-search-path /home/user/workdir/filesys/lib (gdb) target remote 192.168.100.2:1000
==============================


5. (optional) using ddd
==============================
host# ddd --debugger arm_v5t_le-gdb
==============================

6. (optional) error "Malformed packet(b) (missing colon)" 
    in Appro reference design, there is an existing gdbserver under /usr/bin. However, the installation of gdbserver is toward /bin, and the PATH setting will select the old gdbserver (GNU gdbserver 6.6.50.20070301 in my case). Easy to fix though.




[Epilog]
Easy works as far! multitread debugging could be challenge though
[Extend readings]

Debugging on DaVinci using kgdb



2011-08-12

[DM368][IPNC][U-Boot] Porting U-boot to DM368-IPNC (1) Ethernet

[Prologue]
Appro's DM368 IPNC reference code uses u-boot version 1.3.4, which is kind of old version without USB and MMC boot support. Appro doesn't seems to upgrade it in the near future (actually it doesn't care except you are big customer). 


Couple days ago I found TI released a new dvsdk for DM365/DM368 (DVSDK_4.02 4_02_00_06), which contains U-Boot 2010.12-rc2. Even though it's not the latest version, it includes all required feature I want. I decided to port this version to DM368-IPNC.




[Main]
After scanning related config files, I decided to use include/configs/davinci_dm365evm.h as template to start the work. This article focuses on enabling Ethernet of U-Boot on IPNC. Others issues will be discussed later.

Steps:
1. create a new config file include/configs/davinci_dm368_ipnc.h with the same content of davinci_dm365evm.h

2. add board information to boards.cfg
==============================
(davinci_dm368_ipnc           arm         arm926ejs   dm365evm            davinci        davinci)
==============================

3. make u-boot!
I didn't use CodeSourcery so had to assign cross compiler.
the commands are
==============================
make CROSS_COMPILE=arm_v5t_le- distclean
make CROSS_COMPILE=arm_v5t_le- clean
make CROSS_COMPILE=arm_v5t_le- davinci_dm368_ipnc_config
make CROSS_COMPILE=arm_v5t_le-
==============================

4. found Ethernet doesn't work. after issuing "ping 192.168.1.1", which is my tftp/nfs server, IPNC hung forever without any message shown. I cannot break it by Ctrl-C either.

5.turn on Ethernet debug to get more messages
at drivers/net/davinci_emac.c, enable emac_dbg
==============================
unsigned int emac_dbg = 1;
==============================

6. reboot IPNC, and issue ping again, I got

==============================
+ emac_close
+ emac_ch_teardown
- emac_ch_teardown
+ emac_ch_teardown
- emac_ch_teardown
- emac_close
+ emac_open
==============================
and IPNC hung. "+ emac_open" was printed by davinci_eth_open()@drivers/net/davinci_emac.c. after get_link_speed statement, it broke by "return 0".
==============================
(!phy.get_link_speed(active_phy_addr))
return(0);

==============================

6. the suspicious point was the variable "active_phy_addr" above. so I added two debug print to ensure it's the root cause.
==============================

debug_emac("+ emac get_link_speed, active_phy_addr = %x\n", active_phy_addr);
if (!phy.get_link_speed(active_phy_addr))
return(0);
debug_emac("- emac get_link_speed\n");
==============================
it confirmed the problem point and active_phy_addr = 0xFF, which is strange.

7. trace code to locate where we got the active_phy_addr and found davinci_eth_phy_detect() @ drivers/net/davinci_emac.c
==============================

phy_act_state = readl(&adap_mdio->ALIVE) & EMAC_MDIO_PHY_MASK;
if (phy_act_state == 0)
return(0); /* No active PHYs */
==============================
there is no error handling code if return 0 (No active PHYs). EMAC_MDIO_PHY_MASK is a macro from EMAC_MDIO_PHY_NUM(@emac_defs.h), which is defined in config file with the value 2.
==============================
/* PHY mask - set only those phy number bits where phy is/can be connected */
#define EMAC_MDIO_PHY_NUM           CONFIG_EMAC_MDIO_PHY_NUM
#define EMAC_MDIO_PHY_MASK          (1 << EMAC_MDIO_PHY_NUM)
==============================

8. Check with schematic file of IPNC and the datasheet of PHY (DM9161), the strapping config is 1 (PHYAD0 pull high), which means the PHY address is 1. Tried to dump the register of MDIO-ALIVE(0x01d0b00c) and the value is 0x00000002. it showed the PHY address should be 1.

9. Change the config value of PHY number at davinci_dm368_ipnc
==============================
 #define CONFIG_EMAC_MDIO_PHY_NUM 1
==============================
and make u-boot again

10. Bingo!
==============================
Ethernet PHY: GENERIC @ 0x01
DaVinci-EMAC
Hit any key to stop autoboot:  0
==============================

[Epilogue]


Some of the issues are not discussed, some are not fixed yet.
To Be Post -
UART
NAND - ECC

To Be Fixed -
USB
MMC
MTD

2011-07-21

[DM368][RTL8191] Porting RTL8191S to DM368/IPNC

The target is to install RTL8191SU, USB dongle, to davinci DM368.

Steps:
1. get official device driver from Realtek

2. in the software package, there are some documentation we would like to read first.
I suggest
HowTo support more VidPids.doc - check if VID/PID is included in code (os_intf/linux/usb_intf.c)
HowTo support new platform(including Android).doc - change Makefile 
In Makefile, I added a new platform CONFIG_PLATFORM_DM368 so the following lines were added
###
CONFIG_PLATFORM_DM368 = y
ifeq ($(CONFIG_PLATFORM_DM368), y)
EXTRA_CFLAGS += -DCONFIG_LITTLE_ENDIAN
ARCH := arm
CROSS_COMPILE = arm_v5t_le-
KSRC := [YOUR KERNEL SRC]/ipnc/ti-davinci
endif
###
3. No problem after above change, we got 8712u.ko. However, when inserting module "insmod 8712u.ko", some error messages were prompted.


# insmod 8712u.ko
8712u: Unknown symbol strcasecmp
insmod: cannot insert `8712u.ko': Unknown symbol in module (-1): No such file or directory

It's apparently that the function "strcasecmp" is not included in the C library in DM368/IPNC. I confirmed it by checking include/linux/string.h (as well as asm/string.h). I decided not to modify lib but change rtl871x_ioctl_linux.c instead.

in rtl871x_ioctl_linux.c, there are couple lines of code using "strcasecmp". I use "strcmp" with small characters instead. for example

// if(0 == strcasecmp(ext,"RSSI")){
if(0 == strcmp(ext,"rssi")){

4. After all the change, the module can successfully be installed and "wlan0" can be find by "ifconfig -a"

2011-07-20

[DM368][RT73] Enabling Wireless Dongle

Reference information

Davinci USB WLan


in case USB is not configured to OTG or host:
I was using D-link DWA-110, Ralink RT-73 NIC
Steps:
1. download serialmonkey's driver source since it is recommended by TI wiki Davinci USB WLan.

there was not too much trouble to make it by following the wiki. I got rt73.ko and copied it to (target)/opt/ipnc. I also copied rt73.bin to (target)/lib/firmware

However, when issuing "insmod rt73.ko", the result was always -

rt73: init
rt73: idVendor = 0x7d1, idProduct = 0x3c03
rt73: Failed to request_firmware. Check your firmware file location
rt73: Failed to load Firmware.
apparently the firmware "rt73.ko" was not found.  I am not too familiar with the procedure after the driver is installed (such as what script will be called , etc). I searched web for quick solution, some useful sites are listed below:
in short, the search failed, even I place rt73.bin to various location, the firmware simply didn't get loaded.

2. Change to official Ralink driver

After reading TI's forum post "Trouble with USB WLAN driver on IPNC DM368", I decided to give up serialmonkey and go official way.

To make the official driver needs a little more effort. There was some kind of kernel inconstant with IPNC release (probably 2.0.26 or something like that). 

I got rt73_drv1.1.0.5 from ralink's download section. To make module, you have to
- modify Makefile: change LINUX_SRC
the first make resulted in missing sturct member get_wireless_stats error in rtmp_main.c, function usb_rtusb_probe()

#if (WIRELESS_EXT >= 12) 
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
netdev->get_wireless_stats = rt73_get_wireless_stats;
#endif
netdev->wireless_handlers = (struct iw_handler_def *) &rt73_iw_handler_def;
#endif
I believe that my IPNC_DM036 release is of kernel 2.6.18, but the include/linux/netdevice.h, the member  get_wireless_stats doesn't exist. not sure if appro or montavista patched it and I didn't check official kernel tree.

Anyway, I changed the #if statement to KERNEL_VERSION(2,6,18) and the module can be compiled.

3. the new rt73.ko works fine, and I also found that rt73.bin is not required.




2011-07-18

[Linux][kernel][DM368] Cannot Change Kernel Config Variable

After changing variables in the (default)config file, davinci_dm368_ipnc_defconfig, "make sys" generates .config but the .config file doesn't match the changes in davinci_dm368_ipnc_defconfig.

turning on USB_STORAGE at defconfig for example

# may also be needed; see USB_STORAGE Help for more information
#
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_LIBUSUAL is not set
CONFIG_USB_STORAGE=m
CONFIG_USB_LIBUSUAL=y 
the .config will be still
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_LIBUSUAL is not set
check steps:
1. track what's performed after executing "make sysall"  (make -n)
make sysall -> make lspall -> make lspclean, make lsp
make lsp -> make lspcfg
make lspcfg->
make lspbuild MAKE_TARGET=davinci_dm368_ipnc_defconfig => make ARCH=arm davinci_dm368_ipnc_defconfig   <==== I after this, .config is generated with incorrect config variables
make lspbuild MAKE_TARGET=checksetconfig

2.  locate potential trouble maker:
"make ARCH=arm davinci_dm368_ipnc_defconfig" executes "scripts/kconfig/conf -D arch/arm/configs/davinci_dm368_ipnc_defconfig arch/arm/Kconfig" to generate .config

suspicious screen output
arch/arm/configs/davinci_dm368_ipnc_defconfig:1037:warning: trying to reassign symbol USB_STORAGE
arch/arm/configs/davinci_dm368_ipnc_defconfig:1038:warning: trying to reassign symbol USB_LIBUSUAL
3. first, check if the variable USB_STORAGE has dependency problem.
the variable is defined at driver/usb/storage/Kconfig
config USB_STORAGE
    tristate "USB Mass Storage support"
    depends on USB
    select SCSI
but I am sure that CONFIG_USB is enabled in the generated .config file.

4. find more information about making kernel.

kernel 移植笔记(从omap linux-02.01.03.11 到 fred 版本kernel 学习)

史上最经典的Linux内核学习方法论

 "make ${PLATFORM}_defconfig"
     Create a ./.config file by using the default
     symbol values from
     arch/$ARCH/configs/${PLATFORM}_defconfig.
     Use "make help" to get a list of all available
     platforms of your architecture.

however, it seems not to have any problem. even I wasted couple hour to compare with the latest kernel.... no luck though

  5. back to fundamental, why "scripts/kconfig/conf -D arch/arm/configs/davinci_dm368_ipnc_defconfig arch/arm/Kconfig" outputs incorrect value.

[PATCH] Allow kconfig to accept overrides - Kernel

inspired me. so trace confdata.c
at conf_read_simple( )
    while (fgets(line, sizeof(line), in)) {
        conf_lineno++;
        sym = NULL;
        switch (line[0]) {
        case '#':
            if (memcmp(line + 2, "CONFIG_", 7))
                continue;
            p = strchr(line + 9, ' ');
            if (!p)
                continue;
            *p++ = 0;
            if (strncmp(p, "is not set", 10))
                continue;
it is surprised me that the line starting with "#" is not a comment !!

Solution
use double hash (##) as comment to "CONFIG_xxx is not set"


## CONFIG_USB_STORAGE is not set
## CONFIG_USB_LIBUSUAL is not set
CONFIG_USB_STORAGE=m
CONFIG_USB_LIBUSUAL=y  



Followups
in montavista releases, there is "Base Configuration for MontaVista Linux" file (scripts/kconfig/baseconfig), which will be compared with .config generated by make xxx_defconfig. The rules are

# If an option is marked as "m", the .config will only
# be modified if the option is turned off.
#
# If an option is marked as "y", the .config will be modified
# if the options in the "m" or the off states.
#
# If an option is marked as "n", the .config will be modified
# if the option is in the "m" or "y" states.
It could influence the final .config for making kernel.