some news about my TCP/IP problem
Stan
zylog at club-internet.fr
Mon Aug 23 10:19:40 UTC 2004
Hi,
Some weeks ago, I told you about a TCP/IP problem.
I found it :-)
I use the Davicom DM9000 and I have been writing the driver for this chip.
It can use the bus with byte, word or dword mode.
I use this chip with 16 bits as larger.
In Sendpacket function, we work with mbufs.
These mbufs can hold an odd number of bytes.
In my case, we must padding the dword.
I've forgetten that many mbufs can make only one ethernet packet.
Thus, in my case, if a mbuf is odd _and_ there is other mbuf after, I must
complete
the word with the first byte of the next mbuf.
So as to make it plain, this is my new function :
**************************************************************
void
sendpacket (struct ifnet *ifp, struct mbuf *m)
{
board_info_t *db = &Board_info;
struct mbuf *n, *input_m = m;
struct dm9000_softc *sc = ifp->if_softc;
struct mbuf *l = NULL;
unsigned int length = 0, tmplen, i;
rtems_status_code status;
int bd_count = 0;
rtems_event_set events;
rtems_unsigned16 *data16_ptr, val;
int len=0, slen=0;
rtems_interrupt_level level;
struct mbuf *mhold = m;
int leftover;
unsigned char leftover_data;
sc->txInterrupts++;
rtems_interrupt_disable (level);
iow(db, 0xff, 0x80); /* Disable interrupt mask */
rtems_interrupt_enable (level);
outb(0xf8, db->ioaddr);
len = m->m_pkthdr.len;
leftover = 0;
leftover_data = '\0';
for (; m != NULL; m = m->m_next) {
int len;
unsigned char *data;
len = m->m_len;
if (len == 0)
continue;
data = mtod (m, unsigned char *);
if (leftover) {
unsigned char next;
/* Data left over from previous mbuf in chain. */
next = *data++;
--len;
// outport_word (dport, leftover_data | (next << 8));
outw( leftover_data | (next << 8), db->io_data);
leftover = 0;
}
while (len > 1) {
//outport_word (dport, data[0] | (data[1] << 8));
outw( data[0] | (data[1] << 8), db->io_data);
data += 2;
len -= 2;
}
if (len > 0)
{
leftover = 1;
leftover_data = *data++;
}
}
if (leftover)
//outport_word (dport, leftover_data);
outw( leftover_data, db->io_data);
m_freem (mhold);
/* TX control: First packet immediately send, second packet queue */
/* First Packet */
if(db->tx_pkt_cnt == 0){ /* first packet */
db->tx_pkt_cnt++;
/* Set TX length to DM9000 */
iow(db, 0xfc, len & 0xff);
iow(db, 0xfd, (len >> 8) & 0xff);
/* Issue TX polling command */
iow(db, 0x2, 0x1); /* Cleared after TX complete */
/* Re-enable interrupt mask */
/*iow(db, 0xff, DM9000_REGFF);*/
}else{
/* Second packet */
db->tx_pkt_cnt++;
db->queue_pkt_len = len;
}
rtems_interrupt_disable (level);
iow(db, 0xff, DM9000_REGFF); /* Re-enable interrupt mask */
rtems_interrupt_enable (level);
/* sleep until the command has been processed or Timeout encountered. */
status= rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
&events);
if ( status != RTEMS_SUCCESSFUL ) {
/*printf("Could not sleep\n");*/
}
} /* sendpacket */
**************************************************************
Nevertheless, I thank you for your help.
Stan .
More information about the users
mailing list