Name
CYGPKG_DEVS_ETH_SMSC_LAN9118
— eCos Support for SMSC LAN9118 Ethernet Devices
Description
The SMSC LAN9118 chip is a high performance single chip ethernet controller which can be interfaced to a variety of embedded processors. This package provides an eCos driver for that device. The driver supports both polled mode for use by RedBoot and interrupt-driven mode for use by a full TCP/IP stack.
The exact interface between the LAN9118 chip and the main processor is determined by the platform HAL. On some platforms there may even be multiple LAN9118 chips. This package only provides the platform-independent code. It is up to the platform HAL to instantiate one or more device instances and to provide information such as the base address and interrupt vector. There is also no explicit support for features like auto-negotiation or advanced flow control. These are left to the platform HAL or to the application, although usually the default settings will be acceptable for most applications.
Configuration Options
This package should be loaded automatically when selecting a target
equipped with a LAN9118 ethernet chip. and it should never be
necessary to load it explicitly. If the application does not actually
require ethernet functionality then the package is inactive and the
final executable will not suffer any overheads from unused
functionality. This is determined by the presence of the generic
ethernet I/O package CYGPKG_IO_ETH_DRIVERS
.
Typically the choice of eCos template causes the right thing to
happen. For example the default template does not include any TCP/IP
stack so CYGPKG_IO_ETH_DRIVERS
is not included, but
both the net and redboot templates do include a TCP/IP stack so will
specify that package and hence enable the ethernet driver.
Optionally the ethernet driver can maintain statistics about the
number of incoming and transmitted ethernet frames, receive overruns,
collisions, and other conditions. Maintaining and providing these
statistics involves some overhead, and is controlled by the
configuration option
CYGFUN_DEVS_ETH_SMSC_LAN9118_STATISTICS
. Typically
these statistics are only accessed through SNMP, so by default
statistics gathering is enabled if the configuration includes
CYGPKG_SNMPAGENT
and disabled otherwise.
Porting the Driver to New Hardware
It is the responsibility of the platform HAL to instantiate one or more devices, depending on the number of LAN9118 chips present. Typically this involves a separate file in the platform HAL sources:
#include <cyg/io/lan9118.h> LAN9118_INSTANCE(alaia, 0, "eth0", alaia_eth_init); static bool alaia_eth_init(struct cyg_netdevtab_entry* tab) { … return cyg_lan9118_eth_init(tab); }
The first two arguments to the LAN9118_INSTANCE
macro identify the platform and the device instance, and are used to
construct unique variable names. The third argument gives the device
name, and the final argument is a platform-specific initialization
function. The platform HAL should also contain suitable CDL to build
this file:
cdl_component CYGHWR_HAL_ALAIA_ETH { display "External ethernet support" parent CYGPKG_IO_ETH_DRIVERS flavor none active_if CYGPKG_IO_ETH_DRIVERS implements CYGNUM_DEVS_ETH_SMSC_LAN9118_COUNT compile -library=libextras.a alaia_eth.c description " The Alaia board comes with a single LAN9118 ethernet device." cdl_option CYGNUM_HAL_ALAIA_ETH_ISR_PRIORITY { … } … }
If the configuration does not include the generic ethernet support
then this component will be inactive. Otherwise the file
alaia_eth.c
will get built into
libextras.a
, ensuring the device instance does
not get eliminated by linker garbage collection. The interface
CYGNUM_DEVS_ETH_SMSC_LAN9118_COUNT
should be
implemented once per LAN9118 chip. If additional configuration options
are needed, for example to control the MAC address or the interrupt
priority, then these can go inside the component.
The driver needs to know where to access the device. If there is a
single LAN9118 chip then the required information can be supplied via
#define
's in the plf_io.h
header:
#define HAL_LAN9118_BASE 0xBA000000 #define HAL_LAN9118_ISRVEC CYGNUM_HAL_ISR_LAN9118 #define HAL_LAN9118_ISRPRI CYGNUM_HAL_ALAIA_ETH_ISR_PRIORITY
Otherwise the platform-specific initialization function should put this information in fields in the LAN9118 instance structure:
static bool alaia_eth_init(struct cyg_netdevtab_entry* tab) { LAN9118_INSTANCE_NAME(alaia, 0).lan9118_base = 0xBA000000; LAN9118_INSTANCE_NAME(alaia, 0).lan9118_isrvec = CYGNUM_HAL_ISR_PIO4; LAN9118_INSTANCE_NAME(alaia, 0).lan9118_isrpri = 1; LAN9118_INSTANCE_NAME(alaia, 1).lan9118_base = 0xBB000000; LAN9118_INSTANCE_NAME(alaia, 1).lan9118_isrvec = CYGNUM_HAL_ISR_PIO5; LAN9118_INSTANCE_NAME(alaia, 1).lan9118_isrpri = 1; … return cyg_lan9118_eth_init(tab); }
The initialization function should ensure that the processor's bus
interface is set up correctly for talking to the ethernet chip, and
that the interrupt vector has been configured correctly for level vs.
edge interrupts. This must happen before calling the driver init
function. Also the lan9118_hw_flags
should
be set correctly as per the flags in lan9118.h
, for example:
static bool alaia_eth_init(struct cyg_netdevtab_entry* tab) { … LAN9118_INSTANCE_NAME(alaia, 0).lan9118_hw_flags = (LAN9118_HW_FLAGS_IRQ_POL_ACTIVE_HIGH | LAN9118_HW_FLAGS_IRQ_PUSH_PULL | LAN9118_HW_FLAGS_HAS_LED1 | LAN9118_HW_FLAGS_HAS_LED2); … return cyg_lan9118_eth_init(tab); }
The LAN9118 can be accessed via either a 16-bit or 32-bit bus, and
from big-endian or little-endian processors. This gives a number of
combinations. The chip is inherently little-endian, so on a
little-endian processor there should be no problems. On a big-endian
processor there are two possibilities. If the LAN9118 is interfaced in
the obvious way then it will be necessary to swap the data of all
incoming and outgoing packets, which imposes a significant performance
penalty. On a 16-bit bus the
LAN9118_HW_FLAGS_16BIT_BE
flag should be set.
Alternatively the bytes on the bus can be swapped, either by the
hardware or by programming the processor's bus interface. This means
no swapping is needed for data, but all accesses to the LAN9118's
command and status registers need swapping instead. However most of
that swapping can be done at compile-time so has no overhead. Defining
HAL_LAN9118_SWAP_COMMANDS
in plf_io.h
sets up this mode. If there are
multiple ethernet chips then the driver assumes they are all wired the
same way. For further details consult the driver's source code.
All ethernet devices require a unique MAC address. Ideally this will
be provided by a serial EEPROM or similar, and if such a device is
present and attached to the LAN9118 then it will be used automatically
by the ethernet chip to set the MAC address. If the platform does not
have a suitable EEPROM then the MAC address must come from elsewhere,
for example a RedBoot fconfig option, and the platform-specific
initialization function should fill in the instance's
lan9118_mac
field.
2024-03-18 | eCosPro Non-Commercial Public License |