This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Not working lan91cxx_sc drv


Hi,

Forgive me rushing mails,
but I am in desperate.

I am convinced if I only could call lan91cxx_start in ETH_DRV_SC-table
then  it begin to work ethernet drv.

Please teach me where I should set  break_point to trace lan91cxx_start.
Or any hints to tracking lan91cxx_start ?

Please help me.

Masahiro Ariga

-- my prev mai.
Hi,

I put on my target's eth_drivers CDL file.
inserter_eth_drivers.cdl
In order to work ETH_DRV_SC-table-reference-functions,
if anything missing,please teach me.

cdl_package CYGPKG_DEVS_ETH_SH_INSERTER {

display "Inserter SMC91C96 ethernet driver"

   parent        CYGPKG_IO_ETH_DRIVERS
   active_if   CYGPKG_IO_ETH_DRIVERS
   active_if   CYGPKG_HAL_SH_SH77X9_inserter

   # chip wired in PCMCIA, 16-bit mode, no EEPROM
   implements    CYGHWR_NET_DRIVERS
   implements    CYGHWR_NET_DRIVER_ETH0
   implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED
   implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
   implements    CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA

   requires      CYGPKG_DEVS_ETH_SMSC_LAN91CXX
   description   "Ethernet driver for Inserter boards."

   include_dir   cyg/io
   compile       if_inserter.c

define_proc {
puts $::cdl_system_header "/***** ethernet driver proc output start *****/"
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL <cyg/io/devs_eth_inserter.inl>"
puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_SMSC_LAN91CXX_CFG <pkgconf/devs_eth_sh_inserter.h>"
puts $::cdl_system_header "/***** ethernet driver proc output end *****/"
}


   # Arguably this should do in the generic package
   # but then there is a logic loop so you can never enable it.

   cdl_interface CYGINT_DEVS_ETH_SMSC_LAN91CXX_REQUIRED {
       display   "SMSC LAN91CXX driver required"
   }

   cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_NAME {
       display       "Device name for the ethernet driver"
       flavor        data
       default_value {"\"eth0\""}
       description   "
           This option sets the name of the ethernet device for the
           ethernet port."
   }

   cdl_option CYGDAT_DEVS_ETH_SH_INSERTER_ESA {
       display       "The ethernet station address (MAC)"
       flavor        data
       default_value {"{0x00, 0x40, 0x31, 0x08, 0x01, 0x00}"}
       description   "A static ethernet station address.
           Caution: Booting two systems with the same MAC on the same
           network, will cause severe conflicts."
       active_if     !CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
   }

   cdl_option CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA {
       display "Use the RedBoot ESA (MAC address)"
       default_value 0
       flavor        bool
       description   "
           Use the ESA that is stored as a RedBoot variable instead of
           a static ESA."
   }

}
# EOF inserter_eth_drivers.cdl

Mashiro Ariga

-- my prev mail
In order to work ETH_DRV_SC-table-reference-functions,
should I add anything in CDL ?

If there is,
I would appreciate if you show me sample CDL.

Please help me.

Masahiro Ariga

-- my previous mail
I realized I should check Configuration conflicts.

When building "net" template,appeares 2 Resolve Conflicts windows.
I donnot know how much level auto-amendment system guarantees,
but I relied auto-amendment completely.

All-items tracking down is impossible because I consumed time enough.
If any one hits you as most suspecting,please let me know.

[First Resolve Conflicts window]
Resolve conflicts
CYGPKG_DEVS_FLASH_SH_inserter Requires CYGHWR_DEVS_FLASH_AMD_AM29LV160
CYGPKG_HAL_SH_SH77X9_inserter Requires CYGHWR_HAL_SH_IRQ_USE_IRQLVL
CYGPRI_HAL_SH_SH77X9_VARIANT_7709S Requires CYGPRI_HAL_SH_SH77X9_SUPERIO


Proposed Solutions:
CYGPRI_HAL_SH_SH77X9_SUPERIO           Enabled
CYGHWR_HAL_SH_IRQ_USE_IRQLVL        Enabled
CYGHWR_DEVS_FLASH_AMD_AM29LV160     Enabled

[Second Resolve Conflicts window]
CYGPKG_POSIX_CLOCKS Requires CYGBLD_ISO_STRUCTTIMEVAL_HEADER == "<cyg/posix/sys/time.h>"
CYGPKG_FILEIO_FNMATCH Requires CYGBLD_ISO_FNMATCH_HEADER == "<cyg/fileio/fnmatch.h>"


Proposed Solutions:
CYGBLD_ISO_FNMATCH_HEADER                 Enabled,<cyg/fileio/fnmatch.h>
CYGBLD_ISO_STRUCTTIMEVAL_HEADER     Enabled,<cyg/posix/sys/time.h>

Please help me.

Mashiro Ariga

-- my previous mail.
As I said,
My target uses SMSC LAN91C111 chip,CPU is SH7709S.
As ethernet interrupt,uses IRQ3 line.
I build "net" template,eCos source is updated by CVS checkout.

As I inserted LAN91C111's mask routine in the ISR,
I succeeded to entered into DSR.
(This interrupt was caused not by eCos-proper code, but by my tampered
routine.I will later explain.)
But although RCV-INT is assserted,delivering-packet routine never called,
so I entered repetedly ISR and DSR.
Then I discovered LAN91C111 driver's receive routine was never called.


Please forgive me long mail,but I try to
inform you as correctly as possible.
First I relate current problem,and later describe what I have tampered with.


I register SMSC interrupt ruoitne
in \packages\devs\eth\smsc\lan91cxx\current\src\if_lan91cxx.c's
smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
like this,
#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
// Initialize environment, setup interrupt handler
cyg_drv_interrupt_create(cpd->interrupt,
CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
(cyg_addrword_t)sc, // Data item passed to interrupt handler
(cyg_ISR_t *)lan91cxx_isr,
(cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR
&lan91cxx_interrupt_handle,
&lan91cxx_interrupt);
cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
cyg_drv_interrupt_acknowledge(cpd->interrupt);
cyg_drv_interrupt_unmask(cpd->interrupt);


And register LAN91C111 driver in my target's \packages\devs\eth\sh\inserter\current\include\devs_eth_inserter.inl.
I think this is important so I put on all content.
#include <pkgconf/system.h>
#include <pkgconf/devs_eth_sh_inserter.h>
#include <cyg/hal/hal_intr.h>


// MAC address is stored as a Redboot config option
#ifdef CYGPKG_REDBOOT
#include <pkgconf/redboot.h>
#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
#include <redboot.h>
#include <flash_config.h>

#define LAN91CXX_IS_LAN91C111

RedBoot_config_option("Network hardware address [MAC]",
                     inserter_esa,
                     ALWAYS_ENABLED, true,
                     CONFIG_ESA, 0
   );
#endif
#endif

// ESA address fetch function
static void inserter_get_ESA(struct lan91cxx_priv_data *cpd)
{
   // Fetch hardware address from RedBoot config
#if defined(CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA)
#if defined(CYGPKG_REDBOOT) && \
   defined(CYGSEM_REDBOOT_FLASH_CONFIG)
   flash_get_config("inserter_esa", cpd->enaddr, CONFIG_ESA);
#else
#error "No RedBoot flash configuration to store ESA"
#endif
#else
   unsigned char static_esa[] = CYGDAT_DEVS_ETH_SH_INSERTER_ESA;
   memcpy(cpd->enaddr, static_esa, 6);
#endif
}

static lan91cxx_priv_data lan91cxx_eth0_priv_data = {
   config_enaddr : inserter_get_ESA,
#ifndef CYGSEM_DEVS_ETH_SH_INSERTER_REDBOOT_ESA
   enaddr: CYGDAT_DEVS_ETH_SH_INSERTER_ESA,
   hardwired_esa : true,
#else
   hardwired_esa : false,
#endif

#if 0
  base : (unsigned short *) SA1110_FHH_ETH_IOBASE,
  attbase : (unsigned char *) SA1110_FHH_ETH_MMBASE,
  interrupt : SA1110_IRQ_GPIO_ETH
#else
  base : (unsigned short *) 0xa8000000,
  interrupt : 9,
#endif
};

ETH_DRV_SC(lan91cxx_sc,
          &lan91cxx_eth0_priv_data,          // Driver specific data
          CYGDAT_DEVS_ETH_SH_INSERTER_NAME, // Name for device
          lan91cxx_start,
          lan91cxx_stop,
          lan91cxx_control,
          lan91cxx_can_send,
          lan91cxx_send,
          lan91cxx_recv,
          lan91cxx_deliver,
          lan91cxx_poll,
          lan91cxx_int_vector
);

NETDEVTAB_ENTRY(lan91cxx_netdev,
               "lan91cxx_" CYGDAT_DEVS_ETH_SH_INSERTER_NAME,
               smsc_lan91cxx_init,
               &lan91cxx_sc);

//EOF devs_eth_inserter.inl

I found ETH_DRV_SC definition as below.
\packages\io\eth\current\include\eth_drv.h
#define ETH_DRV_SC(sc,priv,name,start,stop,control,can_send,send,recv,deliver,poll,int_vector) \
static void start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags); \
static void stop(struct eth_drv_sc *sc); \
static int control(struct eth_drv_sc *sc, unsigned long key, void *data, int data_length); \
static int can_send(struct eth_drv_sc *sc); \
static void send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
static void recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len); \
static void deliver(struct eth_drv_sc *sc); \
static void poll(struct eth_drv_sc *sc); \
static int int_vector(struct eth_drv_sc *sc); \
static struct eth_hwr_funs sc##_funs = { \
start, \
stop, \
control, \
can_send, \
send, \
recv, \
deliver, \
poll, \
int_vector, \
&eth_drv_funs, \
(struct eth_drv_funs *)0 }; \
struct eth_drv_sc sc = {&sc##_funs, priv, name};


I assume this is developed like below,
#define ETH_DRV_SC(lan91cxx_sc,&lan91cxx_eth0_priv_data,CYGDAT_DEVS_ETH_SH_INSERTER_NAME,lan91cxx_start,lan91cxx_stop,lan91cxx_control,lan91cxx_can_send,lan91cxx_send,lan91cxx_recv,lan91cxx_deliver,lan91cxx_poll,lan91cxx_int_vector) \
static void lan91cxx_start(struct eth_drv_sc *lan91cxx_sc, unsigned char *enaddr, int flags); \
static void lan91cxx_stop(struct eth_drv_sc *lan91cxx_sc); \
static int lan91cxx_control(struct eth_drv_sc *lan91cxx_sc, unsigned long key, void *data, int data_length); \
static int lan91cxx_can_send(struct eth_drv_sc *lan91cxx_sc); \
static void lan91cxx_send(struct eth_drv_sc *lan91cxx_sc, struct eth_drv_sg *sg_list, int sg_len, int total, unsigned long key); \
static void lan91cxx_recv(struct eth_drv_sc *lan91cxx_sc, struct eth_drv_sg *sg_list, int sg_len); \
static void lan91cxx_deliver(struct eth_drv_sc *lan91cxx_sc); \
static void lan91cxx_pollpoll(struct eth_drv_sc *lan91cxx_sc); \
static int lan91cxx_int_vector(struct eth_drv_sc *lan91cxx_sc); \
static struct eth_hwr_funs lan91cxx_sc_funs = { \
lan91cxx_start, \
lan91cxx_stop, \
lan91cxx_control, \
lan91cxx_can_send, \
lan91cxx_send, \
lan91cxx_recv, \
lan91cxx_deliver, \
lan91cxx_poll, \
lan91cxx_int_vector, \
&eth_drv_funs, \
(struct eth_drv_funs *)0 }; \
struct eth_drv_sc lan91cxx_sc = {&lan91cxx_sc_funs, &lan91cxx_eth0_priv_data, CYGDAT_DEVS_ETH_SH_INSERTER_NAME};


I assume lan91cxx_recv must be called to operate on packets,
but it was never called.

I traced DSR routine
DSR is this
\packages\io\eth\current\src\net\eth_drv.c
void
eth_drv_dsr(cyg_vector_t vector,
           cyg_ucount32 count,
           cyg_addrword_t data)
{
   struct eth_drv_sc *sc = (struct eth_drv_sc *)data;

#ifdef CYGDBG_USE_ASSERTS
// then check that this really is a "sc"
{
cyg_netdevtab_entry_t *t;
for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++)
if ( ((struct eth_drv_sc *)t->device_instance) == sc )
break; // found it
CYG_ASSERT( t != &__NETDEVTAB_END__, "eth_drv_dsr: Failed to find sc in NETDEVTAB" );
}
#endif // Checking code


sc->state |= ETH_DRV_NEEDS_DELIVERY;

ecos_synch_eth_drv_dsr(); // [request] run delivery function for this dev
}


And in \packages\net\bsd_tcpip\current\src\ecos\timeout.c
void ecos_synch_eth_drv_dsr(void)
{
   cyg_flag_setbits( &alarm_flag, 2 );
}

And in \packages\kernel\current\src\common\kapi.cxx
void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value) __THROW
{
((Cyg_Flag *)flag)->setbits( value );
}


And in \packages\kernel\current\src\sync\flag.cxx
void
Cyg_Flag::setbits( Cyg_FlagValue arg )
{
   CYG_REPORT_FUNCTION();
   CYG_ASSERTCLASS( this, "Bad this pointer");

   // Prevent preemption
   Cyg_Scheduler::lock();

   // OR in the argument to get a new flag value.
   value |= arg;

   // anyone waiting?
   if ( !(queue.empty()) ) {
       FlagWaitInfo   *p;
       Cyg_Thread     *thread;
       Cyg_ThreadQueue holding;

       do {
           thread = queue.dequeue();
           p = (FlagWaitInfo *)(thread->get_wait_info());

           CYG_ASSERT( (p->allmask == 0) != (p->anymask == 0),
                       "Both masks set" );
           CYG_ASSERT( 0 == p->value_out, "Thread already awoken?" );

if ( ((p->allmask != 0) && (p->allmask & value) == p->allmask) ||
((p->anymask & value) != 0 ) ) {
// success! awaken the thread
thread->set_wake_reason( Cyg_Thread::DONE );
thread->wake();
// return the successful value to it
p->value_out = value;
// do we clear the value; is this the end?
if ( p->do_clear ) {
// we can break here but need to preserve ordering
value = 0;
// so let it cycle the whole queue regardless
}
}
else {
// preserve the entry on the holding queue
holding.enqueue( thread );
}
} while ( !(queue.empty()) );


       // Now re-queue the unaffected threads back into the flag queue
       while ( !(holding.empty()) ) {
           queue.enqueue( holding.dequeue() );
       }
   }
   // Unlock scheduler and allow other threads to run
   Cyg_Scheduler::unlock();
   CYG_REPORT_RETURN();
}

Truely,I cannot fathom this coding and
I would appreciate if you kindly teach me how lan91cxx_recv is to be called.


Now I describe what I have tampered with in detail,please forgive me lengthy details.
The beginning of the matter is when I ran eCos as it is,I couldn't make LAN91C111 into LINK State,
LINK LED didn't light.So I inserted my own routine in order to operate LAN91C111 into LINK State in top of
\packages\io\eth\current\src\net\eth_drv.c's eth_drv_init function like below.
eth_drv_init(struct eth_drv_sc *sc, unsigned char *enaddr)
{
// this is my tampered coding
cyg_netdevtab_entry_t *t;


   struct ifnet *ifp = &sc->sc_arpcom.ac_if;
#ifdef CYGPKG_NET_FREEBSD_STACK
   int unit;
   char *np, *xp;
#endif

// this is my tampered coding
for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
log(LOG_INIT, "Init device '%s'\n", t->name);
if (smsc_91c111_init(t)) { // this is my concocted routine
t->status = CYG_NETDEVTAB_STATUS_AVAIL;
} else {
// What to do if device init fails?
t->status = 0; // Device not [currently] available
}
}


and in order making LAN91C111 into LINK State it was necessary to use interrupt so I enabled LAN91C111 interrupt in my concocted routine.
Above-mentioned interrupt was caused by my tampered code.At LINK-established time interrupt happened.


On second thought, I realized my tampering was wrong.
So I quitted my tampering routine, I returned to eCos original source and checked why couldn't make LINK LED lighed.
I discovered it never called lan91cxx routines(i.e. ETH_DRV_SC routines).


Below is RedBoot output messages log.
I breaked lan91cxx_start() but never entered it.
I made DEBUG_FUNCTION() available.
-- RedBoot output messages log
My Flash ID is 4:22f9:0:19
eth_drv_init:enaddr=0x8c0005c4
Ethernet eth0: MAC address 00:40:31:08:01:00
IP: 172.16.1.200/255.255.255.0, Gateway: 172.16.1.1
Default server: 172.16.1.1

RedBoot(tm) bootstrap and debug environment [ROM]
Non-certified release, version UNKNOWN - built 16:50:29, Sep 19 2007

Platform: inserter (SH 7709S)
Copyright (C) 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
Copyright (C) 2003, 2004, 2005, 2006 eCosCentric Limited

RAM: 0x8c000000-0x90000000, [0x8c00bed0-0x8ffed000] available
FLASH: 0xa0000000 - 0xa0400000, 64 blocks of 0x00010000 bytes each.
== Executing boot script in 3.000 seconds - enter ^C to abort
RedBoot> fis load -b 0x8c010000 nc_slave
RedBoot> channel 1
RedBoot> go 0x8c010000
Network stack using 69632 bytes for misc space
                   69632 bytes for mbufs
                   139264 bytes for mbuf clusters
[cyg_net_init] Init: mbinit(0x00000000)
[cyg_net_init] Init: cyg_net_init_devs(0x00000000)
Init device 'lan91cxx_eth0'
smsc_lan91cxx_init
LAN91CXX - supposed BankReg @ a800000e = 3302
LAN91CXX - type: 9, rev: 1
LAN91CXX - status: 0069
LAN91CXX - static ESA: 00:40:31:08:01:00
[cyg_net_init] Init: loopattach(0x00000000)
[cyg_net_init] Init: ifinit(0x00000000)
[cyg_net_init] Init: domaininit(0x00000000)
[cyg_net_init] Init: cyg_net_add_domain(0x8c05a7b4)
New domain internet at 0x00000000
[cyg_net_init] Init: cyg_net_add_domain(0x8c05a1f8)
New domain route at 0x00000000
[cyg_net_init] Init: call_route_init(0x00000000)
[cyg_net_init] Done
Start Network Characterization - SLAVE
No load = 58470
Set background load = 20%
Set background load = 0%
High Load[20] = 37131 => 37%
Set background load = 20%
Set background load = 0%
Load[10] = 47736 => 19%
Set background load = 20%
Set background load = 0%
Final load[10] = 47853 => 19%
Start test for eth0
-- end of RedBoot output messages log

All matters considered,I deduce that ETH_DRV_SC-table-reference-functions are not working.
I cannot understand where and how they are called.
Please teach me how to correctly call these functions.




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




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




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




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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]