[ECOS] LAN9218 driver porting problem

m mariga ma_ariga@yahoo.co.jp
Sun Feb 14 05:16:00 GMT 2010


Hello,

Thank you,Gary,for your reply.
But I am sorry I sill am not clear.
I cannot get clear relations between cpd->rxpacket,len,and sg_len.What 
determines sg_len ?

>From your reply I infered.
When I calls (sc->funs->eth_drv->recv)(sc, len) in lan91cxx_RxEvent(),
len determins sg_len. Is that so ? (Question remains why sg_len=2?)

If len determins sg_len, then question arises.
LAN91C111 calculate len of ONE block of DATA_FIFO,
but as I said in LAN9218,when entered xxxx_RxEvent(),there are possibilities 
that several data in RX_Status_FIFO had been written that means recv_Data 
are several blocks in RX_Data_FIFO.
In that case how I caluculate len ? Do I sum len all blocks ?

Allow me to quote your flow.
>  Device generates interrupt
>    lan91cxx_RxEvent() runs, determines how many bytes are in the packet
-----------------------------------------------
    here,if several data in RX_Status_FIFO had been written,should I sum len 
all blocks,
    and hand it to (sc->funs->eth_drv->recv) ? What value should I set 
cpd->rxpacket ?
-----------------------------------------------
>       (sc->funs->eth_drv->recv)(sc, len) tells the network layer
>  ... time passes - maybe a lot of time - until the network input
>      thread has time/space to read the packet
>    lan91cxx_recv() is called from the network input thread
>      for each element in 'sg' (based on 'sg_len'), move the next
>        sg[n].len bytes from the device buffer into sg[n].buf
-----------------------------------------------
    here,how should I gather recv_Data into sg[n].buf ?
    Isn't there no mismatch among hardware RX_Status_FIFO written counts and 
sg_len ?
    Could I rely on only sg_len ?
-----------------------------------------------

I appreciate your help.

m mariga

> On 02/12/2010 06:10 PM, m mariga wrote:
>> Hello,
>>
>> In danger of calling off using eCos,
>> again I implore you to lend me your knowledge.
>> I am still studying your LAN91c111 driver.
>> I am stuck in fatham of it. Please help me.
>>
>> I tried to dump cpd->rxpacket,len,sg_len variables in 
>> lan91cxx_RxEvent,and sg_len in lan91cxx_recv like below.
>> And run nc_test_slave() test program. The result dropped me deeper into 
>> the fatham.
>>
>> lan91cxx_RxEvent(struct eth_drv_sc *sc)
>> {
>> |
>> stat = get_reg(sc, LAN91CXX_FIFO_PORTS);
>> // There is an Rx Packet ready
>> cpd->rxpacket = 0xff & (stat >> 8);
>> diag_printf("rxpacket=%x\n",cpd->rxpacket);
>> |
>> stat = get_data_short(sc);
>> len = get_data_short(sc);
>> len = len - 6; // minus header/footer words
>> diag_printf("len=%x\n",len);
>> (sc->funs->eth_drv->recv)(sc, len);
>> }
>>
>> lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int 
>> sg_len)
>> {
>> |
>> diag_printf("sg_len=%x\n",sg_len);
>> }
>>
>> Here is part of the result.
>> ---
>> connection from 172.16.1.28.1226
>> rxpacket=0
>> len=5ea
>> sg_len=2
>> rxpacket=1
>> len=5ea
>> sg_len=2
>> rxpacket=2
>> len=5ea
>> sg_len=2
>> rxpacket=0
>> len=5ea
>> sg_len=2
>> rxpacket=1
>> len=5ea
>> sg_len=2
>> rxpacket=2
>> len=5a
>> sg_len=2
>> rxpacket=1
>> len=3c
>> sg_len=2
>> rxpacket=1
>> len=3c
>> sg_len=2
>> rxpacket=1
>> len=3c
>> sg_len=2
>> rxpacket=0
>> len=3c
>> sg_len=2
>> rxpacket=1
>> len=5ea
>> sg_len=2
>> rxpacket=0
>> len=5ea
>> sg_len=2
>> rxpacket=2
>> len=5ea
>> sg_len=2
>> rxpacket=3
>> len=5ea
>> sg_len=2
>> rxpacket=1
>> len=5a
>> sg_len=2
>> rxpacket=0
>> len=5ea
>> sg_len=2
>> rxpacket=0
>> len=5ea
>> sg_len=2
>> rxpacket=1
>> len=5ea
>> sg_len=2
>> ---
>>
>> My question is,why sg_len is always 2 in spite of len being different.
>> I know it is too difficult for me to understand your Scatter-Gather or 
>> something,but I need to make it work with LAN9218.
>>
>> Your LAN91c111 recv routine uses sg_len in whle loop and gather data into 
>> sg_list from DATA_FIFO.
>>
>> LAN9118/9218 has RX_Status_FIFO,RX_Data_FIFO seperately. RX_Status_FIFO 
>> tells packet length.
>> We know packet number from calculating data count written in 
>> RX_Status_FIFO.
>> I consulted LAN9118 SMSC Linux sample driver.
>> Its recv routine is much easier to understand.
>> Its operation like below.
>>
>> ------------> |
>> | <While RX_Status_FIFO!=0>
>> | |
>> | alloc new packet to skb
>> | //update counters
>> | privateData->stats.rx_packets++;
>> | |
>> | copy data into new skb packet from RX_Data_FIFO
>> | |
>> --------------
>>
>> I rather I would prefer to this, instead of using enigmatic sg_len to 
>> receive data from FIFO.
>> In xxx_recv routine,if I ignored sg_len and I coded like SMSC Sample(of 
>> course I use sg_list[i].buf instead of skb),do you think will it work 
>> properly(or permissably) ?
>> What if there are mismatches between sg_len and data counts written in 
>> RX_Status_FIFO ?
>> Please enlighten me.
>
> The parameter 'sg_len' indicates how many elements are present
> in the sg_list 'sg'.  Looking at 'sg', you'll see that it's
> and array of scatter gather elements which look like this:
>  struct eth_drv_sg {
>      CYG_ADDRESS  buf;
>      CYG_ADDRWORD len;
>  };
>
> What your function lan91cxx_recv() should do is to move the
> data from the device, utilizing the sg list structure.  The
> higher level network code allocates this based on the callback
> from your lan91cxx_RxEvent() function.
>
> To be clear, here's the flow:
>
>  Device generates interrupt
>    lan91cxx_RxEvent() runs, determines how many bytes are in the packet
>       (sc->funs->eth_drv->recv)(sc, len) tells the network layer
>  ... time passes - maybe a lot of time - until the network input
>      thread has time/space to read the packet
>    lan91cxx_recv() is called from the network input thread
>      for each element in 'sg' (based on 'sg_len'), move the next
>        sg[n].len bytes from the device buffer into sg[n].buf
>
> -- 


-- 
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