This is the mail archive of the
ecos-discuss@sourceware.org
mailing list for the eCos project.
Re: LAN9218 driver porting problem
Hello,
Thank you, Gary, for your answer.
Honestly, I do not understand completely, but I anyhow made recved routines
as follows.
Do you think it works ?
Don't bother. I just want to thank you.
<lan9x18_RxEvent>
I can get used-space of STATUS_FIFO(=all DWORDs) & DATA_FIFO(=all recved
data length) from RX_FIFO_INF Register
so, I read both values and setted used-space of STATUS_FIFO into
cpd->rxpacket,
and used-space of DATA_FIFO into len.
<lan9x18_recv>
I get each packet-length from STATUS_FIFO and deployed all data into
sg_list[i].buf.
static void
lan9x18_RxEvent(struct eth_drv_sc *sc)
{
struct lan9x18_priv_data *cpd =
(struct lan9x18_priv_data *)sc->driver_private;
DWORD stat,len;
DEBUG_FUNCTION();
// get used space of STATUS_FIFO & DATA_FIFO from RX_FIFO_INF
stat=get_reg32(sc, RX_FIFO_INF); //RX_FIFO_INF (0x7CUL)
if(stat&0x00FF0000UL) { //RXSUSED!=0
cpd->rxpacket = ((stat&0x00FF0000UL)>>16); //RXSUSED set
len=stat&0x0000FFFFUL; //RXDUSED set
}
else{
#if DEBUG & 1
db_printf("#####RxEvent with empty fifo\n");
#endif
return;
}
INCR_STAT( rx_count );
#if DEBUG & 1
db_printf("RxEvent - STATUS_FIFOs: 0x%08x\n", stat);
#endif
get_data_init(sc);
//Rx status is available, read it
stat=get_reg32(sc, RX_STATUS_FIFO); //RX_STATUS_FIFO (0x40UL)
#ifdef KEEP_STATISTICS
// if ( stat & LAN9x18_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors );
//if ( stat & LAN9x18_RX_STATUS_BCAST ) INCR_STAT( );
if ( stat & 0x00000002 ) INCR_STAT( rx_crc_errors );
if ( stat & 0x00000008 ) INCR_STAT( rx_too_long_frames );
if ( stat & 0x00000800 ) INCR_STAT( rx_short_frames );
//if ( stat & LAN9x18_RX_STATUS_MCAST ) INCR_STAT( );
#endif // KEEP_STATISTICS
// Error check
// if ((stat & LAN9x18_RX_STATUS_BAD) == 0)
if ((stat & RX_STS_ES_) == 0) //RX_STS_ES_ (0x00008000UL)
{
INCR_STAT( rx_good );
// Then it's OK
#if DEBUG & 1
db_printf("RxEvent good rx - stat: 0x%08x, len: 0x%08x\n", stat,
len);
#endif
// Check for bogusly short packets; can happen in promisc mode:
// Asserted against and checked by upper layer driver.
#ifdef CYGPKG_NET
if ( len > sizeof( struct ether_header ) )
// then it is acceptable; offer the data to the network stack
#endif
(sc->funs->eth_drv->recv)(sc, len);
return;
}
// Not OK for one reason or another...
}
static void
lan9x18_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
{
struct lan9x18_priv_data *cpd =
(struct lan9x18_priv_data *)sc->driver_private;
int i;
// short mlen=0, plen;
cyg_uint8 *data=NULL;
short val;
unsigned char *cp, cval;
DWORD mlen=0,stat,plen=0;
DEBUG_FUNCTION();
INCR_STAT( rx_deliver );
get_data_init(sc);
for (i = 0; i < sg_len; ) {
int clen;
if(mlen==0){
data = (cyg_uint8 *)sg_list[i].buf;
mlen = sg_list[i].len;
}
if(plen==0){
//RX_STATUS_FIFO (0x40UL)
if((stat=get_reg32(sc, RX_STATUS_FIFO))==0){
#if DEBUG & 1
db_printf("RX_STATUS_FIFO empty\n");
#endif
goto DONE;
}
plen=((stat&0x3FFF0000UL)>>16);
cpd->data_pos=sizeof(rxd_t);
}
clen = mlen;
if( clen > plen )
clen = plen;
#if DEBUG & 1
db_printf("%s : mlen 0x%08x plen 0x%08x clen 0x%08x\n",
__FUNCTION__, mlen, plen, clen);
#endif
mlen -= clen;
plen -= clen;
if (data) {
while( clen > 0 ) {
*data++ = get_data_byte(sc);
clen--;
}
}
else { // must actively discard ie. read it from the chip anyway.
#if DEBUG & 1
db_printf("lan9x18_recv: No data!!!!!\n");
#endif
while( clen > 0 ) {
(void)get_data_byte(sc);
clen--;
}
}
#if DEBUG & 1
diag_dump_buf( sg_list[i].buf, sg_list[i].len > 64 ? 64 :
sg_list[i].len );
#endif
if(mlen==0)
i++;
}
DONE:
return;
}
Since hardware has not yet made,I can't run my program.
Until then I am just only crossing my fingers.
Thanks your help again.
m mariga
--
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss