📄 readme.txt
字号:
unload the driver on the target with
ifconfig eth1 down
rmmod smsc9118
goto STEP 10 and use a different value for PC
STEP 12:
Apply the parameters to the appropriate location, given the
configuration choosen in step 1, in Platform_GetFlowControlParameters.
PacketCost= (PC from step 10/11);
BurstPeriod= (BP from step 8/9);
recompile driver.
Now the values you applied will be the default values used when that
same configuration is used again.
Goto STEP 1 and choose a configuration you have not yet tuned.
###########################################################
################### TESTED PLATFORMS ######################
###########################################################
This driver has been tested on the following platforms.
The driver was loaded as a module with the following command
line.
insmod smsc9118.o
===========================================================
Platform:
SH3 SE01
Motherboard:
Hitachi/Renesas, MS7727SE01/02
SMSC LAN9118 Board:
LAN9118 FPGA DEV BOARD, ASSY 6337 REV A
LAN9118:
LAN9118
Linux Kernel Version:
2.4.18
Driver Resources:
LAN_BASE=0xB4000000
IRQ=8
===========================================================
Platform:
XSCALE
Motherboard:
Intel Corp, MAINSTONE II MAIN BOARD REV 2.1
SMSC LAN9118 Board:
LAN9118 XSCALE FPGA DEV BOARD, ASSY 6343 REV A
LAN9118:
LAN9118
Linux Kernel Version:
2.4.21
Driver Resources:
LAN_BASE=0xF2000000
IRQ=198
###########################################################
##################### RX CODE PATH ########################
###########################################################
The purpose of this section is to describe how the driver
receives packets out of the LAN9118 and passes them to the
Linux OS. Most functions in the Rx code path start with Rx_
During initialization (Smsc9118_open) the function
Rx_Initialize is called. This call enables interrupts for
receiving packets.
When a packet is received the LAN9118 signals an interrupt,
which causes Smsc9118_ISR to be called. The Smsc9118_ISR function
is the main ISR which passes control to various handler routines.
One such handler routine that gets called is Rx_HandleInterrupt.
Rx_HandleInterrupt first checks to make sure the proper
interrupt has been signaled (INT_STS_RSFL_). If it has not
it returns immediately. If it has been signaled then it decides
if it should use PIO or DMA to read the data.
In both cases the process is like this
An Rx status DWORD is read using Rx_PopRxStatus
If there is an error
the packet is purged from the LAN9118
data fifo with Rx_FastForward
If there is no error
an sk_buff is allocated to receive the data
The data is read into the sk_buff using PIO or DMA.
After data is read the sk_buff is sent to linux using
Rx_HandOffSkb
The process continues until Rx_PopRxStatus returns 0
DMA is a little more complicated than PIO because it is written
to take advantage of concurrent processing. To get as much useful
work done as possible while a DMA operation is in progress.
Therefor DMA has the best performance boost when there are
several packets to service on a single call to Rx_HandleInterrupt
This is the purpose of the INT_DEAS field of INT_CFG. When that
field is set (using the driver parameter int_deas or platform macro
PLATFORM_INT_DEAS) it forces interrupts to be paced, so more packets
can arrive before a single call to the ISR.
The LAN9118 has been proven to receive at about 94Mbps on the
xscale platform. However other platforms run slower and require
some means of flow control. Rx flow control is built into the
LAN9118. It is configured by writing the AFC_CFG register. The
user can set this value at load time using the afc_cfg parameter.
Basically it works like this. If the Rx Data fifo fills up to
a level specified by AFC_HI in AFC_CFG then the LAN9118 will begin
flow control. If the link is half duplex then the LAN9118 will
exert back pressure by forcing a collision on the wire when a
packet is arriving. This will cause the sender to retransmit later.
If the link is full duplex then the LAN9118 will transmit a Pause
frame requesting the partner to stop sending packets. Then when
the Rx Data fifo drops to AFC_LO in AFC_CFG then the LAN9118 will
stop exerting back pressure in half duplex, or in full duplex it
will transmit another pause frame that lets the partner know it
can start sending packets again. See the LAN9118 specification
for more information. But all of this is done with out the help
of the driver.
Still the driver must participate in Rx flow control because of
platform speed limitations. Rx flow control in the driver is handled
in the functions Rx_HandOffSkb, and Rx_PopRxStatus. The function
Rx_HandOffSkb calls netif_rx which returns a congestion level.
If any congestion is detected then Rx_HandOffSkb will set the
RxCongested flag. The next time the driver calls Rx_PopRxStatus it
will see the RxCongested flag is set and will not Pop a new status
off the RX_STATUS_FIFO, but rather it will disable and re-enable
interrupts. This action will cause the interrupt deassertion interval
to begin. The ISR will return, and not be called again until the
deassertion interval has expired. This gives CPU time to linux so it
can handle the packets that have been sent to it and lower the
congestion level. In this case the driver voluntarily stops
servicing packets, which means the RX Data Fifo will fill up.
Eventually the hardware flow control will start up to slow down the
sender. Many times this will still result in an overflow of the
Rx Data fifo and packets will be lost under heavy traffic conditions.
But if the driver did not release the CPU to linux, then linux would
drop almost all the packets. So it is better to let the packets be
lost on the wire, rather than over consuming resources to service
them.
###########################################################
##################### TX CODE PATH ########################
###########################################################
When Linux wants to transmit a packet it will call
Smsc9118_hard_start_xmit. This function performs some checks
then calles Tx_SendSkb to send the packet.
Tx_SendSkb works with PIO or DMA depending on the selected
mode.
The basic sequence is this.
First Write TxCmdA and TxCmdB into the TX_DATA_FIFO.
Then Write the packet data into the TX_DATA_FIFO with
adjustments for offset and end alignment.
Then free the skb using dev_kfree_skb
DMA is a little more complicated than PIO because it is written
to take advantage of concurrent processing. To get as much useful
work done as possible while a DMA operation is in progress.
Therefor DMA has the best performance boost when there are
a burst of large packets to transmit.
Tx Flow control works like this.
If the free space in the TX_DATA_FIFO after writing the data
is determined to be less than about the size of one full size
packet then the driver can't be sure it can transmit the next
packet without overflowing. Therefor the driver turns off the
Tx queue by calling Tx_StopQueue. Then it prepares an interrupt
to be signaled when the free space in the TX_DATA_FIFO has risen
to an acceptable level. When that level of free space has been
reached the interrupt is signaled and the handler will turn on
the Tx queue by calling Tx_WakeQueue
Statistic counters are updated after about every 30 packets or
when linux calls Smsc9118_get_stats
###########################################################
########## PLATFORM INTERFACE DESCRIPTIONS ################
###########################################################
The platform interface provides a platform independent
interface for the driver (smsc9118.c) This interface
simplifies the task of porting the driver to other platforms.
All functions that start with Platform_ are part of the
platform interface. All macros that start with PLATFORM_
are part of the platform interface.
Below are descriptions of PLATFORM_ macros.
for examples of usage see sh3.h, xscale.h or peaks.h
PLATFORM_CACHE_LINE_BYTES
This macro is set to the size of a cache line in bytes.
It is used with dma operations to insure cache line
alignment which generally improves dma efficiency
It is also used to insure that the IP header of received
packets will be aligned on a cache line boundary
PLATFORM_IRQ_POL
This macro is set to 0 or 1 and indicates the default
value the driver will use when setting the IRQ_POL bit
of the INT_CFG register. The user can override this
value at load time by setting the driver parameter irq_pol.
PLATFORM_IRQ_TYPE
This macro is set to 0 or 1 and indicates the default
value the driver will use when setting the IRQ_TYPE bit
of the INT_CFG register. The user can override this
value at load time by setting the driver parameter irq_type.
PLATFORM_IRQ
This macro indicates the default irq the driver will
use when requesting an ISR.
The user can override this value at load time by setting
the driver parameter irq.
PLATFORM_RX_DMA
This macro indicates the default dma channel to use for
receiving packets. It may also be set to the following
macros
TRANSFER_PIO = 256
the driver will not use dma. It will use PIO.
TRANSFER_REQUEST_DMA = 255
the driver will call the Platform_RequestDmaChannel
to get an available dma channel
The user can override this value at load time by setting
the driver parameter rx_dma.
PLATFORM_TX_DMA
This macro indicates the default dma channel to use for
transmitting packets. It may also be set to the following
macros
TRANSFER_PIO = 256
the driver will not use dma. It will use PIO.
TRANSFER_REQUEST_DMA = 255
the driver will call the Platform_RequestDmaChannel
to get an available dma channel
The user can override this value at load time by setting
the driver parameter
PLATFORM_DMA_THRESHOLD
This macro indicates the default value for dma_threshold.
This value specifies the minimum size a packet must be
for using DMA. Otherwise the driver will use PIO. For small
packets PIO may be faster than DMA because DMA requires a
certain amount of set up time where as PIO can start almost
immediately. Setting this value to 0 means dma will always
be used where dma has been enabled.
The platform specific header files (sh3.h, and xscale.h)
must also define the platform specific data structure
PLATFORM_DATA, and its pointer PPLATFORM_DATA.
this structure is passed to most Platform_ functions. It
allows the platform layer to maintain its own context information.
The following are descriptions of the Platform_ functions
for examples of usage see the files sh3.c, or xscale.c
/************************************************************
FUNCTION: Platform_Initialize
PARAMETERS:
platformData, pointer to platform specified data structure
dwLanBase, user specified physical base address for the LAN9118
= 0, let this function decide
dwBusWidth,
= 16, user specifies 16 bit mode operation, bypass autodetection
= 32, user specifies 32 bit mode operation, bypass autodetection
= any other value, driver should auto detect bus width
DESCRIPTION:
This is the first Platform_xxx function that will be called
This function will initialize the PLATFORM_DATA structure.
This function will prepare the system to access the LAN9118.
It will properly initialize the bus and return the virtual
memory location where the LAN9118 can be access.
RETURN VALUE:
0 = failed,
any other value is the virtual base address where the LAN9118
can be accessed
************************************************************/
DWORD Platform_Initialize(
PPLATFORM_DATA platformData,
DWORD dwLanBase,
DWORD dwBusWidth);
/***********************************************************
FUNCTION: Platform_CleanUp
PARAMETERS:
platformData, pointer to platform specified data structure
DESCRIPTION:
This function is called so the platform layer can clean up
any resources that may have been acquired in Platform_Initialize.
If Platform_Initialize returned 0, then this function will
not be called.
***********************************************************/
void Platform_CleanUp(
PPLATFORM_DATA platformData);
/************************************************************
FUNCTION: Platform_SetRegDW
PARAMETERS:
DWORD dwLanBase, the virtual base address returned by
Platform_Initialize
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -