iMX28 Driver Not Supporting 10Mbps Ethernet

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX28 Driver Not Supporting 10Mbps Ethernet

Jump to solution
1,010 Views
markwilliams
Senior Contributor I

We have been using the iMX28 in our products for some time based around the Windows CE 6.0 BSP. We have a customer that wishes to use 10Mbps Ethernet (for some unknown reason) but we have found that this is not supported by the BSP, despite the BSP reference manual stating that the driver supports 10/100Mbps.

Our customer uses 10Mbps HDX. If we configure a port to these settings then the PHY (LAN8720A over RMII, default HW set to auto-negotiate) detects and reports the link state (WinCE desktop shows connection made) but data transfer does not occur.

Studying the ENET driver it seems that the HW_ENET_MAC_RCR RMII_10T bit is not set anywhere. According to the register specification this must be set for 10Mbps mode with the RMII interface but there isn't any further information other than that. There is some anecdotal information suggesting a reset is required but this is not mentioned for this bit like others.

Has anyone else seen this issue? I know rare these days to run at 10Mbps (hence 4/5 years of product before we noticed it!).

Also could it be confirmed that RMII_10T must be set for this mode and if this can be done without resetting the controller.

It looks like in ENETParseLAN87xxSCSR I may need to set/clear the RMII_10T bit depending on whether this register shows 10 or 100Mbps capability.

I looked in the WEC7 driver but it looked the same as the CE6 one.

Thanks, Mark

Labels (1)
0 Kudos
1 Solution
724 Views
markwilliams
Senior Contributor I

After a few days testing I have managed to resolve this. As I mentioned in an earlier post the Windows CE ENET driver does not support speed or duplex changes from 100Mbps FDX. This seems odd as there is a reference manual that explains that it does support it but the code does not back that up.

This is evident from functions such as ENETEnetReset which takes in a parameter of DuplexMode but is only called from one place with FALSE hard coded for this field. Also in this function the code checks duplex mode and configures it for half but then later in the function hard-codes it back to full.

The windows miniport driver makes a call to ENETCheckForHang every two seconds (interestingly this function can never return TRUE so not sure what happens if the PHY does hang!). This function calls ENETGetLinkStatus which sends a series of MII commands to the PHY. Unfortunately the code does not check the SCSR register which includes the established link speed and duplex obtained during auto-negotiation/parallel detection. We can add this to the list of commands here:

(C:\WINCE600\PLATFORM\COMMON\src\soc\COMMON_FSL_V2_PDK1_9\ENET\phys.h)

ENET_PHY_CMD LAN87xxAckint[] = {
{MII_READ_COMMAND(MII_REG_SR), ENETParseMIISr},
{MII_READ_COMMAND(MII_LAN87xx_ICR), NULL },
{MII_READ_COMMAND(MII_LAN87xx_SCSR), ENETParseLAN87xxSCSR}, /* Add check of SCSR register */
{ENET_MII_END, NULL}
};

The SCSR register is parsed in the callback ENETParseLAN87xxSCSR. Here we can handle changes in link speed and duplex, looking for changes from the previous settings and reconfiguring the PHY registers for 10/100 H/FDX. We can also set pEthernet->FullDuplexMode to keep track of this setting.

Interestingly on change in Duplex the higher level miniport driver calls ENETReset. At present this hardcodes the duplex setting. In ENETReset we need to change:

ENETEnetReset(MiniportAdapterContext, FALSE);

ENETEnetReset(MiniportAdapterContext, pEthernet->FullDuplexMode);

But within ENETEnetReset (called from ENETReset) we need to comment out the line:

BW_ENET_MAC_TCR_FEDN(index,1);

For some reason after testing the DuplexMode and setting up the PHY accordingly later on at the end of the function is the above line which then hard-codes full duplex mode on (regardless of whether the reset function was passed full/half duplex).

When I get a moment I will add the updated source files. It is probably rare someone wants to use 10Mbps or HDX but the supplied driver doesn't support the change in link properties.

A side issue is that if the iMX28 end is configured for auto-negotiate but the other end configured for fixed setting then the iMX28 end can determine the speed through parallel detection but the duplex defaults to HDX. This means if the link partner is FDX fixed (either speed) then there will be a duplex mismatch leading to comms errors.

To work around this the driver would need the ability to turn off auto-negotiate but this would involve more coding to add support for re-configuring the PHY over the MII interface to specify a duplex mode.

I hope the above is useful to others with similar issues!

Mark

View solution in original post

0 Kudos
4 Replies
725 Views
markwilliams
Senior Contributor I

After a few days testing I have managed to resolve this. As I mentioned in an earlier post the Windows CE ENET driver does not support speed or duplex changes from 100Mbps FDX. This seems odd as there is a reference manual that explains that it does support it but the code does not back that up.

This is evident from functions such as ENETEnetReset which takes in a parameter of DuplexMode but is only called from one place with FALSE hard coded for this field. Also in this function the code checks duplex mode and configures it for half but then later in the function hard-codes it back to full.

The windows miniport driver makes a call to ENETCheckForHang every two seconds (interestingly this function can never return TRUE so not sure what happens if the PHY does hang!). This function calls ENETGetLinkStatus which sends a series of MII commands to the PHY. Unfortunately the code does not check the SCSR register which includes the established link speed and duplex obtained during auto-negotiation/parallel detection. We can add this to the list of commands here:

(C:\WINCE600\PLATFORM\COMMON\src\soc\COMMON_FSL_V2_PDK1_9\ENET\phys.h)

ENET_PHY_CMD LAN87xxAckint[] = {
{MII_READ_COMMAND(MII_REG_SR), ENETParseMIISr},
{MII_READ_COMMAND(MII_LAN87xx_ICR), NULL },
{MII_READ_COMMAND(MII_LAN87xx_SCSR), ENETParseLAN87xxSCSR}, /* Add check of SCSR register */
{ENET_MII_END, NULL}
};

The SCSR register is parsed in the callback ENETParseLAN87xxSCSR. Here we can handle changes in link speed and duplex, looking for changes from the previous settings and reconfiguring the PHY registers for 10/100 H/FDX. We can also set pEthernet->FullDuplexMode to keep track of this setting.

Interestingly on change in Duplex the higher level miniport driver calls ENETReset. At present this hardcodes the duplex setting. In ENETReset we need to change:

ENETEnetReset(MiniportAdapterContext, FALSE);

ENETEnetReset(MiniportAdapterContext, pEthernet->FullDuplexMode);

But within ENETEnetReset (called from ENETReset) we need to comment out the line:

BW_ENET_MAC_TCR_FEDN(index,1);

For some reason after testing the DuplexMode and setting up the PHY accordingly later on at the end of the function is the above line which then hard-codes full duplex mode on (regardless of whether the reset function was passed full/half duplex).

When I get a moment I will add the updated source files. It is probably rare someone wants to use 10Mbps or HDX but the supplied driver doesn't support the change in link properties.

A side issue is that if the iMX28 end is configured for auto-negotiate but the other end configured for fixed setting then the iMX28 end can determine the speed through parallel detection but the duplex defaults to HDX. This means if the link partner is FDX fixed (either speed) then there will be a duplex mismatch leading to comms errors.

To work around this the driver would need the ability to turn off auto-negotiate but this would involve more coding to add support for re-configuring the PHY over the MII interface to specify a duplex mode.

I hope the above is useful to others with similar issues!

Mark

0 Kudos
724 Views
markwilliams
Senior Contributor I

I have been debugging this further and it looks like the driver does not handle changes in link speed. The enet init function sets it up as if 100Mbps and only then initially reads the register from the PHY that shows the achieved link speed.

Every two seconds or so the MII bus polls the PHY to read the SR register and interrupt register. The SR register result is parsed and just reports changes in link state (connected/not). It does not handle changes in speed or duplex mode as the reference manual would lead you to believe it should.

I have managed to get 10Mbps by adding a poll to the SCSR register to the message queue sent every two seconds on the MII. I have then updated the SCSR response handler to change the RMII_10T bit depending on whether the SCSR register shows it has achieved a 10Mbps or 100Mbps link. Initial testing shows that now I can connect and communicate at 10Mbps.

However the driver also doesn't seem to reconfigure the ENET controller in the iMX28 based on duplex mode. According to the iMX28 manual:

DRT - Disable receive on transmit. 0=FDX 1=HDX

FEDN - Full Duplex Enable bit. 1=FDX 0=HDX         (interesting this bit is called FDEN for other processors but FEDN for this. Typo?!)

From debugging it looks like DRT is set to 0 and FEDN 1 (as per full duplex). This doesn't change regardless of link.

So in summary it looks like I need to change more than just RMII_II on link change. One sticking point is that to change FEDN the ETHER_EN bit must be clear. I need to research further but am I ok to clear ETHER_EN, change FEDN then set ETHER_EN. Or does clearing/setting ETHER_EN reset other registers to defaults?

Any help would be greatly appreciated.

Mark

0 Kudos
724 Views
b36401
NXP Employee
NXP Employee

If your board is based on i.MX28 EVK and WinCE 6.0 then please follow chapter 10 in Windows Embedded CE 6.0 Reference Manual:
http://www.freescale.com/files/32bit/doc/support_info/WCE600_MX28_SDK_1008_DOCKIT.zip

In chapter 10.3 "Hardware Operations" you can read the following description:
The Ethernet MAC Controller connects with the external transceiver using standard RMII (Reduced Media Independent Interface) connection.
All the registers in the external transceiver (LAN8720) can be accessed by the RMII compatible management frames.
The attached transceiver for the Fast Ethernet Controller can detect the speed of the ethernet network automatically by the auto-negotiation process.
The software accesses the status register of attached transceiver to determine the speed of the ethernet network (10 Mbps or 100 Mbps).

In this situation 100 Mbps port should work properly also with 10 Mbps devices without problems.

Have a great day,
Victor

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
724 Views
markwilliams
Senior Contributor I

Thank you for your reply Victor but I did mention in my original post that I was aware that the reference manual says that the driver should work with both 10 and 100Mbps but the point of the post is that it doesn't.

As the manual suggests the driver is able to detect the current speed of the ethernet port but as I put in my post above I am concerned as despite the connection status data transfer is not possible.

I mentioned in my post that there is a bit in the manual (RMII_10T) that is not well documented but supposedly needs to be enabled for 10Mbps operation in RMII mode. This does not seem to be set anywhere by the driver so if this is the case then it could be why 10Mbps operation does not work.

Can you confirm what the RMII_10T bit does and if this should be set for 10Mbps operation when using RMII?

Regards, Mark

0 Kudos