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