King Jin

FEC driver will hang up when re-load network adapter

Discussion created by King Jin Employee on Mar 30, 2012

In i.MX51 WINCE platform, if the driver of LAN (FEC) is made to re-load via Ndis, it will stop being able to carry out MII access of the FEC driver at the time of a re-load, and a driver will hang-up.

[The reproduction method]
It reproduces on IMX515 EVK board.
A procedure is the following.
1. Start Command Prompt.
2. Execute Command as Follows.
Ndisconfig Adapter Del Fec1
Ndisconfig Adapter Add Fec Fec1

 

The root cause is when the FEC adapter is removed, it will call the FSL code FECHalt() to halt the network adapter, in this function it will call Microsoft code NdisMDeregisterInterrupt() function de-allocate interrupt resources, at last it will call FSL code  OALIntrReleaseSysIntr() to release the given SYSINTR, but it won't. So the SYSINTR is still exist and bind with IRQ_FEC. When the FEC adapter is re-load, the FSL code FECInitialize() will call NdisMRegisterInterrupt(), then it call OALIntrRequestSysIntr() to allocate new SYSINTR for IRQ_FEC, at this time, there have two SYSINTR map to the IRQ_FEC and morever the old SYSINTR is ahead of the new one, as a result, the old SYSINTR will be set when IRQ_FEC is triggered, the interrupt handle have never been called. As you know FEC driver sending command to get the PHY ID is implemeted in the interrupt handle.

We can use the static map between SYSINTR and IRQ_FEC as following to fix this issue:
1. In ..\WINCE600\PLATFORM\COMMON\SRC\SOC\MX51_FSL_V2\OAL\INTR\Intr.c
BOOL OALIntrInit()
{
....
   // Initialize interrupt mapping
    OALIntrMapInit();
/****************** Start add***************************/
    OALIntrStaticTranslate(SYSINTR_FEC, IRQ_FEC);  // add static map the IRQ_FEC to  SYSINTR_FEC.
/*****************End add*****************************/
....
}

2. in ..\WINCE600\PLATFORM\COMMON\SRC\SOC\MX51_FSL_V2\OAL\INTR\map.c
UINT32 OALIntrRequestSysIntr(UINT32 count, const UINT32 *pIrqs, UINT32 flags)
{
    UINT32 sysIntr, i, j;

    //OALMSG(OAL_INTR&&OAL_FUNC, (
    RETAILMSG(1, (
        L"+OALIntrRequestSysIntr(%d, 0x%08x, 0x%08x)\r\n", count, pIrqs, flags
        ));
/****************** Start add***************************/
    if(IRQ_FEC == pIrqs[0])
     {
         sysIntr = SYSINTR_FEC;
           goto cleanUp;
     }                                            //if request IRQ is IRQ_FEC, assign given SYSINTR_FEC and return
/*****************End add*****************************/

..............
}

3...\WINCE600\PLATFORM\COMMON\SRC\SOC\MX51_FSL_V2\INC\Mx51_irq.h
/******************Add the SYSINTR_FEC  macro **************************/             
#define SYSINTR_FEC                 (SYSINTR_FIRMWARE + 3)
/******************END **************************/  

I have verified it in MX51 BBG board.

Outcomes