[ECOS] Dual Ethernet for i386/pc

David Brennan eCos@brennanhome.com
Sat Sep 11 03:45:00 GMT 2004


I have just started trying to get eth1 to work on our "dual 82559" VME pc.
I ran pci1test and here is a snippet of the output.
Found device on bus 1, devfn 0x30:
 Note that board is active. Probed sizes and CPU addresses invalid!
 Device configuration succeeded
 Vendor    0x8086 [Intel][Intel Corporation]
 Device    0x1209 [82559ER][Ethernet Controller]
 Command   0x0117, Status 0x0290
 Class/Rev 0x02000009 [Network Controller][Ethernet][]
 Header 0x00
 SubVendor 0x0000, Sub ID 0x0000
 BAR[0]    0xf410b000 / probed size 0x00000000 / CPU addr 0xf410b000
 BAR[1]    0x00002001 / probed size 0x00000000 / CPU addr 0x00002000
 BAR[2]    0xf4120000 / probed size 0x00000000 / CPU addr 0xf4120000
 BAR[3]    0x00000000 / probed size 0x00000000 / CPU addr 0x00000000
 BAR[4]    0x00000000 / probed size 0x00000000 / CPU addr 0x00000000
 BAR[5]    0x00000000 / probed size 0x00000000 / CPU addr 0x00000000
 Wired to HAL vector 41
Found device on bus 1, devfn 0x40:
 Note that board is active. Probed sizes and CPU addresses invalid!
 Device configuration succeeded
 Vendor    0x8086 [Intel][Intel Corporation]
 Device    0x2449 [82801BA/BAM/CA][LAN Controller]
 Command   0x0117, Status 0x0290
 Class/Rev 0x02000003 [Network Controller][Ethernet][]
 Header 0x00
 SubVendor 0x0000, Sub ID 0x0000
 BAR[0]    0xf410c000 / probed size 0x00000000 / CPU addr 0xf410c000
 BAR[1]    0x00002041 / probed size 0x00000000 / CPU addr 0x00002040
 BAR[2]    0x00000000 / probed size 0x00000000 / CPU addr 0x00000000
 BAR[3]    0x00000000 / probed size 0x00000000 / CPU addr 0x00000000
 BAR[4]    0x00000000 / probed size 0x00000000 / CPU addr 0x00000000
 BAR[5]    0x00000000 / probed size 0x00000000 / CPU addr 0x00000000
 Wired to HAL vector 37
So it is not truly a dual 82559 pc, but according to the driver both of 
these device ID's are supported. But I was concerned that the 82559 had 
3 BARs and the 82801 only reported 2.

I read through the if_i82559.c code and could not see any reason why 
this should not work. So I modified i386_pc_i82559_eth_driver.cdl, 
devs_eth_i386_pc_i82559.inl and intel_i82559_eth_drivers.cdl.

On my first attempt at booting up, the code asserted:
   Bus: 1, Dev: 6, Fn: 0, Vendor: 8086
... PCI vendor = 8086, device = 1209, class 20000
Update memory base to f420b000 from bar: 0
cyg_pci_find_matching - func is at 22ee2c
cyg_pci_find_next: start[13000] ...
   Bus: 1, Dev: 8, Fn: 0, Vendor: 8086
... PCI vendor = 8086, device = 2449, class 20000
Init device 'i82559_eth1'
rfd under: InitRxRing:1848
rfd under: InitRxRing:1848
Bad link eth1 0x003889b0 0x00000000 8 0x0022d2dc: InitRxRing:1848
ASSERT FAIL: <1>if_i82559.c[1928]CheckRxRing() Bad Link
[New Thread 1]
[Switching to Thread 1]

Breakpoint 1, cyg_assert_fail (psz_func=0x2c2215 "CheckRxRing",
    psz_file=0x2c2ac0 
"/ecos-c/cygwin/opt/ecos/ecos-cvs/ecos/packages/devs/eth/i
ntel/i82559/current/src/if_i82559.c", linenum=1928,
    psz_msg=0x2c220c "Bad Link")
    at 
/ecos-c/cygwin/opt/ecos/ecos-cvs/ecos/packages/infra/current/src/buffer.c
xx:727
727         HAL_DISABLE_INTERRUPTS(old_ints);
Current language:  auto; currently c++
(gdb) l
722     cyg_assert_fail( const char *psz_func, const char *psz_file,
723                      cyg_uint32 linenum, const char *psz_msg ) __THROW
724     {
725         cyg_uint32 old_ints;
726
727         HAL_DISABLE_INTERRUPTS(old_ints);
728         DIAG_DEVICE_START_SYNC();
729
730         diag_write_string("ASSERT FAIL: ");
731         write_thread_id();
(gdb) fr 1
#1  0x0022d652 in CheckRxRing (p_i82559=0x2cfc20, func=0x2c218c 
"InitRxRing",
    line=1848)
    at 
/ecos-c/cygwin/opt/ecos/ecos-cvs/ecos/packages/devs/eth/intel/i82559/curr
ent/src/if_i82559.c:1928
1928            CYG_ASSERT(HAL_LE32TOC(link) == VIRT_TO_BUS(p_rfd),"Bad 
Link");
Current language:  auto; currently c
(gdb) l
1923            console_printf("Bad link eth%d %p %p %d %p: %s:%d\n",
1924                           p_i82559->index,
1925                           HAL_LE32TOC(link), VIRT_TO_BUS(p_rfd),
1926                           i, __builtin_return_address(0),
1927                           func,line);
1928            CYG_ASSERT(HAL_LE32TOC(link) == VIRT_TO_BUS(p_rfd),"Bad 
Link");
1929          }
1930        }
1931    }
1932
(gdb) p p_i82559->rx_ring
$1 = {0x3889b0 "", 0x388fc0 "", 0x3895d0 "", 0x389be0 "", 0x38a1f0 "",
  0x38a800 "", 0x38ae10 "", 0x0 <repeats 121 times>}
(gdb) p p_rfd2
$2 = (RFD *) 0x2 ""
(gdb) p p_rfd
$3 = (RFD *) 0x0
(gdb) p i
$4 = 8
I'm not really sure what caused this, but as a temporary solution I 
changed CYGNUM_DEVS_ETH_INTEL_I82559_MAX_RX_DESCRIPTORS to only be 8. 
(I'm not sure why eth0 initialized all of its rx rings, but eth1 did 
not. But that's a problem for another day. As are the two rfd under 
messages.)

The next problem was:
   Bus: 1, Dev: 6, Fn: 0, Vendor: 8086
... PCI vendor = 8086, device = 1209, class 20000
Update memory base to f420b000 from bar: 0
cyg_pci_find_matching - func is at 22ede4
cyg_pci_find_next: start[13000] ...
   Bus: 1, Dev: 8, Fn: 0, Vendor: 8086
... PCI vendor = 8086, device = 2449, class 20000
Init device 'i82559_eth1'
ASSERT FAIL: <1>if_i82559.c[2194]ResetTxRing() txcb under
[New Thread 1]
[Switching to Thread 1]

Breakpoint 1, cyg_assert_fail (psz_func=0x2c22b6 "ResetTxRing",
    psz_file=0x2c2a60 
"/ecos-c/cygwin/opt/ecos/ecos-cvs/ecos/packages/devs/eth/i
ntel/i82559/current/src/if_i82559.c", linenum=2194,
    psz_msg=0x2c22cc "txcb under")
    at 
/ecos-c/cygwin/opt/ecos/ecos-cvs/ecos/packages/infra/current/src/buffer.c
xx:727
727         HAL_DISABLE_INTERRUPTS(old_ints);
Current language:  auto; currently c++
(gdb) fr 1
#1  0x0022dfa4 in ResetTxRing (p_i82559=0x2cf9e0)
    at 
/ecos-c/cygwin/opt/ecos/ecos-cvs/ecos/packages/devs/eth/intel/i82559/curr
ent/src/if_i82559.c:991
991             CYG_ASSERT( wait > 0, "wait_for_cmd_done: CU busy" );
Current language:  auto; currently c
(gdb) l
986                 wait = 0x100000;
987                 do status = INW(scb_ioaddr + SCBCmd) /* nothing */;
988                 while( (0 != ((CU_CMD_MASK | RU_CMD_MASK) & status)) 
&& --wa
it >= 0);
989             }
990
991             CYG_ASSERT( wait > 0, "wait_for_cmd_done: CU busy" );
992
993         } else if (WAIT_RU == type) {
994             // Can't see any active state in the doc to check for
995         }
(gdb) p scb_ioaddr
No symbol "scb_ioaddr" in current context.
(gdb) p status
$1 = 2
(gdb) p wait
$2 = 2947552
(gdb) p/x wait
$3 = 0x2cf9e0
This confused me in a couple of ways. First the fact that scb_ioaddr was 
undefined (probably out of scope due to optimization.). Second that wait 
is clearly >0.
Assuming that these are easily explainable, I don't know what I should 
do to start troubleshooting the 'wait_cmd_done: CU busy' condition?

I suspect that on Monday I will actually try and configure my PC to boot 
LAN 2 as eth0 and see if that works. But if it does or doesn't I'm not 
sure that I am up to debugging an Ethernet device driver. Are there any 
goo pointers for how to go about doing this?

Thanks
David Brennan

-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss



More information about the Ecos-discuss mailing list