//------------------------------------------------------------------------------
static void setupVethBroadcast(tEdrvFilter* pFilter_p, BOOL fEnable_p)
{
    ami_setUint48Be(&pFilter_p->aFilterValue[0], C_DLL_MACADDR_MASK);
    ami_setUint48Be(&pFilter_p->aFilterMask[0], C_DLL_MACADDR_MASK);

    pFilter_p->pTxBuffer = NULL;
    pFilter_p->fEnable = fEnable_p;
}
//------------------------------------------------------------------------------
void dllk_setupPresFilter(tEdrvFilter* pFilter_p, BOOL fEnable_p)
{
    ami_setUint48Be(&pFilter_p->aFilterValue[0], C_DLL_MULTICAST_PRES);
    ami_setUint48Be(&pFilter_p->aFilterMask[0], C_DLL_MACADDR_MASK);
    ami_setUint16Be(&pFilter_p->aFilterValue[12], C_DLL_ETHERTYPE_EPL);
    ami_setUint16Be(&pFilter_p->aFilterMask[12], 0xFFFF);
    ami_setUint8Be(&pFilter_p->aFilterValue[14], kMsgTypePres);
    ami_setUint8Be(&pFilter_p->aFilterMask[14], 0xFF);
    pFilter_p->fEnable = fEnable_p;
}
//------------------------------------------------------------------------------
void dllkfilter_setupPresFilter(tEdrvFilter* pFilter_p, BOOL fEnable_p)
{
    // Check parameter validity
    ASSERT(pFilter_p != NULL);

    ami_setUint48Be(&pFilter_p->aFilterValue[0], C_DLL_MULTICAST_PRES);
    ami_setUint48Be(&pFilter_p->aFilterMask[0], C_DLL_MACADDR_MASK);
    ami_setUint16Be(&pFilter_p->aFilterValue[12], C_DLL_ETHERTYPE_EPL);
    ami_setUint16Be(&pFilter_p->aFilterMask[12], 0xFFFF);
    ami_setUint8Be(&pFilter_p->aFilterValue[14], kMsgTypePres);
    ami_setUint8Be(&pFilter_p->aFilterMask[14], 0xFF);
    pFilter_p->fEnable = fEnable_p;
}
//------------------------------------------------------------------------------
static void setupVethUnicast(tEdrvFilter* pFilter_p,
                             const UINT8* pMacAdrs_p,
                             BOOL fEnable_p)
{
    OPLK_MEMCPY(&pFilter_p->aFilterValue[0], pMacAdrs_p, 6);
    ami_setUint48Be(&pFilter_p->aFilterMask[0], C_DLL_MACADDR_MASK);

    pFilter_p->pTxBuffer = NULL;
    pFilter_p->fEnable = fEnable_p;
}
//------------------------------------------------------------------------------
void dllk_setupSoaUnspecReqFilter(tEdrvFilter* pFilter_p, UINT nodeId_p, tEdrvTxBuffer* pBuffer_p)
{
    ami_setUint48Be(&pFilter_p->aFilterValue[0], C_DLL_MULTICAST_SOA);
    ami_setUint48Be(&pFilter_p->aFilterMask[0], C_DLL_MACADDR_MASK);
    ami_setUint16Be(&pFilter_p->aFilterValue[12], C_DLL_ETHERTYPE_EPL);
    ami_setUint16Be(&pFilter_p->aFilterMask[12], 0xFFFF);
    ami_setUint8Be(&pFilter_p->aFilterValue[14], kMsgTypeSoa);
#if defined(CONFIG_INCLUDE_MASND)
    // Ignore bit4 of message type to react on both Asnd and AInv frames
    ami_setUint8Be(&pFilter_p->aFilterMask[14], 0xF7);
#else
    ami_setUint8Be(&pFilter_p->aFilterMask[14], 0xFF);
#endif
    ami_setUint8Be(&pFilter_p->aFilterValue[20], kDllReqServiceUnspecified);
    ami_setUint8Be(&pFilter_p->aFilterMask[20], 0xFF);
    ami_setUint8Be(&pFilter_p->aFilterValue[21], (UINT8)nodeId_p);
    ami_setUint8Be(&pFilter_p->aFilterMask[21], 0xFF);
    pFilter_p->pTxBuffer = pBuffer_p;
    pFilter_p->fEnable = FALSE;
}
//------------------------------------------------------------------------------
void dllk_setupPreqFilter(tEdrvFilter* pFilter_p, UINT nodeId_p, tEdrvTxBuffer* pBuffer_p, UINT8* pMacAdrs_p)
{
    OPLK_MEMCPY(&pFilter_p->aFilterValue[0], pMacAdrs_p, 6);
    ami_setUint48Be(&pFilter_p->aFilterMask[0], C_DLL_MACADDR_MASK);
    ami_setUint16Be(&pFilter_p->aFilterValue[12], C_DLL_ETHERTYPE_EPL);
    ami_setUint16Be(&pFilter_p->aFilterMask[12], 0xFFFF);
    ami_setUint8Be(&pFilter_p->aFilterValue[14], kMsgTypePreq);
    ami_setUint8Be(&pFilter_p->aFilterMask[14], 0xFF);
    ami_setUint8Be(&pFilter_p->aFilterValue[15], (UINT8)nodeId_p);
    ami_setUint8Be(&pFilter_p->aFilterMask[15], 0xFF);
    ami_setUint8Be(&pFilter_p->aFilterValue[16], C_ADR_MN_DEF_NODE_ID);
    ami_setUint8Be(&pFilter_p->aFilterMask[16], 0xFF);
    pFilter_p->pTxBuffer = pBuffer_p;
    pFilter_p->fEnable = FALSE;
}
//------------------------------------------------------------------------------
void dllk_setupSoaFilter(tEdrvFilter* pFilter_p)
{
    ami_setUint48Be(&pFilter_p->aFilterValue[0], C_DLL_MULTICAST_SOA);
    ami_setUint48Be(&pFilter_p->aFilterMask[0], C_DLL_MACADDR_MASK);
    pFilter_p->fEnable = TRUE;
}
示例#8
0
//------------------------------------------------------------------------------
tOplkError dllknode_setupLocalNode(tNmtState nmtState_p)
{
    tOplkError      ret = kErrorOk;
    UINT            handle;
    UINT            frameSize;
    UINT8           aMulticastMac[6];

#if !defined(CONFIG_INCLUDE_NMT_MN)
    UNUSED_PARAMETER(nmtState_p);
#endif

    // initialize flags for PRes and StatusRes (leave Flag 1 unchanged)
    dllkInstance_g.mnFlag1 = 0;
    dllkInstance_g.flag2 = 0;

#if defined(CONFIG_INCLUDE_NMT_MN)
    // initialize linked node list
    dllkInstance_g.pFirstNodeInfo = NULL;
    dllkInstance_g.pFirstPrcNodeInfo = NULL;
#endif
#if defined(CONFIG_INCLUDE_NMT_RMN)
    if (nmtState_p == kNmtRmsNotActive)
        dllkInstance_g.fRedundancy = TRUE;
    else
        dllkInstance_g.fRedundancy = FALSE;

    // AMNI
    if (dllkInstance_g.fRedundancy)
    {
        frameSize = C_DLL_MINSIZE_AMNI;
        ret = dllkframe_createTxFrame(&handle, &frameSize, kMsgTypeAmni, kDllAsndNotDefined);
        if (ret != kErrorOk)
        {   // error occurred while registering Tx frame
            return ret;
        }
    }
#endif

    /*-----------------------------------------------------------------------*/
    /* register TxFrames in Edrv */
    // IdentResponse
    frameSize = C_DLL_MINSIZE_IDENTRES;
    ret = dllkframe_createTxFrame(&handle, &frameSize, kMsgTypeAsnd, kDllAsndIdentResponse);
    if (ret != kErrorOk)
        return ret;

    // StatusResponse
    frameSize = C_DLL_MINSIZE_STATUSRES;
    ret = dllkframe_createTxFrame(&handle, &frameSize, kMsgTypeAsnd, kDllAsndStatusResponse);
    if (ret != kErrorOk)
        return ret;

#if CONFIG_DLL_PRES_CHAINING_CN != FALSE
    // SyncResponse
    frameSize = C_DLL_MINSIZE_SYNCRES;
    ret = dllkframe_createTxFrame(&handle, &frameSize, kMsgTypeAsnd, kDllAsndSyncResponse);
    if (ret != kErrorOk)
        return ret;
#endif

    // PRes
    if ((dllkInstance_g.dllConfigParam.fAsyncOnly == FALSE) &&
        (dllkInstance_g.dllConfigParam.presActPayloadLimit >= 36))
    {   // it is not configured as async-only CN,
        // so take part in isochronous phase and register PRes frame
        frameSize = dllkInstance_g.dllConfigParam.presActPayloadLimit + PLK_FRAME_OFFSET_PDO_PAYLOAD;
        ret = dllkframe_createTxFrame(&handle, &frameSize, kMsgTypePres, kDllAsndNotDefined);
        if (ret != kErrorOk)
            return ret;

        // reset cycle counter
        dllkInstance_g.cycleCount = 0;
        dllkInstance_g.prescaleCycleCount = 0;
    }
    else
    {   // it is an async-only CN -> fool changeState() to think that PRes was not expected
        dllkInstance_g.cycleCount = 1;
    }

    // NMT request
    frameSize = C_IP_MAX_MTU;
    ret = dllkframe_createTxFrame(&handle, &frameSize, kMsgTypeAsnd, kDllAsndNmtRequest);
    if (ret != kErrorOk)
        return ret;
    // mark Tx buffer as empty
    dllkInstance_g.aTxBufferStateNmtReq[0] = kDllkTxBufEmpty;
    dllkInstance_g.pTxBuffer[handle].txFrameSize = 0;
    dllkInstance_g.pTxBuffer[handle].pfnTxHandler = dllkframe_processTransmittedNmtReq;
    handle++;
    dllkInstance_g.aTxBufferStateNmtReq[1] = kDllkTxBufEmpty;
    dllkInstance_g.pTxBuffer[handle].txFrameSize = 0;
    dllkInstance_g.pTxBuffer[handle].pfnTxHandler = dllkframe_processTransmittedNmtReq;

    // non-POWERLINK frame
    frameSize = C_IP_MAX_MTU;
    ret = dllkframe_createTxFrame(&handle, &frameSize, kMsgTypeNonPowerlink, kDllAsndNotDefined);
    if (ret != kErrorOk)
        return ret;
    // mark Tx buffer as empty
    dllkInstance_g.aTxBufferStateNonPlk[0] = kDllkTxBufEmpty;
    dllkInstance_g.pTxBuffer[handle].txFrameSize = 0;
    dllkInstance_g.pTxBuffer[handle].pfnTxHandler = dllkframe_processTransmittedNonPlk;
    handle++;
    dllkInstance_g.aTxBufferStateNonPlk[1] = kDllkTxBufEmpty;
    dllkInstance_g.pTxBuffer[handle].txFrameSize = 0;
    dllkInstance_g.pTxBuffer[handle].pfnTxHandler = dllkframe_processTransmittedNonPlk;

    /*------------------------------------------------------------------------*/
    /* setup filter structure for Edrv */
    dllkfilter_setupFilters();

    // register multicast MACs in ethernet driver
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_SOC);
    ret = edrv_setRxMulticastMacAddr(aMulticastMac);
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_SOA);
    ret = edrv_setRxMulticastMacAddr(aMulticastMac);
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_PRES);
    ret = edrv_setRxMulticastMacAddr(aMulticastMac);
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_ASND);
    ret = edrv_setRxMulticastMacAddr(aMulticastMac);

#if defined(CONFIG_INCLUDE_NMT_RMN)
    if (dllkInstance_g.fRedundancy)
    {
        ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_AMNI);
        ret = edrv_setRxMulticastMacAddr(aMulticastMac);
    }
#endif

#if defined(CONFIG_INCLUDE_NMT_MN)
    if (NMT_IF_MN_OR_RMN(nmtState_p))
    {
        if ((ret = setupLocalNodeMn()) != kErrorOk)
            return ret;

#if defined(CONFIG_INCLUDE_NMT_RMN)
        if (nmtState_p == kNmtRmsNotActive)
        {
            if ((ret = setupLocalNodeCn()) != kErrorOk)
                return ret;
        }
#endif
    }
    else
    {
        if ((ret = setupLocalNodeCn()) != kErrorOk)
            return ret;
    }
#else
    if ((ret = setupLocalNodeCn()) != kErrorOk)
        return ret;
#endif

    // clear all asynchronous buffers
    ret = dllkcal_clearAsyncBuffer();
    if (ret != kErrorOk)
        return ret;

    // set filters in Edrv
    ret = edrv_changeRxFilter(dllkInstance_g.aFilter, DLLK_FILTER_COUNT, DLLK_FILTER_COUNT, 0);

    return ret;
}
示例#9
0
//------------------------------------------------------------------------------
tOplkError dllknode_cleanupLocalNode(tNmtState oldNmtState_p)
{
    tOplkError      ret = kErrorOk;
    BYTE            aMulticastMac[6];
#if NMT_MAX_NODE_ID > 0
    UINT            index;
#endif

#if defined(CONFIG_INCLUDE_NMT_MN)
    UINT            handle;
#else
    UNUSED_PARAMETER(oldNmtState_p);
#endif

    // remove all filters from Edrv
    ret = edrv_changeRxFilter(NULL, 0, 0, 0);

    // delete timer
#if CONFIG_TIMER_USE_HIGHRES != FALSE
    if ((ret = hrestimer_deleteTimer(&dllkInstance_g.timerHdlCycle)) != kErrorOk)
        return ret;

#if defined(CONFIG_INCLUDE_NMT_RMN)
    if ((ret = hrestimer_deleteTimer(&dllkInstance_g.timerHdlSwitchOver)) != kErrorOk)
        return ret;
#endif
#endif

#if defined(CONFIG_INCLUDE_NMT_MN)
    if ((ret = edrvcyclic_stopCycle(FALSE)) != kErrorOk)
        return ret;

    if ((ret = edrvcyclic_regSyncHandler(NULL)) != kErrorOk)
        return ret;
#endif

#if (CONFIG_DLL_PROCESS_SYNC == DLL_PROCESS_SYNC_ON_TIMER)
    if ((ret = synctimer_stopSync()) != kErrorOk)
        return ret;
#endif

#if defined(CONFIG_INCLUDE_NMT_MN)
    // destroy all data structures
    OPLK_FREE(dllkInstance_g.ppTxBufferList);
    dllkInstance_g.ppTxBufferList = NULL;
#endif

    // delete Tx frames
    if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_IDENTRES)) != kErrorOk)
        return ret;

    if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_STATUSRES)) != kErrorOk)
        return ret;

    if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_PRES)) != kErrorOk)
        return ret;

#if defined(CONFIG_INCLUDE_NMT_RMN)
    if (dllkInstance_g.fRedundancy)
    {
      if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_AMNI)) != kErrorOk)
        return ret;
    }
#endif

    dllkInstance_g.aTxBufferStateNmtReq[0] = kDllkTxBufEmpty;
    dllkInstance_g.aTxBufferStateNmtReq[1] = kDllkTxBufEmpty;
    if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_NMTREQ)) != kErrorOk)
        return ret;

#if CONFIG_DLL_PRES_CHAINING_CN != FALSE
    if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_SYNCRES)) != kErrorOk)
        return ret;
#endif

    dllkInstance_g.aTxBufferStateNonPlk[0] = kDllkTxBufEmpty;
    dllkInstance_g.aTxBufferStateNonPlk[1] = kDllkTxBufEmpty;
    if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_NONPLK)) != kErrorOk)
        return ret;

#if defined(CONFIG_INCLUDE_NMT_MN)
#if !defined(CONFIG_INCLUDE_NMT_RMN)
    if (NMT_IF_MN_OR_RMN(oldNmtState_p))
#else
    if (NMT_IF_MN_OR_RMN(oldNmtState_p) || (dllkInstance_g.fRedundancy))
#endif
    {   // local node was MN
        if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_SOC)) != kErrorOk)
            return ret;

        if ((ret = dllkframe_deleteTxFrame(DLLK_TXFRAME_SOA)) != kErrorOk)
            return ret;

        for (index = 0; index < tabentries (dllkInstance_g.aNodeInfo); index++)
        {
            if (dllkInstance_g.aNodeInfo[index].pPreqTxBuffer != NULL)
            {
                handle = (UINT)(dllkInstance_g.aNodeInfo[index].pPreqTxBuffer - dllkInstance_g.pTxBuffer);
                dllkInstance_g.aNodeInfo[index].pPreqTxBuffer = NULL;
                if (handle != DLLK_TXFRAME_PRES)
                {
                    if ((ret = dllkframe_deleteTxFrame(handle)) != kErrorOk)
                        return ret;
                }
            }
            // disable PReq and PRes for this node
            dllkInstance_g.aNodeInfo[index].preqPayloadLimit = 0;
            dllkInstance_g.aNodeInfo[index].presPayloadLimit = 0;
        }
    }
    else
    {   // local node was CN
        for (index = 0; index < tabentries(dllkInstance_g.aNodeInfo); index++)
        {
            // disable PReq and PRes for this node
            dllkInstance_g.aNodeInfo[index].presPayloadLimit = 0;
            dllkInstance_g.aNodeInfo[index].preqPayloadLimit = 0;
        }
    }
#else
    // must be CN, because MN part is not compiled!
#if NMT_MAX_NODE_ID > 0
    for (index = 0; index < tabentries(dllkInstance_g.aNodeInfo); index++)
    {
        // disable PRes for this node
        dllkInstance_g.aNodeInfo[index].presPayloadLimit = 0;
    }
#endif

#endif

    // de-register multicast MACs in Ethernet driver
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_SOC);
    ret = edrv_clearRxMulticastMacAddr(aMulticastMac);
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_SOA);
    ret = edrv_clearRxMulticastMacAddr(aMulticastMac);
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_PRES);
    ret = edrv_clearRxMulticastMacAddr(aMulticastMac);
    ami_setUint48Be(&aMulticastMac[0], C_DLL_MULTICAST_ASND);
    ret = edrv_clearRxMulticastMacAddr(aMulticastMac);

    return ret;
}