SMSC LAN1198 User Manual

Page of 45
LAN9118 Family Programmer Reference Guide
Revision 1.0 (12-14-09)
28
SMSC AN 12.12
APPLICATION NOTE
 
Last Segment is also a 1-bit field, marking the data transfer as the end of a single packet.
To better understand the use of these last two fields, let’s discuss two popular operating systems
that utilize different packet allocation schemes.  Under Linux, system kernel buffers (skb’s) are used
to hold packet data and almost always contain enough space for the largest possible packet size
(1514 bytes) as an optimization of time-of-allocation.  For sending a packet in a single data buffer
transfer operation, these two fields (First SegmentLast Segment) would both be set.
FreeBSD on the other hand uses an mbuf (64-byte memory management buffers) packet allocation
scheme to economize memory allocation space by chaining together only as much mbuf memory
as needed to contain a given packet.  Each mbuf typically holds the header from a single layer
(MAC, IP, UDP, or RTP).  Under this scheme each mbuf could be dealt with as an individual data
transfer, and the head link in the chain would have the First Segment flag set in its command
word, while the tail link would have Last Segment set.  Intervening mbufs will have neither flag
set (see TX Buffer Fragmentation Rules in the datasheet for more detail).
Buffer Size is an 11-bit field specifying the number of data bytes in the current data transfer not
including the two command words.
Interrupt on Completion causes TX_DONE to be asserted after the current data transfer has
completed.  This is useful and important for chained DMA transfer operations.
The TX_CMD_B command word contains 2 major and 2 minor fields of concern:
1. Packet Tag is a 16-bit field which contains a unique ID which can be read back from the TX Status
word after the packet has been sent.  This field is examined by the device only to the extent that
in a chained packet transfer where all transfers relate to a single packet, all tags must be identical,
but beyond that, the tag may be used for a variety of purposes by the driver writer, such as tracking
the chains, or keeping byte count statistics.
2. Packet Length contains the overall number of bytes in the current packet.  Note the distinction to
the Buffer Size field in TX_CMD_A.  All links in an mbuf scheme will contain an identical value in
this field.
„
Add CRC Disable disables the automatic appending of CRC to the packet.
„
Disable Ethernet Frame Padding prevents the automatic padding of the packet when the overall 
packet length is less than 64 bytes (IEEE 802.3).  A side affect is that CRC is always added, 
despite the setting of ADD CRC Disable.
6.3   Per Packet Flow Control
To regulate data transfers on a per-packet basis, a driver needs to track the space remaining in the
TX_FIFO for subsequent transmit packets (flow design works better if the packets which the device is
currently transmitting do not have to be stalled).  This can be obtained by reading the TX Data FIFO
Free Space
 field (TDFREE) of the Transmit FIFO Information register (TX_FIFO_INF).    Note  that
TDFREE is read in bytes and represents the free space in the TX Data FIFO.  The device offers the
driver writer a variety of techniques to synchronize the application with the device having enough free
space to accommodate a packet transfer.  One method of handling the situation where there is not
enough free space to accommodate the current packet transfer is for the driver to enable the device
to interrupt when the free space exceeds a threshold level specified by the FIFO_INT:TX Data
Available Level
 field, and enabling the INT_EN:TDFA_INT_EN bit.  Alternately a scheme could be
constructed using the INT_EN:TSFL_INT_EN interrupt which signals a level change in the  TXUSED
count.  In this scheme the driver would track the number of TX_FIFO bytes freed up simply by
summing the bytes used in packets completed, and deciding the appropriate moment to re-enable the
transmit packet flow.  Use of the FIFO interrupt schemes is encouraged, as it helps eliminate register
sharing between transmit and receive threads.