This page is intended to
provide general guidelines about NDK device drivers' source code
and highlight specific points necessary to adapt it to custom
EMAC/PHY combinations.
Introduction
Since the beginning, NDK was
designed to abstract the environment by using two layers of
software that require minimum changes depending on the OS and the
hardware used. These layers are the Operating System Abstraction
Layer () and the Hardware
Abstraction Layer (all the libraries of type
).
Typically no changes are required
to the OSAL, which runs on top of DSP/BIOS. However, the HAL is a
source of frequent questions asking to port to specific hardware
configurations or different PHYs. Since it is impossible to foresee
all the custom hardware implementations or PHY devices available on
the marketplace today, the source code for the drivers is available
with the NDK distributions since release 1.92.
In addition to the source code
availability, the great number of source files in a typical NDK
project are usually confusing for anyone that is trying to make
modifications to adapt for custom hardware.
Therefore the information below is
given to help pinpoint the places where device drivers' code should
be carefully examined and modified. Note that several of the PHY
manufacturers do not open detailed datasheets or configuration
information unless under a non-disclosure agreement, therefore any
changes are of entire responsibility of the customer.
Useful
information
For NDK 1.9x releases, each
Network Support Package (NSP) contains a design document for the
Ethernet device driver that covers the basic architecture and file
organization. These files are usually installed under
%NDK_INSTALL_DIR%packagestindkdocs
For NDK 2.00, the NSP Ethernet
Driver Design Guide (SPRUFP2)
contains the information for all the device drivers and is
typically installed under
%NDK_INSTALL_DIR%packagestindkdocsstack
The NDK Programmer's Guide for NDK
1.94 and 2.00 contains additional information in the sections A.14
(for NDK 1.94) and A.15 (for NDK 2.00).
Note: The information in
these two last references can also be applied to the NSPs for C6455
and DM642 running with NDK 1.94.
Due to performance and added
features, it is highly recommended to use the NIMU driver
architecture consolidated in NDK release 2.00. Please note that
there are also several driver-stack API changes that render it
backward incompatible with previous versions.
Tips to modify device
drivers
llPacket
The llPacket source code location
varies depending on the installation but is typically located at
%NDK_INSTALL_DIR%packagestindksrchal
1) Hardware Independent Low-Level
Ethernet Driver. This layer is provided in the file named
and does not require
changes to adapt to different PHYs.
2) Hardware Specific Low-Level
Ethernet (mini) Driver. As the name says, this layer contains the
hardware dependent information and changes should be done to
specific files.
The EMAC configuration files may
require just minimal changes (if any), since they mostly change
EMAC-only settings. Some examples of these files are
,
,
,
The MDIO configuration files need
to be carefully inspected and modified, since they perform the
functions of PHY initialization, configuration
(MDIO_initPHY() or cpsw_MDIO_Init() functions)
and polling (MDIO_timerTick() or cpsw_MDIO_Tic()
functions). Some examples of these files are:
,
<64lcmdio.c> and
For example, the code below
starting at line 582 of the file
might have to be
modified to properly initialize a different PHY:
if ( macsel == CSL_DEV_DEVSTAT_MACSEL_RGMII )
{
//Put phy in copper mode
PHYREG_write( PHYREG_ACCESS, phyAddr, PHYREG_ACCESS_COPPER );
PHYREG_waitResultsAck( i, ack );if( !ack )
return(0);
PHYREG_write( 0x10, phyAddr, 0x0000 ); //GMII Interface
PHYREG_wait();
// Put phy in RGMII mode/in-band status data for PG 2.0
if (EMAC_REGS->TXIDVER != 0x000C1207) {
PHYREG_write(PHYREG_SHADOW, phyAddr, PHYREG_SHADOW_INBAND);
PHYREG_waitResultsAck( i, ack );
if( !ack )
return(0);
}
}
3) The hardware initialization
file in each example project. These files contain functions called
before main() and read or configure some initial
parameters for the hardware. These files are usually located in the
example project directories. For example, at the end of the file
the code below may
have to be modified:
void C6455EMAC_linkStatus( uint phy, uint linkStatus )
{
Uint16 pData;
printf("Link Status: %s on PHY %dn",LinkStr[linkStatus],phy);
MDIO_phyRegRead( phy, 0x2, &pData );
// Program the LEDs for the Intel phy
if (pData ==0x13)
MDIO_phyRegWrite( phy, 0x14, 0xd5d0 );
// Program the LEDs for the Broadcom phy
if (pData ==0x20)
MDIO_phyRegWrite( phy, 0x1C, 0xa418 );
}
NIMU
The NIMU source drivers are
usually located in the directory
%NDK_INSTALL_DIR%packagestindksrchaleth_
1) Layer 1 – NDK stack interaction
layer (NIMU layer). Since it encapsulates all interactions between
the stack and the NIMU layer, it has no PHY or hardware dependency.
Please check section 2.2 of the NSP Ethernet Design Guide above.
Typically the usage example of this layer is shown in the file
2) Layer 2 – Ethernet mini-driver
layer. This layer configures the EMAC using the data structures
exposed by underlying CSL layers data structures and APIs. Despite
directly communicating with the hardware (cache, interrupts, etc)
its code is mostly contained into the DSP itself, thus requiring
minor (if any) changes to accomodate a different PHY. This layer is
usually shown in the file
. For example, check the
code below starting at line 401 of the file
for C6455; if the use
of Jumbo Frames is desired but the PHY supports a MTU value smaller
than 10200 bytes, an adjustment is required to the value of
ecfg.PktMTU.
#ifndef _INCLUDE_JUMBOFRAME_SUPPORT
ecfg.PktMTU = 1514;
#else
ecfg.PktMTU = 10200;
#endif
3) Layer 3 – CSL EMAC / MDIO
layer. External hardware dependent layer. Defines data structures
and APIs required to configure and control the EMAC and PHY.
Changes to this layer can be split in two categories:
CSL EMAC configuration. Despite
the fact that CSL itself directly interacts with the hardware, very
little is needed to be changed to the EMAC configuration file since
it is tailored for the DSP. Such configuration is usually located
in the file named
.
CSL MDIO configuration. Similarly
to the MDIO configuration files for llPacket interface, the code
requires careful inspection and modification to match the PHY - the
names of the functions also match the ones listed for llPacket MDIO
configuration. Such configuration is performed by the file
For example, the code below
starting at line 618 of the file
might require
modifications to be adjusted to a different PHY.
if ( macsel == RGMII )
{
PHYREG_write( PHYREG_ACCESS, phyAddr, PHYREG_ACCESS_COPPER );
PHYREG_waitResultsAck( i, ack );
if( !ack )
return(0);
PHYREG_write( 0x10, phyAddr, 0x0000 ); //GMII Interface
PHYREG_wait();
// Put phy in RGMII mode/in-band status data
if (EMAC_REGS->TXIDVER != 0x000C1207) {
PHYREG_write(PHYREG_SHADOW, phyAddr, PHYREG_SHADOW_INBAND);
PHYREG_waitResultsAck( i, ack );
}
// If the PHY did not ACK the write, return zero
if( !ack )
return(0);
#if 0
// Override gtxcdly so it's low - it's still needed on EVM
PHYREG_write( PHYREG_ACCESS, phyAddr, 0x8C00 );
PHYREG_waitResultsAck( i, ack );
// If the PHY did not ACK the write, return zero
if( !ack )
return(0);
#endif
}
4) At last, verify the hardware
initialization files in each example project. Its names, locations
and functionality are identical as shown in the llPacket interface
above.
Emac
layer
C647x specific: verify the phy
setup in comparison with the NDK evm configuration. On the on the
6474 evm the connection between the phy and the device has a
polarity setting which is specific for a hw workaround.
When using your own board,
assuming you connected the phy properly, you will likely have to
rebuild the ethernet driver which is generating the
library
NDK_2_0libhalevm6474hal_eth_c6474.lib
Basically you will need to edit the
file NDK_2_0srchalevm6474eth_c6474ethdriver.c at line 601 to
make sure you specify the correct polarity for the SGMII connection
between the device and the PHY
the value to be edited / checked
is:
SgmiiCfg.txConfig = 0x00000ea1;
for the actual meaning of the bit
fields, refer to the emac user guide of the device
For technical support please post
your questions at http://e2e.ti.com. Please post only comments about the article
Guidelines when porting NDK to different PHYs
here.