//------------------------------------------------------------------------------ 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; }
//------------------------------------------------------------------------------ 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; }
//------------------------------------------------------------------------------ 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; }