blob: 9e22641055c61cd7066410603c73d74e99d198fa [file] [log] [blame]
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001/****************************************************************************
2
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
5
6 Project: openPOWERLINK
7
8 Description: source file for kernel DLL module
9
10 License:
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
22
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
27
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
40
41 Severability Clause:
42
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
49
50 -------------------------------------------------------------------------
51
52 $RCSfile: EplDllk.c,v $
53
54 $Author: D.Krueger $
55
56 $Revision: 1.21 $ $Date: 2008/11/13 17:13:09 $
57
58 $State: Exp $
59
60 Build Environment:
61 GCC V3.4
62
63 -------------------------------------------------------------------------
64
65 Revision History:
66
67 2006/06/12 d.k.: start of the implementation, version 1.00
68
69****************************************************************************/
70
71#include "kernel/EplDllk.h"
72#include "kernel/EplDllkCal.h"
73#include "kernel/EplEventk.h"
74#include "kernel/EplNmtk.h"
75#include "edrv.h"
76#include "Benchmark.h"
77
78#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
79#include "kernel/EplPdok.h"
80#endif
81
82#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
83#include "kernel/VirtualEthernet.h"
84#endif
85
86//#if EPL_TIMER_USE_HIGHRES != FALSE
87#include "kernel/EplTimerHighResk.h"
88//#endif
89
90#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
91
92#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) == 0)
93#error "EPL module DLLK needs EPL module NMTK!"
94#endif
95
96#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) && (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
97#error "EPL module DLLK: select only one of EPL_DLL_PRES_READY_AFTER_SOA and EPL_DLL_PRES_READY_AFTER_SOC."
98#endif
99
100#if ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)) \
101 && (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
102#error "EPL module DLLK: currently, EPL_DLL_PRES_READY_AFTER_* is not supported if EPL_MODULE_NMT_MN is enabled."
103#endif
104
105#if (EDRV_FAST_TXFRAMES == FALSE) && \
106 ((EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE))
107#error "EPL module DLLK: EPL_DLL_PRES_READY_AFTER_* is enabled, but not EDRV_FAST_TXFRAMES."
108#endif
109
110/***************************************************************************/
111/* */
112/* */
113/* G L O B A L D E F I N I T I O N S */
114/* */
115/* */
116/***************************************************************************/
117
118//---------------------------------------------------------------------------
119// const defines
120//---------------------------------------------------------------------------
121
122// TracePoint support for realtime-debugging
123#ifdef _DBG_TRACE_POINTS_
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800124void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
125void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
126#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
127#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800128#else
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800129#define TGT_DBG_SIGNAL_TRACE_POINT(p)
130#define TGT_DBG_POST_TRACE_VALUE(v)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800131#endif
132#define EPL_DLLK_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
133 TGT_DBG_POST_TRACE_VALUE((kEplEventSinkDllk << 28) | (Event_p << 24) \
134 | (uiNodeId_p << 16) | wErrorCode_p)
135
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800136/***************************************************************************/
137/* */
138/* */
139/* C L A S S EplDllk */
140/* */
141/* */
142/***************************************************************************/
143//
144// Description:
145//
146//
147/***************************************************************************/
148
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800149//=========================================================================//
150// //
151// P R I V A T E D E F I N I T I O N S //
152// //
153//=========================================================================//
154
155//---------------------------------------------------------------------------
156// const defines
157//---------------------------------------------------------------------------
158
159// defines for indexes of tEplDllInstance.m_pTxFrameInfo
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800160#define EPL_DLLK_TXFRAME_IDENTRES 0 // IdentResponse on CN / MN
161#define EPL_DLLK_TXFRAME_STATUSRES 1 // StatusResponse on CN / MN
162#define EPL_DLLK_TXFRAME_NMTREQ 2 // NMT Request from FIFO on CN / MN
163#define EPL_DLLK_TXFRAME_NONEPL 3 // non-EPL frame from FIFO on CN / MN
164#define EPL_DLLK_TXFRAME_PRES 4 // PRes on CN / MN
165#define EPL_DLLK_TXFRAME_SOC 5 // SoC on MN
166#define EPL_DLLK_TXFRAME_SOA 6 // SoA on MN
167#define EPL_DLLK_TXFRAME_PREQ 7 // PReq on MN
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800168#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800169#define EPL_DLLK_TXFRAME_COUNT (7 + EPL_D_NMT_MaxCNNumber_U8 + 2) // on MN: 7 + MaxPReq of regular CNs + 1 Diag + 1 Router
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800170#else
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800171#define EPL_DLLK_TXFRAME_COUNT 5 // on CN: 5
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800172#endif
173
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800174#define EPL_DLLK_BUFLEN_EMPTY 0 // buffer is empty
175#define EPL_DLLK_BUFLEN_FILLING 1 // just the buffer is being filled
176#define EPL_DLLK_BUFLEN_MIN 60 // minimum ethernet frame length
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800177
178//---------------------------------------------------------------------------
179// local types
180//---------------------------------------------------------------------------
181
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800182typedef enum {
183 kEplDllGsInit = 0x00, // MN/CN: initialisation (< PreOp2)
184 kEplDllCsWaitPreq = 0x01, // CN: wait for PReq frame
185 kEplDllCsWaitSoc = 0x02, // CN: wait for SoC frame
186 kEplDllCsWaitSoa = 0x03, // CN: wait for SoA frame
187 kEplDllMsNonCyclic = 0x04, // MN: reduced EPL cycle (PreOp1)
188 kEplDllMsWaitSocTrig = 0x05, // MN: wait for SoC trigger (cycle timer)
189 kEplDllMsWaitPreqTrig = 0x06, // MN: wait for (first) PReq trigger (WaitSoCPReq_U32)
190 kEplDllMsWaitPres = 0x07, // MN: wait for PRes frame from CN
191 kEplDllMsWaitSoaTrig = 0x08, // MN: wait for SoA trigger (PRes transmitted)
192 kEplDllMsWaitAsndTrig = 0x09, // MN: wait for ASnd trigger (SoA transmitted)
193 kEplDllMsWaitAsnd = 0x0A, // MN: wait for ASnd frame if SoA contained invitation
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800194
195} tEplDllState;
196
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800197typedef struct {
198 BYTE m_be_abSrcMac[6];
199 tEdrvTxBuffer *m_pTxBuffer; // Buffers for Tx-Frames
200 unsigned int m_uiMaxTxFrames;
201 BYTE m_bFlag1; // Flag 1 with EN, EC for PRes, StatusRes
202 BYTE m_bMnFlag1; // Flag 1 with EA, ER from PReq, SoA of MN
203 BYTE m_bFlag2; // Flag 2 with PR and RS for PRes, StatusRes, IdentRes
204 tEplDllConfigParam m_DllConfigParam;
205 tEplDllIdentParam m_DllIdentParam;
206 tEplDllState m_DllState;
207 tEplDllkCbAsync m_pfnCbAsync;
208 tEplDllAsndFilter m_aAsndFilter[EPL_DLL_MAX_ASND_SERVICE_ID];
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800209
210#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800211 tEplDllkNodeInfo *m_pFirstNodeInfo;
212 tEplDllkNodeInfo *m_pCurNodeInfo;
213 tEplDllkNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID];
214 tEplDllReqServiceId m_LastReqServiceId;
215 unsigned int m_uiLastTargetNodeId;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800216#endif
217
218#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800219 tEplTimerHdl m_TimerHdlCycle; // used for EPL cycle monitoring on CN and generation on MN
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800220#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800221 tEplTimerHdl m_TimerHdlResponse; // used for CN response monitoring
222#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800223#endif
224
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800225 unsigned int m_uiCycleCount; // cycle counter (needed for multiplexed cycle support)
226 unsigned long long m_ullFrameTimeout; // frame timeout (cycle length + loss of frame tolerance)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800227
228} tEplDllkInstance;
229
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800230//---------------------------------------------------------------------------
231// local vars
232//---------------------------------------------------------------------------
233
234// if no dynamic memory allocation shall be used
235// define structures statically
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800236static tEplDllkInstance EplDllkInstance_g;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800237
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800238static tEdrvTxBuffer aEplDllkTxBuffer_l[EPL_DLLK_TXFRAME_COUNT];
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800239
240//---------------------------------------------------------------------------
241// local function prototypes
242//---------------------------------------------------------------------------
243
244// change DLL state on event
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800245static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p,
246 tEplNmtState NmtState_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800247
248// called from EdrvInterruptHandler()
249static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p);
250
251// called from EdrvInterruptHandler()
252static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p);
253
254// check frame and set missing information
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800255static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
256 unsigned int uiFrameSize_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800257
258// called by high resolution timer module to monitor EPL cycle as CN
259#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800260static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800261#endif
262
263#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
264// MN: returns internal node info structure
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800265static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800266
267// transmit SoA
268static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800269 tEplDllState * pDllStateProposed_p,
270 BOOL fEnableInvitation_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800271
272static tEplKernel EplDllkMnSendSoc(void);
273
274static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800275 tEplDllState * pDllStateProposed_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800276
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800277static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
278 ReqServiceId_p,
279 unsigned int uiNodeId_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800280
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800281static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800282
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800283static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
284 pEventArg_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800285
286#endif
287
288//=========================================================================//
289// //
290// P U B L I C F U N C T I O N S //
291// //
292//=========================================================================//
293
294//---------------------------------------------------------------------------
295//
296// Function: EplDllkAddInstance()
297//
298// Description: add and initialize new instance of EPL stack
299//
300// Parameters: pInitParam_p = initialisation parameters like MAC address
301//
302// Returns: tEplKernel = error code
303//
304//
305// State:
306//
307//---------------------------------------------------------------------------
308
309tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p)
310{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800311 tEplKernel Ret = kEplSuccessful;
312 unsigned int uiIndex;
313 tEdrvInitParam EdrvInitParam;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800314
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800315 // reset instance structure
316 EPL_MEMSET(&EplDllkInstance_g, 0, sizeof(EplDllkInstance_g));
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800317
318#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800319 Ret = EplTimerHighReskInit();
320 if (Ret != kEplSuccessful) { // error occured while initializing high resolution timer module
321 goto Exit;
322 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800323#endif
324
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800325 // if dynamic memory allocation available
326 // allocate instance structure
327 // allocate TPDO and RPDO table with default size
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800328
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800329 // initialize and link pointers in instance structure to frame tables
330 EplDllkInstance_g.m_pTxBuffer = aEplDllkTxBuffer_l;
331 EplDllkInstance_g.m_uiMaxTxFrames =
332 sizeof(aEplDllkTxBuffer_l) / sizeof(tEdrvTxBuffer);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800333
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800334 // initialize state
335 EplDllkInstance_g.m_DllState = kEplDllGsInit;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800336
337#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800338 // set up node info structure
339 for (uiIndex = 0; uiIndex < tabentries(EplDllkInstance_g.m_aNodeInfo);
340 uiIndex++) {
341 EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
342 EplDllkInstance_g.m_aNodeInfo[uiIndex].m_wPresPayloadLimit =
343 0xFFFF;
344 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800345#endif
346
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800347 // initialize Edrv
348 EPL_MEMCPY(EdrvInitParam.m_abMyMacAddr, pInitParam_p->m_be_abSrcMac, 6);
349 EdrvInitParam.m_pfnRxHandler = EplDllkCbFrameReceived;
350 EdrvInitParam.m_pfnTxHandler = EplDllkCbFrameTransmitted;
351 Ret = EdrvInit(&EdrvInitParam);
352 if (Ret != kEplSuccessful) { // error occured while initializing ethernet driver
353 goto Exit;
354 }
355 // copy local MAC address from Ethernet driver back to local instance structure
356 // because Ethernet driver may have read it from controller EEPROM
357 EPL_MEMCPY(EplDllkInstance_g.m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr,
358 6);
359 EPL_MEMCPY(pInitParam_p->m_be_abSrcMac, EdrvInitParam.m_abMyMacAddr, 6);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800360
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800361 // initialize TxBuffer array
362 for (uiIndex = 0; uiIndex < EplDllkInstance_g.m_uiMaxTxFrames;
363 uiIndex++) {
364 EplDllkInstance_g.m_pTxBuffer[uiIndex].m_pbBuffer = NULL;
365 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800366
367#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800368 Ret = VEthAddInstance(pInitParam_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800369#endif
370
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800371 Exit:
372 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800373}
374
375//---------------------------------------------------------------------------
376//
377// Function: EplDllkDelInstance()
378//
379// Description: deletes an instance of EPL stack
380//
381// Parameters: (none)
382//
383// Returns: tEplKernel = error code
384//
385//
386// State:
387//
388//---------------------------------------------------------------------------
389
390tEplKernel EplDllkDelInstance(void)
391{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800392 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800393
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800394 // reset state
395 EplDllkInstance_g.m_DllState = kEplDllGsInit;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800396
397#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800398 Ret = EplTimerHighReskDelInstance();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800399#endif
400
401#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800402 Ret = VEthDelInstance();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800403#endif
404
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800405 Ret = EdrvShutdown();
406 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800407}
408
409//---------------------------------------------------------------------------
410//
411// Function: EplDllkCreateTxFrame
412//
413// Description: creates the buffer for a Tx frame and registers it to the
414// ethernet driver
415//
416// Parameters: puiHandle_p = OUT: handle to frame buffer
417// ppFrame_p = OUT: pointer to pointer of EPL frame
418// puiFrameSize_p = IN/OUT: pointer to size of frame
419// returned size is always equal or larger than
420// requested size, if that is not possible
421// an error will be returned
422// MsgType_p = EPL message type
423// ServiceId_p = Service ID in case of ASnd frame, otherwise
424// kEplDllAsndNotDefined
425//
426// Returns: tEplKernel = error code
427//
428//
429// State:
430//
431//---------------------------------------------------------------------------
432
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800433tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
434 tEplFrame ** ppFrame_p,
435 unsigned int *puiFrameSize_p,
436 tEplMsgType MsgType_p,
437 tEplDllAsndServiceId ServiceId_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800438{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800439 tEplKernel Ret = kEplSuccessful;
440 tEplFrame *pTxFrame;
441 unsigned int uiHandle = EplDllkInstance_g.m_uiMaxTxFrames;
442 tEdrvTxBuffer *pTxBuffer = NULL;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800443
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800444 if (MsgType_p == kEplMsgTypeAsnd) {
445 // search for fixed Tx buffers
446 if (ServiceId_p == kEplDllAsndIdentResponse) {
447 uiHandle = EPL_DLLK_TXFRAME_IDENTRES;
448 } else if (ServiceId_p == kEplDllAsndStatusResponse) {
449 uiHandle = EPL_DLLK_TXFRAME_STATUSRES;
450 } else if ((ServiceId_p == kEplDllAsndNmtRequest)
451 || (ServiceId_p == kEplDllAsndNmtCommand)) {
452 uiHandle = EPL_DLLK_TXFRAME_NMTREQ;
453 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800454
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800455 if (uiHandle >= EplDllkInstance_g.m_uiMaxTxFrames) { // look for free entry
456 uiHandle = EPL_DLLK_TXFRAME_PREQ;
457 pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
458 for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames;
459 uiHandle++, pTxBuffer++) {
460 if (pTxBuffer->m_pbBuffer == NULL) { // free entry found
461 break;
462 }
463 }
464 }
465 } else if (MsgType_p == kEplMsgTypeNonEpl) {
466 uiHandle = EPL_DLLK_TXFRAME_NONEPL;
467 } else if (MsgType_p == kEplMsgTypePres) {
468 uiHandle = EPL_DLLK_TXFRAME_PRES;
469 } else if (MsgType_p == kEplMsgTypeSoc) {
470 uiHandle = EPL_DLLK_TXFRAME_SOC;
471 } else if (MsgType_p == kEplMsgTypeSoa) {
472 uiHandle = EPL_DLLK_TXFRAME_SOA;
473 } else { // look for free entry
474 uiHandle = EPL_DLLK_TXFRAME_PREQ;
475 pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
476 for (; uiHandle < EplDllkInstance_g.m_uiMaxTxFrames;
477 uiHandle++, pTxBuffer++) {
478 if (pTxBuffer->m_pbBuffer == NULL) { // free entry found
479 break;
480 }
481 }
482 if (pTxBuffer->m_pbBuffer != NULL) {
483 Ret = kEplEdrvNoFreeBufEntry;
484 goto Exit;
485 }
486 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800487
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800488 // test if requested entry is free
489 pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle];
490 if (pTxBuffer->m_pbBuffer != NULL) { // entry is not free
491 Ret = kEplEdrvNoFreeBufEntry;
492 goto Exit;
493 }
494 // setup Tx buffer
495 pTxBuffer->m_EplMsgType = MsgType_p;
496 pTxBuffer->m_uiMaxBufferLen = *puiFrameSize_p;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800497
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800498 Ret = EdrvAllocTxMsgBuffer(pTxBuffer);
499 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
500 goto Exit;
501 }
502 // because buffer size may be larger than requested
503 // memorize real length of frame
504 pTxBuffer->m_uiTxMsgLen = *puiFrameSize_p;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800505
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800506 // fill whole frame with 0
507 EPL_MEMSET(pTxBuffer->m_pbBuffer, 0, pTxBuffer->m_uiMaxBufferLen);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800508
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800509 pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800510
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800511 if (MsgType_p != kEplMsgTypeNonEpl) { // fill out Frame only if it is an EPL frame
512 // ethertype
513 AmiSetWordToBe(&pTxFrame->m_be_wEtherType,
514 EPL_C_DLL_ETHERTYPE_EPL);
515 // source node ID
516 AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId,
517 (BYTE) EplDllkInstance_g.m_DllConfigParam.
518 m_uiNodeId);
519 // source MAC address
520 EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0],
521 &EplDllkInstance_g.m_be_abSrcMac[0], 6);
522 switch (MsgType_p) {
523 case kEplMsgTypeAsnd:
524 // destination MAC address
525 AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
526 EPL_C_DLL_MULTICAST_ASND);
527 // destination node ID
528 switch (ServiceId_p) {
529 case kEplDllAsndIdentResponse:
530 case kEplDllAsndStatusResponse:
531 { // IdentResponses and StatusResponses are Broadcast
532 AmiSetByteToLe(&pTxFrame->
533 m_le_bDstNodeId,
534 (BYTE)
535 EPL_C_ADR_BROADCAST);
536 break;
537 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800538
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800539 default:
540 break;
541 }
542 // ASnd Service ID
543 AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_le_bServiceId,
544 ServiceId_p);
545 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800546
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800547 case kEplMsgTypeSoc:
548 // destination MAC address
549 AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
550 EPL_C_DLL_MULTICAST_SOC);
551 // destination node ID
552 AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
553 (BYTE) EPL_C_ADR_BROADCAST);
554 // reset Flags
555 //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (BYTE) 0);
556 //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (BYTE) 0);
557 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800558
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800559 case kEplMsgTypeSoa:
560 // destination MAC address
561 AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
562 EPL_C_DLL_MULTICAST_SOA);
563 // destination node ID
564 AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
565 (BYTE) EPL_C_ADR_BROADCAST);
566 // reset Flags
567 //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (BYTE) 0);
568 //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (BYTE) 0);
569 // EPL profile version
570 AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bEplVersion,
571 (BYTE) EPL_SPEC_VERSION);
572 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800573
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800574 case kEplMsgTypePres:
575 // destination MAC address
576 AmiSetQword48ToBe(&pTxFrame->m_be_abDstMac[0],
577 EPL_C_DLL_MULTICAST_PRES);
578 // destination node ID
579 AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
580 (BYTE) EPL_C_ADR_BROADCAST);
581 // reset Flags
582 //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (BYTE) 0);
583 //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (BYTE) 0);
584 // PDO size
585 //AmiSetWordToLe(&pTxFrame->m_Data.m_Pres.m_le_wSize, 0);
586 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800587
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800588 case kEplMsgTypePreq:
589 // reset Flags
590 //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (BYTE) 0);
591 //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (BYTE) 0);
592 // PDO size
593 //AmiSetWordToLe(&pTxFrame->m_Data.m_Preq.m_le_wSize, 0);
594 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800595
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800596 default:
597 break;
598 }
599 // EPL message type
600 AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (BYTE) MsgType_p);
601 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800602
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800603 *ppFrame_p = pTxFrame;
604 *puiFrameSize_p = pTxBuffer->m_uiMaxBufferLen;
605 *puiHandle_p = uiHandle;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800606
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800607 Exit:
608 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800609}
610
611//---------------------------------------------------------------------------
612//
613// Function: EplDllkDeleteTxFrame
614//
615// Description: deletes the buffer for a Tx frame and frees it in the
616// ethernet driver
617//
618// Parameters: uiHandle_p = IN: handle to frame buffer
619//
620// Returns: tEplKernel = error code
621//
622//
623// State:
624//
625//---------------------------------------------------------------------------
626
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800627tEplKernel EplDllkDeleteTxFrame(unsigned int uiHandle_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800628{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800629 tEplKernel Ret = kEplSuccessful;
630 tEdrvTxBuffer *pTxBuffer = NULL;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800631
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800632 if (uiHandle_p >= EplDllkInstance_g.m_uiMaxTxFrames) { // handle is not valid
633 Ret = kEplDllIllegalHdl;
634 goto Exit;
635 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800636
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800637 pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[uiHandle_p];
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800638
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800639 // mark buffer as free so that frame will not be send in future anymore
640 // $$$ d.k. What's up with running transmissions?
641 pTxBuffer->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
642 pTxBuffer->m_pbBuffer = NULL;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800643
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800644 // delete Tx buffer
645 Ret = EdrvReleaseTxMsgBuffer(pTxBuffer);
646 if (Ret != kEplSuccessful) { // error occured while releasing Tx frame
647 goto Exit;
648 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800649
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800650 Exit:
651 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800652}
653
654//---------------------------------------------------------------------------
655//
656// Function: EplDllkProcess
657//
658// Description: process the passed event
659//
660// Parameters: pEvent_p = event to be processed
661//
662// Returns: tEplKernel = error code
663//
664//
665// State:
666//
667//---------------------------------------------------------------------------
668
669tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
670{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800671 tEplKernel Ret = kEplSuccessful;
672 tEplFrame *pTxFrame;
673 tEdrvTxBuffer *pTxBuffer;
674 unsigned int uiHandle;
675 unsigned int uiFrameSize;
676 BYTE abMulticastMac[6];
677 tEplDllAsyncReqPriority AsyncReqPriority;
678 unsigned int uiFrameCount;
679 tEplNmtState NmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800680#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800681 tEplFrameInfo FrameInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800682#endif
683
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800684 switch (pEvent_p->m_EventType) {
685 case kEplEventTypeDllkCreate:
686 {
687 // $$$ reset ethernet driver
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800688
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800689 NmtState = *((tEplNmtState *) pEvent_p->m_pArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800690
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800691 // initialize flags for PRes and StatusRes
692 EplDllkInstance_g.m_bFlag1 = EPL_FRAME_FLAG1_EC;
693 EplDllkInstance_g.m_bMnFlag1 = 0;
694 EplDllkInstance_g.m_bFlag2 = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800695
696#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800697 // initialize linked node list
698 EplDllkInstance_g.m_pFirstNodeInfo = NULL;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800699#endif
700
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800701 // register TxFrames in Edrv
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800702
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800703 // IdentResponse
704 uiFrameSize = EPL_C_DLL_MINSIZE_IDENTRES;
705 Ret =
706 EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
707 &uiFrameSize, kEplMsgTypeAsnd,
708 kEplDllAsndIdentResponse);
709 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
710 goto Exit;
711 }
712 // EPL profile version
713 AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
714 m_IdentResponse.m_le_bEplProfileVersion,
715 (BYTE) EPL_SPEC_VERSION);
716 // FeatureFlags
717 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
718 m_IdentResponse.m_le_dwFeatureFlags,
719 EplDllkInstance_g.m_DllConfigParam.
720 m_dwFeatureFlags);
721 // MTU
722 AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
723 m_IdentResponse.m_le_wMtu,
724 (WORD) EplDllkInstance_g.
725 m_DllConfigParam.m_uiAsyncMtu);
726 // PollInSize
727 AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
728 m_IdentResponse.m_le_wPollInSize,
729 (WORD) EplDllkInstance_g.
730 m_DllConfigParam.
731 m_uiPreqActPayloadLimit);
732 // PollOutSize
733 AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
734 m_IdentResponse.m_le_wPollOutSize,
735 (WORD) EplDllkInstance_g.
736 m_DllConfigParam.
737 m_uiPresActPayloadLimit);
738 // ResponseTime / PresMaxLatency
739 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
740 m_IdentResponse.m_le_dwResponseTime,
741 EplDllkInstance_g.m_DllConfigParam.
742 m_dwPresMaxLatency);
743 // DeviceType
744 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
745 m_IdentResponse.m_le_dwDeviceType,
746 EplDllkInstance_g.m_DllIdentParam.
747 m_dwDeviceType);
748 // VendorId
749 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
750 m_IdentResponse.m_le_dwVendorId,
751 EplDllkInstance_g.m_DllIdentParam.
752 m_dwVendorId);
753 // ProductCode
754 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
755 m_IdentResponse.m_le_dwProductCode,
756 EplDllkInstance_g.m_DllIdentParam.
757 m_dwProductCode);
758 // RevisionNumber
759 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
760 m_IdentResponse.m_le_dwRevisionNumber,
761 EplDllkInstance_g.m_DllIdentParam.
762 m_dwRevisionNumber);
763 // SerialNumber
764 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
765 m_IdentResponse.m_le_dwSerialNumber,
766 EplDllkInstance_g.m_DllIdentParam.
767 m_dwSerialNumber);
768 // VendorSpecificExt1
769 AmiSetQword64ToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
770 m_IdentResponse.
771 m_le_qwVendorSpecificExt1,
772 EplDllkInstance_g.m_DllIdentParam.
773 m_qwVendorSpecificExt1);
774 // VerifyConfigurationDate
775 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
776 m_IdentResponse.
777 m_le_dwVerifyConfigurationDate,
778 EplDllkInstance_g.m_DllIdentParam.
779 m_dwVerifyConfigurationDate);
780 // VerifyConfigurationTime
781 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
782 m_IdentResponse.
783 m_le_dwVerifyConfigurationTime,
784 EplDllkInstance_g.m_DllIdentParam.
785 m_dwVerifyConfigurationTime);
786 // ApplicationSwDate
787 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
788 m_IdentResponse.
789 m_le_dwApplicationSwDate,
790 EplDllkInstance_g.m_DllIdentParam.
791 m_dwApplicationSwDate);
792 // ApplicationSwTime
793 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
794 m_IdentResponse.
795 m_le_dwApplicationSwTime,
796 EplDllkInstance_g.m_DllIdentParam.
797 m_dwApplicationSwTime);
798 // IPAddress
799 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
800 m_IdentResponse.m_le_dwIpAddress,
801 EplDllkInstance_g.m_DllIdentParam.
802 m_dwIpAddress);
803 // SubnetMask
804 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
805 m_IdentResponse.m_le_dwSubnetMask,
806 EplDllkInstance_g.m_DllIdentParam.
807 m_dwSubnetMask);
808 // DefaultGateway
809 AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
810 m_IdentResponse.m_le_dwDefaultGateway,
811 EplDllkInstance_g.m_DllIdentParam.
812 m_dwDefaultGateway);
813 // HostName
814 EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload.
815 m_IdentResponse.m_le_sHostname[0],
816 &EplDllkInstance_g.m_DllIdentParam.
817 m_sHostname[0],
818 sizeof(EplDllkInstance_g.m_DllIdentParam.
819 m_sHostname));
820 // VendorSpecificExt2
821 EPL_MEMCPY(&pTxFrame->m_Data.m_Asnd.m_Payload.
822 m_IdentResponse.m_le_abVendorSpecificExt2[0],
823 &EplDllkInstance_g.m_DllIdentParam.
824 m_abVendorSpecificExt2[0],
825 sizeof(EplDllkInstance_g.m_DllIdentParam.
826 m_abVendorSpecificExt2));
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800827
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800828 // StatusResponse
829 uiFrameSize = EPL_C_DLL_MINSIZE_STATUSRES;
830 Ret =
831 EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
832 &uiFrameSize, kEplMsgTypeAsnd,
833 kEplDllAsndStatusResponse);
834 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
835 goto Exit;
836 }
837 // PRes $$$ maybe move this to PDO module
838 if ((EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly ==
839 FALSE)
840 && (EplDllkInstance_g.m_DllConfigParam.m_uiPresActPayloadLimit >= 36)) { // it is not configured as async-only CN,
841 // so take part in isochronous phase and register PRes frame
842 uiFrameSize =
843 EplDllkInstance_g.m_DllConfigParam.
844 m_uiPresActPayloadLimit + 24;
845 Ret =
846 EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
847 &uiFrameSize,
848 kEplMsgTypePres,
849 kEplDllAsndNotDefined);
850 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
851 goto Exit;
852 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800853#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800854 // initially encode TPDO -> inform PDO module
855 FrameInfo.m_pFrame = pTxFrame;
856 FrameInfo.m_uiFrameSize = uiFrameSize;
857 Ret = EplPdokCbPdoTransmitted(&FrameInfo);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800858#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800859 // reset cycle counter
860 EplDllkInstance_g.m_uiCycleCount = 0;
861 } else { // it is an async-only CN
862 // fool EplDllkChangeState() to think that PRes was not expected
863 EplDllkInstance_g.m_uiCycleCount = 1;
864 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800865
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800866 // NMT request
867 uiFrameSize = EPL_C_IP_MAX_MTU;
868 Ret =
869 EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
870 &uiFrameSize, kEplMsgTypeAsnd,
871 kEplDllAsndNmtRequest);
872 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
873 goto Exit;
874 }
875 // mark Tx buffer as empty
876 EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen =
877 EPL_DLLK_BUFLEN_EMPTY;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800878
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800879 // non-EPL frame
880 uiFrameSize = EPL_C_IP_MAX_MTU;
881 Ret =
882 EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
883 &uiFrameSize,
884 kEplMsgTypeNonEpl,
885 kEplDllAsndNotDefined);
886 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
887 goto Exit;
888 }
889 // mark Tx buffer as empty
890 EplDllkInstance_g.m_pTxBuffer[uiHandle].m_uiTxMsgLen =
891 EPL_DLLK_BUFLEN_EMPTY;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800892
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800893 // register multicast MACs in ethernet driver
894 AmiSetQword48ToBe(&abMulticastMac[0],
895 EPL_C_DLL_MULTICAST_SOC);
896 Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
897 AmiSetQword48ToBe(&abMulticastMac[0],
898 EPL_C_DLL_MULTICAST_SOA);
899 Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
900 AmiSetQword48ToBe(&abMulticastMac[0],
901 EPL_C_DLL_MULTICAST_PRES);
902 Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
903 AmiSetQword48ToBe(&abMulticastMac[0],
904 EPL_C_DLL_MULTICAST_ASND);
905 Ret = EdrvDefineRxMacAddrEntry(abMulticastMac);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800906
907#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800908 if (NmtState >= kEplNmtMsNotActive) { // local node is MN
909 unsigned int uiIndex;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800910
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800911 // SoC
912 uiFrameSize = EPL_C_DLL_MINSIZE_SOC;
913 Ret =
914 EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
915 &uiFrameSize,
916 kEplMsgTypeSoc,
917 kEplDllAsndNotDefined);
918 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
919 goto Exit;
920 }
921 // SoA
922 uiFrameSize = EPL_C_DLL_MINSIZE_SOA;
923 Ret =
924 EplDllkCreateTxFrame(&uiHandle, &pTxFrame,
925 &uiFrameSize,
926 kEplMsgTypeSoa,
927 kEplDllAsndNotDefined);
928 if (Ret != kEplSuccessful) { // error occured while registering Tx frame
929 goto Exit;
930 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800931
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800932 for (uiIndex = 0;
933 uiIndex <
934 tabentries(EplDllkInstance_g.m_aNodeInfo);
935 uiIndex++) {
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800936// EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800937 EplDllkInstance_g.m_aNodeInfo[uiIndex].
938 m_wPresPayloadLimit =
939 (WORD) EplDllkInstance_g.
940 m_DllConfigParam.
941 m_uiIsochrRxMaxPayload;
942 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800943
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800944 // calculate cycle length
945 EplDllkInstance_g.m_ullFrameTimeout = 1000LL
946 *
947 ((unsigned long long)EplDllkInstance_g.
948 m_DllConfigParam.m_dwCycleLen);
949 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800950#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
951
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800952 Ret = EplDllkCalAsyncClearBuffer();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800953
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800954 break;
955 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800956
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800957 case kEplEventTypeDllkDestroy:
958 {
959 // destroy all data structures
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800960
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800961 NmtState = *((tEplNmtState *) pEvent_p->m_pArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800962
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800963 // delete Tx frames
964 Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_IDENTRES);
965 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
966 goto Exit;
967 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800968
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800969 Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_STATUSRES);
970 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
971 goto Exit;
972 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800973
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800974 Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_PRES);
975 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
976 goto Exit;
977 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800978
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800979 Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NMTREQ);
980 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
981 goto Exit;
982 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800983
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800984 Ret = EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_NONEPL);
985 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
986 goto Exit;
987 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800988#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800989 if (NmtState >= kEplNmtMsNotActive) { // local node was MN
990 unsigned int uiIndex;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800991
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800992 Ret =
993 EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOC);
994 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
995 goto Exit;
996 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800997
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800998 Ret =
999 EplDllkDeleteTxFrame(EPL_DLLK_TXFRAME_SOA);
1000 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
1001 goto Exit;
1002 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001003
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001004 for (uiIndex = 0;
1005 uiIndex <
1006 tabentries(EplDllkInstance_g.m_aNodeInfo);
1007 uiIndex++) {
1008 if (EplDllkInstance_g.
1009 m_aNodeInfo[uiIndex].
1010 m_pPreqTxBuffer != NULL) {
1011 uiHandle =
1012 EplDllkInstance_g.
1013 m_aNodeInfo[uiIndex].
1014 m_pPreqTxBuffer -
1015 EplDllkInstance_g.
1016 m_pTxBuffer;
1017 EplDllkInstance_g.
1018 m_aNodeInfo[uiIndex].
1019 m_pPreqTxBuffer = NULL;
1020 Ret =
1021 EplDllkDeleteTxFrame
1022 (uiHandle);
1023 if (Ret != kEplSuccessful) { // error occured while deregistering Tx frame
1024 goto Exit;
1025 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001026
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001027 }
1028 EplDllkInstance_g.m_aNodeInfo[uiIndex].
1029 m_wPresPayloadLimit = 0xFFFF;
1030 }
1031 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001032#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1033
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001034 // deregister multicast MACs in ethernet driver
1035 AmiSetQword48ToBe(&abMulticastMac[0],
1036 EPL_C_DLL_MULTICAST_SOC);
1037 Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
1038 AmiSetQword48ToBe(&abMulticastMac[0],
1039 EPL_C_DLL_MULTICAST_SOA);
1040 Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
1041 AmiSetQword48ToBe(&abMulticastMac[0],
1042 EPL_C_DLL_MULTICAST_PRES);
1043 Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
1044 AmiSetQword48ToBe(&abMulticastMac[0],
1045 EPL_C_DLL_MULTICAST_ASND);
1046 Ret = EdrvUndefineRxMacAddrEntry(abMulticastMac);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001047
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001048 // delete timer
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001049#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001050 Ret =
1051 EplTimerHighReskDeleteTimer(&EplDllkInstance_g.
1052 m_TimerHdlCycle);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001053#endif
1054
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001055 break;
1056 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001057
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001058 case kEplEventTypeDllkFillTx:
1059 {
1060 // fill TxBuffer of specified priority with new frame if empty
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001061
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001062 pTxFrame = NULL;
1063 AsyncReqPriority =
1064 *((tEplDllAsyncReqPriority *) pEvent_p->m_pArg);
1065 switch (AsyncReqPriority) {
1066 case kEplDllAsyncReqPrioNmt: // NMT request priority
1067 {
1068 pTxBuffer =
1069 &EplDllkInstance_g.
1070 m_pTxBuffer
1071 [EPL_DLLK_TXFRAME_NMTREQ];
1072 if (pTxBuffer->m_pbBuffer != NULL) { // NmtRequest does exist
1073 // check if frame is empty and not being filled
1074 if (pTxBuffer->m_uiTxMsgLen ==
1075 EPL_DLLK_BUFLEN_EMPTY) {
1076 // mark Tx buffer as filling is in process
1077 pTxBuffer->
1078 m_uiTxMsgLen =
1079 EPL_DLLK_BUFLEN_FILLING;
1080 // set max buffer size as input parameter
1081 uiFrameSize =
1082 pTxBuffer->
1083 m_uiMaxBufferLen;
1084 // copy frame from shared loop buffer to Tx buffer
1085 Ret =
1086 EplDllkCalAsyncGetTxFrame
1087 (pTxBuffer->
1088 m_pbBuffer,
1089 &uiFrameSize,
1090 AsyncReqPriority);
1091 if (Ret ==
1092 kEplSuccessful) {
1093 pTxFrame =
1094 (tEplFrame
1095 *)
1096 pTxBuffer->
1097 m_pbBuffer;
1098 Ret =
1099 EplDllkCheckFrame
1100 (pTxFrame,
1101 uiFrameSize);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001102
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001103 // set buffer valid
1104 pTxBuffer->
1105 m_uiTxMsgLen
1106 =
1107 uiFrameSize;
1108 } else if (Ret == kEplDllAsyncTxBufferEmpty) { // empty Tx buffer is not a real problem
1109 // so just ignore it
1110 Ret =
1111 kEplSuccessful;
1112 // mark Tx buffer as empty
1113 pTxBuffer->
1114 m_uiTxMsgLen
1115 =
1116 EPL_DLLK_BUFLEN_EMPTY;
1117 }
1118 }
1119 }
1120 break;
1121 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001122
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001123 default: // generic priority
1124 {
1125 pTxBuffer =
1126 &EplDllkInstance_g.
1127 m_pTxBuffer
1128 [EPL_DLLK_TXFRAME_NONEPL];
1129 if (pTxBuffer->m_pbBuffer != NULL) { // non-EPL frame does exist
1130 // check if frame is empty and not being filled
1131 if (pTxBuffer->m_uiTxMsgLen ==
1132 EPL_DLLK_BUFLEN_EMPTY) {
1133 // mark Tx buffer as filling is in process
1134 pTxBuffer->
1135 m_uiTxMsgLen =
1136 EPL_DLLK_BUFLEN_FILLING;
1137 // set max buffer size as input parameter
1138 uiFrameSize =
1139 pTxBuffer->
1140 m_uiMaxBufferLen;
1141 // copy frame from shared loop buffer to Tx buffer
1142 Ret =
1143 EplDllkCalAsyncGetTxFrame
1144 (pTxBuffer->
1145 m_pbBuffer,
1146 &uiFrameSize,
1147 AsyncReqPriority);
1148 if (Ret ==
1149 kEplSuccessful) {
1150 pTxFrame =
1151 (tEplFrame
1152 *)
1153 pTxBuffer->
1154 m_pbBuffer;
1155 Ret =
1156 EplDllkCheckFrame
1157 (pTxFrame,
1158 uiFrameSize);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001159
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001160 // set buffer valid
1161 pTxBuffer->
1162 m_uiTxMsgLen
1163 =
1164 uiFrameSize;
1165 } else if (Ret == kEplDllAsyncTxBufferEmpty) { // empty Tx buffer is not a real problem
1166 // so just ignore it
1167 Ret =
1168 kEplSuccessful;
1169 // mark Tx buffer as empty
1170 pTxBuffer->
1171 m_uiTxMsgLen
1172 =
1173 EPL_DLLK_BUFLEN_EMPTY;
1174 }
1175 }
1176 }
1177 break;
1178 }
1179 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001180
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001181 NmtState = EplNmtkGetNmtState();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001182
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001183 if ((NmtState == kEplNmtCsBasicEthernet) || (NmtState == kEplNmtMsBasicEthernet)) { // send frame immediately
1184 if (pTxFrame != NULL) { // frame is present
1185 // padding is done by Edrv or ethernet controller
1186 Ret = EdrvSendTxMsg(pTxBuffer);
1187 } else { // no frame moved to TxBuffer
1188 // check if TxBuffers contain unsent frames
1189 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame
1190 Ret =
1191 EdrvSendTxMsg
1192 (&EplDllkInstance_g.
1193 m_pTxBuffer
1194 [EPL_DLLK_TXFRAME_NMTREQ]);
1195 } else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // non-EPL Tx buffer contains a frame
1196 Ret =
1197 EdrvSendTxMsg
1198 (&EplDllkInstance_g.
1199 m_pTxBuffer
1200 [EPL_DLLK_TXFRAME_NONEPL]);
1201 }
1202 if (Ret == kEplInvalidOperation) { // ignore error if caused by already active transmission
1203 Ret = kEplSuccessful;
1204 }
1205 }
1206 // reset PRes flag 2
1207 EplDllkInstance_g.m_bFlag2 = 0;
1208 } else {
1209 // update Flag 2 (PR, RS)
1210 Ret =
1211 EplDllkCalAsyncGetTxCount(&AsyncReqPriority,
1212 &uiFrameCount);
1213 if (AsyncReqPriority == kEplDllAsyncReqPrioNmt) { // non-empty FIFO with hightest priority is for NMT requests
1214 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame
1215 // add one more frame
1216 uiFrameCount++;
1217 }
1218 } else { // non-empty FIFO with highest priority is for generic frames
1219 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // NMT request Tx buffer contains a frame
1220 // use NMT request FIFO, because of higher priority
1221 uiFrameCount = 1;
1222 AsyncReqPriority =
1223 kEplDllAsyncReqPrioNmt;
1224 } else if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_uiTxMsgLen > EPL_DLLK_BUFLEN_EMPTY) { // non-EPL Tx buffer contains a frame
1225 // use NMT request FIFO, because of higher priority
1226 // add one more frame
1227 uiFrameCount++;
1228 }
1229 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001230
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001231 if (uiFrameCount > 7) { // limit frame request to send counter to 7
1232 uiFrameCount = 7;
1233 }
1234 if (uiFrameCount > 0) {
1235 EplDllkInstance_g.m_bFlag2 =
1236 (BYTE) (((AsyncReqPriority <<
1237 EPL_FRAME_FLAG2_PR_SHIFT)
1238 & EPL_FRAME_FLAG2_PR)
1239 | (uiFrameCount &
1240 EPL_FRAME_FLAG2_RS));
1241 } else {
1242 EplDllkInstance_g.m_bFlag2 = 0;
1243 }
1244 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001245
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001246 break;
1247 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001248
1249#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001250 case kEplEventTypeDllkStartReducedCycle:
1251 {
1252 // start the reduced cycle by programming the cycle timer
1253 // it is issued by NMT MN module, when PreOp1 is entered
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001254
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001255 // clear the asynchronous queues
1256 Ret = EplDllkCalAsyncClearQueues();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001257
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001258 // reset cycle counter (everytime a SoA is triggerd in PreOp1 the counter is incremented
1259 // and when it reaches EPL_C_DLL_PREOP1_START_CYCLES the SoA may contain invitations)
1260 EplDllkInstance_g.m_uiCycleCount = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001261
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001262 // remove any CN from isochronous phase
1263 while (EplDllkInstance_g.m_pFirstNodeInfo != NULL) {
1264 EplDllkDeleteNode(EplDllkInstance_g.
1265 m_pFirstNodeInfo->m_uiNodeId);
1266 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001267
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001268 // change state to NonCyclic,
1269 // hence EplDllkChangeState() will not ignore the next call
1270 EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001271
1272#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001273 if (EplDllkInstance_g.m_DllConfigParam.
1274 m_dwAsyncSlotTimeout != 0) {
1275 Ret =
1276 EplTimerHighReskModifyTimerNs
1277 (&EplDllkInstance_g.m_TimerHdlCycle,
1278 EplDllkInstance_g.m_DllConfigParam.
1279 m_dwAsyncSlotTimeout,
1280 EplDllkCbMnTimerCycle, 0L, FALSE);
1281 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001282#endif
1283
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001284 break;
1285 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001286#endif
1287
1288#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001289 case kEplEventTypeDllkPresReady:
1290 {
1291 // post PRes to transmit FIFO
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001292
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001293 NmtState = EplNmtkGetNmtState();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001294
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001295 if (NmtState != kEplNmtCsBasicEthernet) {
1296 // Does PRes exist?
1297 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].m_pbBuffer != NULL) { // PRes does exist
1298 pTxFrame =
1299 (tEplFrame *) EplDllkInstance_g.
1300 m_pTxBuffer[EPL_DLLK_TXFRAME_PRES].
1301 m_pbBuffer;
1302 // update frame (NMT state, RD, RS, PR, MS, EN flags)
1303 if (NmtState < kEplNmtCsPreOperational2) { // NMT state is not PreOp2, ReadyToOp or Op
1304 // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater
1305 NmtState =
1306 kEplNmtCsPreOperational2;
1307 }
1308 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
1309 m_le_bNmtStatus,
1310 (BYTE) NmtState);
1311 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
1312 m_le_bFlag2,
1313 EplDllkInstance_g.
1314 m_bFlag2);
1315 if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op
1316 // $$$ reset only RD flag; set other flags appropriately
1317 AmiSetByteToLe(&pTxFrame->
1318 m_Data.m_Pres.
1319 m_le_bFlag1, 0);
1320 }
1321 // $$$ make function that updates Pres, StatusRes
1322 // mark PRes frame as ready for transmission
1323 Ret =
1324 EdrvTxMsgReady(&EplDllkInstance_g.
1325 m_pTxBuffer
1326 [EPL_DLLK_TXFRAME_PRES]);
1327 }
1328 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001329
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001330 break;
1331 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001332#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001333 default:
1334 {
1335 ASSERTMSG(FALSE,
1336 "EplDllkProcess(): unhandled event type!\n");
1337 }
1338 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001339
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001340 Exit:
1341 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001342}
1343
1344//---------------------------------------------------------------------------
1345//
1346// Function: EplDllkConfig
1347//
1348// Description: configure parameters of DLL
1349//
1350// Parameters: pDllConfigParam_p = configuration parameters
1351//
1352// Returns: tEplKernel = error code
1353//
1354//
1355// State:
1356//
1357//---------------------------------------------------------------------------
1358
1359tEplKernel EplDllkConfig(tEplDllConfigParam * pDllConfigParam_p)
1360{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001361 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001362
1363// d.k. check of NMT state disabled, because CycleLen is programmed at run time by MN without reset of CN
1364/*tEplNmtState NmtState;
1365
1366 NmtState = EplNmtkGetNmtState();
1367
1368 if (NmtState > kEplNmtGsResetConfiguration)
1369 { // only allowed in state DLL_GS_INIT
1370 Ret = kEplInvalidOperation;
1371 goto Exit;
1372 }
1373*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001374 EPL_MEMCPY(&EplDllkInstance_g.m_DllConfigParam, pDllConfigParam_p,
1375 (pDllConfigParam_p->m_uiSizeOfStruct <
1376 sizeof(tEplDllConfigParam) ? pDllConfigParam_p->
1377 m_uiSizeOfStruct : sizeof(tEplDllConfigParam)));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001378
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001379 if ((EplDllkInstance_g.m_DllConfigParam.m_dwCycleLen != 0)
1380 && (EplDllkInstance_g.m_DllConfigParam.m_dwLossOfFrameTolerance != 0)) { // monitor EPL cycle, calculate frame timeout
1381 EplDllkInstance_g.m_ullFrameTimeout = (1000LL
1382 *
1383 ((unsigned long long)
1384 EplDllkInstance_g.
1385 m_DllConfigParam.
1386 m_dwCycleLen))
1387 +
1388 ((unsigned long long)EplDllkInstance_g.m_DllConfigParam.
1389 m_dwLossOfFrameTolerance);
1390 } else {
1391 EplDllkInstance_g.m_ullFrameTimeout = 0LL;
1392 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001393
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001394 if (EplDllkInstance_g.m_DllConfigParam.m_fAsyncOnly != FALSE) { // it is configured as async-only CN
1395 // disable multiplexed cycle, that m_uiCycleCount will not be incremented spuriously on SoC
1396 EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt = 0;
1397 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001398//Exit:
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001399 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001400}
1401
1402//---------------------------------------------------------------------------
1403//
1404// Function: EplDllkSetIdentity
1405//
1406// Description: configure identity of local node for IdentResponse
1407//
1408// Parameters: pDllIdentParam_p = identity
1409//
1410// Returns: tEplKernel = error code
1411//
1412//
1413// State:
1414//
1415//---------------------------------------------------------------------------
1416
1417tEplKernel EplDllkSetIdentity(tEplDllIdentParam * pDllIdentParam_p)
1418{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001419 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001420
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001421 EPL_MEMCPY(&EplDllkInstance_g.m_DllIdentParam, pDllIdentParam_p,
1422 (pDllIdentParam_p->m_uiSizeOfStruct <
1423 sizeof(tEplDllIdentParam) ? pDllIdentParam_p->
1424 m_uiSizeOfStruct : sizeof(tEplDllIdentParam)));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001425
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001426 // $$$ if IdentResponse frame exists update it
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001427
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001428 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001429}
1430
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001431//---------------------------------------------------------------------------
1432//
1433// Function: EplDllkRegAsyncHandler
1434//
1435// Description: registers handler for non-EPL frames
1436//
1437// Parameters: pfnDllkCbAsync_p = pointer to callback function
1438//
1439// Returns: tEplKernel = error code
1440//
1441//
1442// State:
1443//
1444//---------------------------------------------------------------------------
1445
1446tEplKernel EplDllkRegAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p)
1447{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001448 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001449
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001450 if (EplDllkInstance_g.m_pfnCbAsync == NULL) { // no handler registered yet
1451 EplDllkInstance_g.m_pfnCbAsync = pfnDllkCbAsync_p;
1452 } else { // handler already registered
1453 Ret = kEplDllCbAsyncRegistered;
1454 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001455
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001456 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001457}
1458
1459//---------------------------------------------------------------------------
1460//
1461// Function: EplDllkDeregAsyncHandler
1462//
1463// Description: deregisters handler for non-EPL frames
1464//
1465// Parameters: pfnDllkCbAsync_p = pointer to callback function
1466//
1467// Returns: tEplKernel = error code
1468//
1469//
1470// State:
1471//
1472//---------------------------------------------------------------------------
1473
1474tEplKernel EplDllkDeregAsyncHandler(tEplDllkCbAsync pfnDllkCbAsync_p)
1475{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001476 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001477
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001478 if (EplDllkInstance_g.m_pfnCbAsync == pfnDllkCbAsync_p) { // same handler is registered
1479 // deregister it
1480 EplDllkInstance_g.m_pfnCbAsync = NULL;
1481 } else { // wrong handler or no handler registered
1482 Ret = kEplDllCbAsyncRegistered;
1483 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001484
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001485 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001486}
1487
1488//---------------------------------------------------------------------------
1489//
1490// Function: EplDllkSetAsndServiceIdFilter()
1491//
1492// Description: sets the specified node ID filter for the specified
1493// AsndServiceId. It registers C_DLL_MULTICAST_ASND in ethernet
1494// driver if any AsndServiceId is open.
1495//
1496// Parameters: ServiceId_p = ASnd Service ID
1497// Filter_p = node ID filter
1498//
1499// Returns: tEplKernel = error code
1500//
1501//
1502// State:
1503//
1504//---------------------------------------------------------------------------
1505
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001506tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p,
1507 tEplDllAsndFilter Filter_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001508{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001509 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001510
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001511 if (ServiceId_p < tabentries(EplDllkInstance_g.m_aAsndFilter)) {
1512 EplDllkInstance_g.m_aAsndFilter[ServiceId_p] = Filter_p;
1513 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001514
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001515 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001516}
1517
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001518#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1519
1520//---------------------------------------------------------------------------
1521//
1522// Function: EplDllkSetFlag1OfNode()
1523//
1524// Description: sets Flag1 (for PReq and SoA) of the specified node ID.
1525//
1526// Parameters: uiNodeId_p = node ID
1527// bSoaFlag1_p = flag1
1528//
1529// Returns: tEplKernel = error code
1530//
1531//
1532// State:
1533//
1534//---------------------------------------------------------------------------
1535
1536tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
1537{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001538 tEplKernel Ret = kEplSuccessful;
1539 tEplDllkNodeInfo *pNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001540
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001541 pNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
1542 if (pNodeInfo == NULL) { // no node info structure available
1543 Ret = kEplDllNoNodeInfo;
1544 goto Exit;
1545 }
1546 // store flag1 in internal node info structure
1547 pNodeInfo->m_bSoaFlag1 = bSoaFlag1_p;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001548
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001549 Exit:
1550 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001551}
1552
1553//---------------------------------------------------------------------------
1554//
1555// Function: EplDllkGetFirstNodeInfo()
1556//
1557// Description: returns first info structure of first node in isochronous phase.
1558// It is only useful for ErrorHandlerk module.
1559//
1560// Parameters: ppNodeInfo_p = pointer to pointer of internal node info structure
1561//
1562// Returns: tEplKernel = error code
1563//
1564//
1565// State:
1566//
1567//---------------------------------------------------------------------------
1568
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001569tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001570{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001571 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001572
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001573 *ppNodeInfo_p = EplDllkInstance_g.m_pFirstNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001574
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001575 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001576}
1577
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001578//---------------------------------------------------------------------------
1579//
1580// Function: EplDllkAddNode()
1581//
1582// Description: adds the specified node to the isochronous phase.
1583//
1584// Parameters: pNodeInfo_p = pointer of node info structure
1585//
1586// Returns: tEplKernel = error code
1587//
1588//
1589// State:
1590//
1591//---------------------------------------------------------------------------
1592
1593tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p)
1594{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001595 tEplKernel Ret = kEplSuccessful;
1596 tEplDllkNodeInfo *pIntNodeInfo;
1597 tEplDllkNodeInfo **ppIntNodeInfo;
1598 unsigned int uiHandle;
1599 tEplFrame *pFrame;
1600 unsigned int uiFrameSize;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001601
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001602 pIntNodeInfo = EplDllkGetNodeInfo(pNodeInfo_p->m_uiNodeId);
1603 if (pIntNodeInfo == NULL) { // no node info structure available
1604 Ret = kEplDllNoNodeInfo;
1605 goto Exit;
1606 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001607
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001608 EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkAddNode,
1609 pNodeInfo_p->m_uiNodeId, 0);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001610
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001611 // copy node configuration
1612 pIntNodeInfo->m_dwPresTimeout = pNodeInfo_p->m_dwPresTimeout;
1613 pIntNodeInfo->m_wPresPayloadLimit = pNodeInfo_p->m_wPresPayloadLimit;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001614
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001615 // $$$ d.k.: actually add node only if MN. On CN it is sufficient to update the node configuration
1616 if (pNodeInfo_p->m_uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // we shall send PRes ourself
1617 // insert our node at the end of the list
1618 ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
1619 while ((*ppIntNodeInfo != NULL)
1620 && ((*ppIntNodeInfo)->m_pNextNodeInfo != NULL)) {
1621 ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
1622 }
1623 if (*ppIntNodeInfo != NULL) {
1624 if ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId) { // node was already added to list
1625 // $$$ d.k. maybe this should be an error
1626 goto Exit;
1627 } else { // add our node at the end of the list
1628 ppIntNodeInfo =
1629 &(*ppIntNodeInfo)->m_pNextNodeInfo;
1630 }
1631 }
1632 // set "PReq"-TxBuffer to PRes-TxBuffer
1633 pIntNodeInfo->m_pPreqTxBuffer =
1634 &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
1635 } else { // normal CN shall be added to isochronous phase
1636 // insert node into list in ascending order
1637 ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
1638 while ((*ppIntNodeInfo != NULL)
1639 && ((*ppIntNodeInfo)->m_uiNodeId <
1640 pNodeInfo_p->m_uiNodeId)
1641 && ((*ppIntNodeInfo)->m_uiNodeId !=
1642 EplDllkInstance_g.m_DllConfigParam.m_uiNodeId)) {
1643 ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
1644 }
1645 if ((*ppIntNodeInfo != NULL) && ((*ppIntNodeInfo)->m_uiNodeId == pNodeInfo_p->m_uiNodeId)) { // node was already added to list
1646 // $$$ d.k. maybe this should be an error
1647 goto Exit;
1648 }
1649 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001650
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001651 // initialize elements of internal node info structure
1652 pIntNodeInfo->m_bSoaFlag1 = 0;
1653 pIntNodeInfo->m_fSoftDelete = FALSE;
1654 pIntNodeInfo->m_NmtState = kEplNmtCsNotActive;
1655 if (pIntNodeInfo->m_pPreqTxBuffer == NULL) { // create TxBuffer entry
1656 uiFrameSize = pNodeInfo_p->m_wPreqPayloadLimit + 24;
1657 Ret =
1658 EplDllkCreateTxFrame(&uiHandle, &pFrame, &uiFrameSize,
1659 kEplMsgTypePreq,
1660 kEplDllAsndNotDefined);
1661 if (Ret != kEplSuccessful) {
1662 goto Exit;
1663 }
1664 pIntNodeInfo->m_pPreqTxBuffer =
1665 &EplDllkInstance_g.m_pTxBuffer[uiHandle];
1666 AmiSetByteToLe(&pFrame->m_le_bDstNodeId,
1667 (BYTE) pNodeInfo_p->m_uiNodeId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001668
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001669 // set up destination MAC address
1670 EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr,
1671 6);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001672
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001673#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
1674 {
1675 tEplFrameInfo FrameInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001676
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001677 // initially encode TPDO -> inform PDO module
1678 FrameInfo.m_pFrame = pFrame;
1679 FrameInfo.m_uiFrameSize = uiFrameSize;
1680 Ret = EplPdokCbPdoTransmitted(&FrameInfo);
1681 }
1682#endif
1683 }
1684 pIntNodeInfo->m_ulDllErrorEvents = 0L;
1685 // add node to list
1686 pIntNodeInfo->m_pNextNodeInfo = *ppIntNodeInfo;
1687 *ppIntNodeInfo = pIntNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001688
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001689 Exit:
1690 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001691}
1692
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001693//---------------------------------------------------------------------------
1694//
1695// Function: EplDllkDeleteNode()
1696//
1697// Description: removes the specified node from the isochronous phase.
1698//
1699// Parameters: uiNodeId_p = node ID
1700//
1701// Returns: tEplKernel = error code
1702//
1703//
1704// State:
1705//
1706//---------------------------------------------------------------------------
1707
1708tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p)
1709{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001710 tEplKernel Ret = kEplSuccessful;
1711 tEplDllkNodeInfo *pIntNodeInfo;
1712 tEplDllkNodeInfo **ppIntNodeInfo;
1713 unsigned int uiHandle;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001714
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001715 pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
1716 if (pIntNodeInfo == NULL) { // no node info structure available
1717 Ret = kEplDllNoNodeInfo;
1718 goto Exit;
1719 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001720
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001721 EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkDelNode, uiNodeId_p, 0);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001722
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001723 // search node in whole list
1724 ppIntNodeInfo = &EplDllkInstance_g.m_pFirstNodeInfo;
1725 while ((*ppIntNodeInfo != NULL)
1726 && ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) {
1727 ppIntNodeInfo = &(*ppIntNodeInfo)->m_pNextNodeInfo;
1728 }
1729 if ((*ppIntNodeInfo == NULL) || ((*ppIntNodeInfo)->m_uiNodeId != uiNodeId_p)) { // node was not found in list
1730 // $$$ d.k. maybe this should be an error
1731 goto Exit;
1732 }
1733 // remove node from list
1734 *ppIntNodeInfo = pIntNodeInfo->m_pNextNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001735
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001736 if ((pIntNodeInfo->m_pPreqTxBuffer != NULL)
1737 && (pIntNodeInfo->m_pPreqTxBuffer != &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) { // delete TxBuffer entry
1738 uiHandle =
1739 pIntNodeInfo->m_pPreqTxBuffer -
1740 EplDllkInstance_g.m_pTxBuffer;
1741 pIntNodeInfo->m_pPreqTxBuffer = NULL;
1742 Ret = EplDllkDeleteTxFrame(uiHandle);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001743/* if (Ret != kEplSuccessful)
1744 {
1745 goto Exit;
1746 }*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001747 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001748
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001749 Exit:
1750 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001751}
1752
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001753//---------------------------------------------------------------------------
1754//
1755// Function: EplDllkSoftDeleteNode()
1756//
1757// Description: removes the specified node not immediately from the isochronous phase.
1758// Instead the will be removed after error (late/loss PRes) without
1759// charging the error.
1760//
1761// Parameters: uiNodeId_p = node ID
1762//
1763// Returns: tEplKernel = error code
1764//
1765//
1766// State:
1767//
1768//---------------------------------------------------------------------------
1769
1770tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p)
1771{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001772 tEplKernel Ret = kEplSuccessful;
1773 tEplDllkNodeInfo *pIntNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001774
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001775 pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId_p);
1776 if (pIntNodeInfo == NULL) { // no node info structure available
1777 Ret = kEplDllNoNodeInfo;
1778 goto Exit;
1779 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001780
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001781 EPL_DLLK_DBG_POST_TRACE_VALUE(kEplEventTypeDllkSoftDelNode,
1782 uiNodeId_p, 0);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001783
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001784 pIntNodeInfo->m_fSoftDelete = TRUE;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001785
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001786 Exit:
1787 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001788}
1789
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001790#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1791
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001792//=========================================================================//
1793// //
1794// P R I V A T E F U N C T I O N S //
1795// //
1796//=========================================================================//
1797
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001798//---------------------------------------------------------------------------
1799//
1800// Function: EplDllkChangeState
1801//
1802// Description: change DLL state on event and diagnose some communication errors
1803//
1804// Parameters: NmtEvent_p = DLL event (wrapped in NMT event)
1805//
1806// Returns: tEplKernel = error code
1807//
1808//
1809// State:
1810//
1811//---------------------------------------------------------------------------
1812
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001813static tEplKernel EplDllkChangeState(tEplNmtEvent NmtEvent_p,
1814 tEplNmtState NmtState_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001815{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001816 tEplKernel Ret = kEplSuccessful;
1817 tEplEvent Event;
1818 tEplErrorHandlerkEvent DllEvent;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001819
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001820 DllEvent.m_ulDllErrorEvents = 0;
1821 DllEvent.m_uiNodeId = 0;
1822 DllEvent.m_NmtState = NmtState_p;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001823
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001824 switch (NmtState_p) {
1825 case kEplNmtGsOff:
1826 case kEplNmtGsInitialising:
1827 case kEplNmtGsResetApplication:
1828 case kEplNmtGsResetCommunication:
1829 case kEplNmtGsResetConfiguration:
1830 case kEplNmtCsBasicEthernet:
1831 // enter DLL_GS_INIT
1832 EplDllkInstance_g.m_DllState = kEplDllGsInit;
1833 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001834
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001835 case kEplNmtCsNotActive:
1836 case kEplNmtCsPreOperational1:
1837 // reduced EPL cycle is active
1838 if (NmtEvent_p == kEplNmtEventDllCeSoc) { // SoC received
1839 // enter DLL_CS_WAIT_PREQ
1840 EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
1841 } else {
1842 // enter DLL_GS_INIT
1843 EplDllkInstance_g.m_DllState = kEplDllGsInit;
1844 }
1845 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001846
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001847 case kEplNmtCsPreOperational2:
1848 case kEplNmtCsReadyToOperate:
1849 case kEplNmtCsOperational:
1850 // full EPL cycle is active
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001851
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001852 switch (EplDllkInstance_g.m_DllState) {
1853 case kEplDllCsWaitPreq:
1854 switch (NmtEvent_p) {
1855 // DLL_CT2
1856 case kEplNmtEventDllCePreq:
1857 // enter DLL_CS_WAIT_SOA
1858 DllEvent.m_ulDllErrorEvents |=
1859 EPL_DLL_ERR_CN_RECVD_PREQ;
1860 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
1861 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001862
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001863 // DLL_CT8
1864 case kEplNmtEventDllCeFrameTimeout:
1865 if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2,
1866 // because the previously configured cycle len
1867 // may be wrong.
1868 // 2008/10/15 d.k. If it would not be ignored,
1869 // we would go cyclically to PreOp1 and on next
1870 // SoC back to PreOp2.
1871 break;
1872 }
1873 // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
1874 DllEvent.m_ulDllErrorEvents |=
1875 EPL_DLL_ERR_CN_LOSS_SOA |
1876 EPL_DLL_ERR_CN_LOSS_SOC;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001877
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001878 // enter DLL_CS_WAIT_SOC
1879 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
1880 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001881
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001882 case kEplNmtEventDllCeSoa:
1883 // check if multiplexed and PReq should have been received in this cycle
1884 // and if >= NMT_CS_READY_TO_OPERATE
1885 if ((EplDllkInstance_g.m_uiCycleCount == 0)
1886 && (NmtState_p >= kEplNmtCsReadyToOperate)) { // report DLL_CEV_LOSS_OF_PREQ
1887 DllEvent.m_ulDllErrorEvents |=
1888 EPL_DLL_ERR_CN_LOSS_PREQ;
1889 }
1890 // enter DLL_CS_WAIT_SOC
1891 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
1892 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001893
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001894 // DLL_CT7
1895 case kEplNmtEventDllCeSoc:
1896 case kEplNmtEventDllCeAsnd:
1897 // report DLL_CEV_LOSS_SOA
1898 DllEvent.m_ulDllErrorEvents |=
1899 EPL_DLL_ERR_CN_LOSS_SOA;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001900
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001901 case kEplNmtEventDllCePres:
1902 default:
1903 // remain in this state
1904 break;
1905 }
1906 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001907
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001908 case kEplDllCsWaitSoc:
1909 switch (NmtEvent_p) {
1910 // DLL_CT1
1911 case kEplNmtEventDllCeSoc:
1912 // start of cycle and isochronous phase
1913 // enter DLL_CS_WAIT_PREQ
1914 EplDllkInstance_g.m_DllState =
1915 kEplDllCsWaitPreq;
1916 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001917
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001918 // DLL_CT4
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001919// case kEplNmtEventDllCePres:
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001920 case kEplNmtEventDllCeFrameTimeout:
1921 if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2,
1922 // because the previously configured cycle len
1923 // may be wrong.
1924 // 2008/10/15 d.k. If it would not be ignored,
1925 // we would go cyclically to PreOp1 and on next
1926 // SoC back to PreOp2.
1927 break;
1928 }
1929 // fall through
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001930
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001931 case kEplNmtEventDllCePreq:
1932 case kEplNmtEventDllCeSoa:
1933 // report DLL_CEV_LOSS_SOC
1934 DllEvent.m_ulDllErrorEvents |=
1935 EPL_DLL_ERR_CN_LOSS_SOC;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001936
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001937 case kEplNmtEventDllCeAsnd:
1938 default:
1939 // remain in this state
1940 break;
1941 }
1942 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001943
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001944 case kEplDllCsWaitSoa:
1945 switch (NmtEvent_p) {
1946 case kEplNmtEventDllCeFrameTimeout:
1947 // DLL_CT3
1948 if (NmtState_p == kEplNmtCsPreOperational2) { // ignore frame timeout in PreOp2,
1949 // because the previously configured cycle len
1950 // may be wrong.
1951 // 2008/10/15 d.k. If it would not be ignored,
1952 // we would go cyclically to PreOp1 and on next
1953 // SoC back to PreOp2.
1954 break;
1955 }
1956 // fall through
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001957
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001958 case kEplNmtEventDllCePreq:
1959 // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
1960 DllEvent.m_ulDllErrorEvents |=
1961 EPL_DLL_ERR_CN_LOSS_SOA |
1962 EPL_DLL_ERR_CN_LOSS_SOC;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001963
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001964 case kEplNmtEventDllCeSoa:
1965 // enter DLL_CS_WAIT_SOC
1966 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
1967 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001968
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001969 // DLL_CT9
1970 case kEplNmtEventDllCeSoc:
1971 // report DLL_CEV_LOSS_SOA
1972 DllEvent.m_ulDllErrorEvents |=
1973 EPL_DLL_ERR_CN_LOSS_SOA;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001974
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001975 // enter DLL_CS_WAIT_PREQ
1976 EplDllkInstance_g.m_DllState =
1977 kEplDllCsWaitPreq;
1978 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001979
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001980 // DLL_CT10
1981 case kEplNmtEventDllCeAsnd:
1982 // report DLL_CEV_LOSS_SOA
1983 DllEvent.m_ulDllErrorEvents |=
1984 EPL_DLL_ERR_CN_LOSS_SOA;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001985
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001986 case kEplNmtEventDllCePres:
1987 default:
1988 // remain in this state
1989 break;
1990 }
1991 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001992
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001993 case kEplDllGsInit:
1994 // enter DLL_CS_WAIT_PREQ
1995 EplDllkInstance_g.m_DllState = kEplDllCsWaitPreq;
1996 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001997
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001998 default:
1999 break;
2000 }
2001 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002002
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002003 case kEplNmtCsStopped:
2004 // full EPL cycle is active, but without PReq/PRes
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002005
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002006 switch (EplDllkInstance_g.m_DllState) {
2007 case kEplDllCsWaitPreq:
2008 switch (NmtEvent_p) {
2009 // DLL_CT2
2010 case kEplNmtEventDllCePreq:
2011 // enter DLL_CS_WAIT_SOA
2012 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
2013 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002014
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002015 // DLL_CT8
2016 case kEplNmtEventDllCeFrameTimeout:
2017 // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
2018 DllEvent.m_ulDllErrorEvents |=
2019 EPL_DLL_ERR_CN_LOSS_SOA |
2020 EPL_DLL_ERR_CN_LOSS_SOC;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002021
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002022 case kEplNmtEventDllCeSoa:
2023 // NMT_CS_STOPPED active
2024 // it is Ok if no PReq was received
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002025
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002026 // enter DLL_CS_WAIT_SOC
2027 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
2028 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002029
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002030 // DLL_CT7
2031 case kEplNmtEventDllCeSoc:
2032 case kEplNmtEventDllCeAsnd:
2033 // report DLL_CEV_LOSS_SOA
2034 DllEvent.m_ulDllErrorEvents |=
2035 EPL_DLL_ERR_CN_LOSS_SOA;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002036
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002037 case kEplNmtEventDllCePres:
2038 default:
2039 // remain in this state
2040 break;
2041 }
2042 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002043
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002044 case kEplDllCsWaitSoc:
2045 switch (NmtEvent_p) {
2046 // DLL_CT1
2047 case kEplNmtEventDllCeSoc:
2048 // start of cycle and isochronous phase
2049 // enter DLL_CS_WAIT_SOA
2050 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
2051 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002052
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002053 // DLL_CT4
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002054// case kEplNmtEventDllCePres:
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002055 case kEplNmtEventDllCePreq:
2056 case kEplNmtEventDllCeSoa:
2057 case kEplNmtEventDllCeFrameTimeout:
2058 // report DLL_CEV_LOSS_SOC
2059 DllEvent.m_ulDllErrorEvents |=
2060 EPL_DLL_ERR_CN_LOSS_SOC;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002061
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002062 case kEplNmtEventDllCeAsnd:
2063 default:
2064 // remain in this state
2065 break;
2066 }
2067 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002068
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002069 case kEplDllCsWaitSoa:
2070 switch (NmtEvent_p) {
2071 // DLL_CT3
2072 case kEplNmtEventDllCeFrameTimeout:
2073 // report DLL_CEV_LOSS_SOC and DLL_CEV_LOSS_SOA
2074 DllEvent.m_ulDllErrorEvents |=
2075 EPL_DLL_ERR_CN_LOSS_SOA |
2076 EPL_DLL_ERR_CN_LOSS_SOC;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002077
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002078 case kEplNmtEventDllCeSoa:
2079 // enter DLL_CS_WAIT_SOC
2080 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoc;
2081 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002082
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002083 // DLL_CT9
2084 case kEplNmtEventDllCeSoc:
2085 // report DLL_CEV_LOSS_SOA
2086 DllEvent.m_ulDllErrorEvents |=
2087 EPL_DLL_ERR_CN_LOSS_SOA;
2088 // remain in DLL_CS_WAIT_SOA
2089 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002090
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002091 // DLL_CT10
2092 case kEplNmtEventDllCeAsnd:
2093 // report DLL_CEV_LOSS_SOA
2094 DllEvent.m_ulDllErrorEvents |=
2095 EPL_DLL_ERR_CN_LOSS_SOA;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002096
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002097 case kEplNmtEventDllCePreq:
2098 // NMT_CS_STOPPED active and we do not expect any PReq
2099 // so just ignore it
2100 case kEplNmtEventDllCePres:
2101 default:
2102 // remain in this state
2103 break;
2104 }
2105 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002106
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002107 case kEplDllGsInit:
2108 default:
2109 // enter DLL_CS_WAIT_PREQ
2110 EplDllkInstance_g.m_DllState = kEplDllCsWaitSoa;
2111 break;
2112 }
2113 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002114
2115#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002116 case kEplNmtMsNotActive:
2117 case kEplNmtMsBasicEthernet:
2118 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002119
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002120 case kEplNmtMsPreOperational1:
2121 // reduced EPL cycle is active
2122 if (EplDllkInstance_g.m_DllState != kEplDllMsNonCyclic) { // stop cycle timer
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002123#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002124 Ret =
2125 EplTimerHighReskDeleteTimer(&EplDllkInstance_g.
2126 m_TimerHdlCycle);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002127#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002128 EplDllkInstance_g.m_DllState = kEplDllMsNonCyclic;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002129
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002130 // stop further processing,
2131 // because it will be restarted by NMT MN module
2132 break;
2133 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002134
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002135 switch (NmtEvent_p) {
2136 case kEplNmtEventDllMeSocTrig:
2137 case kEplNmtEventDllCeAsnd:
2138 { // because of reduced EPL cycle SoA shall be triggered, not SoC
2139 tEplDllState DummyDllState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002140
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002141 Ret =
2142 EplDllkAsyncFrameNotReceived
2143 (EplDllkInstance_g.m_LastReqServiceId,
2144 EplDllkInstance_g.m_uiLastTargetNodeId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002145
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002146 // go ahead and send SoA
2147 Ret = EplDllkMnSendSoa(NmtState_p,
2148 &DummyDllState,
2149 (EplDllkInstance_g.
2150 m_uiCycleCount >=
2151 EPL_C_DLL_PREOP1_START_CYCLES));
2152 // increment cycle counter to detect if EPL_C_DLL_PREOP1_START_CYCLES empty cycles are elapsed
2153 EplDllkInstance_g.m_uiCycleCount++;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002154
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002155 // reprogram timer
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002156#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002157 if (EplDllkInstance_g.m_DllConfigParam.
2158 m_dwAsyncSlotTimeout != 0) {
2159 Ret =
2160 EplTimerHighReskModifyTimerNs
2161 (&EplDllkInstance_g.m_TimerHdlCycle,
2162 EplDllkInstance_g.m_DllConfigParam.
2163 m_dwAsyncSlotTimeout,
2164 EplDllkCbMnTimerCycle, 0L, FALSE);
2165 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002166#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002167 break;
2168 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002169
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002170 default:
2171 break;
2172 }
2173 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002174
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002175 case kEplNmtMsPreOperational2:
2176 case kEplNmtMsReadyToOperate:
2177 case kEplNmtMsOperational:
2178 // full EPL cycle is active
2179 switch (NmtEvent_p) {
2180 case kEplNmtEventDllMeSocTrig:
2181 {
2182 // update cycle counter
2183 if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) { // multiplexed cycle active
2184 EplDllkInstance_g.m_uiCycleCount =
2185 (EplDllkInstance_g.m_uiCycleCount +
2186 1) %
2187 EplDllkInstance_g.m_DllConfigParam.
2188 m_uiMultiplCycleCnt;
2189 // $$$ check multiplexed cycle restart
2190 // -> toggle MC flag
2191 // -> change node linked list
2192 } else { // non-multiplexed cycle active
2193 // start with first node in isochronous phase
2194 EplDllkInstance_g.m_pCurNodeInfo = NULL;
2195 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002196
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002197 switch (EplDllkInstance_g.m_DllState) {
2198 case kEplDllMsNonCyclic:
2199 { // start continuous cycle timer
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002200#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002201 Ret =
2202 EplTimerHighReskModifyTimerNs
2203 (&EplDllkInstance_g.
2204 m_TimerHdlCycle,
2205 EplDllkInstance_g.
2206 m_ullFrameTimeout,
2207 EplDllkCbMnTimerCycle, 0L,
2208 TRUE);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002209#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002210 // continue with sending SoC
2211 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002212
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002213 case kEplDllMsWaitAsnd:
2214 case kEplDllMsWaitSocTrig:
2215 { // if m_LastReqServiceId is still valid,
2216 // SoA was not correctly answered
2217 // and user part has to be informed
2218 Ret =
2219 EplDllkAsyncFrameNotReceived
2220 (EplDllkInstance_g.
2221 m_LastReqServiceId,
2222 EplDllkInstance_g.
2223 m_uiLastTargetNodeId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002224
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002225 // send SoC
2226 Ret = EplDllkMnSendSoc();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002227
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002228 // new DLL state
2229 EplDllkInstance_g.m_DllState =
2230 kEplDllMsWaitPreqTrig;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002231
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002232 // start WaitSoCPReq Timer
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002233#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002234 Ret =
2235 EplTimerHighReskModifyTimerNs
2236 (&EplDllkInstance_g.
2237 m_TimerHdlResponse,
2238 EplDllkInstance_g.
2239 m_DllConfigParam.
2240 m_dwWaitSocPreq,
2241 EplDllkCbMnTimerResponse,
2242 0L, FALSE);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002243#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002244 break;
2245 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002246
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002247 default:
2248 { // wrong DLL state / cycle time exceeded
2249 DllEvent.m_ulDllErrorEvents |=
2250 EPL_DLL_ERR_MN_CYCTIMEEXCEED;
2251 EplDllkInstance_g.m_DllState =
2252 kEplDllMsWaitSocTrig;
2253 break;
2254 }
2255 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002256
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002257 break;
2258 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002259
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002260 case kEplNmtEventDllMePresTimeout:
2261 {
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002262
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002263 switch (EplDllkInstance_g.m_DllState) {
2264 case kEplDllMsWaitPres:
2265 { // PRes not received
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002266
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002267 if (EplDllkInstance_g.m_pCurNodeInfo->m_fSoftDelete == FALSE) { // normal isochronous CN
2268 DllEvent.
2269 m_ulDllErrorEvents
2270 |=
2271 EPL_DLL_ERR_MN_CN_LOSS_PRES;
2272 DllEvent.m_uiNodeId =
2273 EplDllkInstance_g.
2274 m_pCurNodeInfo->
2275 m_uiNodeId;
2276 } else { // CN shall be deleted softly
2277 Event.m_EventSink =
2278 kEplEventSinkDllkCal;
2279 Event.m_EventType =
2280 kEplEventTypeDllkSoftDelNode;
2281 // $$$ d.k. set Event.m_NetTime to current time
2282 Event.m_uiSize =
2283 sizeof(unsigned
2284 int);
2285 Event.m_pArg =
2286 &EplDllkInstance_g.
2287 m_pCurNodeInfo->
2288 m_uiNodeId;
2289 Ret =
2290 EplEventkPost
2291 (&Event);
2292 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002293
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002294 // continue with sending next PReq
2295 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002296
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002297 case kEplDllMsWaitPreqTrig:
2298 {
2299 // send next PReq
2300 Ret =
2301 EplDllkMnSendPreq
2302 (NmtState_p,
2303 &EplDllkInstance_g.
2304 m_DllState);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002305
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002306 break;
2307 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002308
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002309 default:
2310 { // wrong DLL state
2311 break;
2312 }
2313 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002314
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002315 break;
2316 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002317
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002318 case kEplNmtEventDllCePres:
2319 {
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002320
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002321 switch (EplDllkInstance_g.m_DllState) {
2322 case kEplDllMsWaitPres:
2323 { // PRes received
2324 // send next PReq
2325 Ret =
2326 EplDllkMnSendPreq
2327 (NmtState_p,
2328 &EplDllkInstance_g.
2329 m_DllState);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002330
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002331 break;
2332 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002333
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002334 default:
2335 { // wrong DLL state
2336 break;
2337 }
2338 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002339
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002340 break;
2341 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002342
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002343 case kEplNmtEventDllMeSoaTrig:
2344 {
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002345
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002346 switch (EplDllkInstance_g.m_DllState) {
2347 case kEplDllMsWaitSoaTrig:
2348 { // MN PRes sent
2349 // send SoA
2350 Ret =
2351 EplDllkMnSendSoa(NmtState_p,
2352 &EplDllkInstance_g.
2353 m_DllState,
2354 TRUE);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002355
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002356 break;
2357 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002358
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002359 default:
2360 { // wrong DLL state
2361 break;
2362 }
2363 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002364
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002365 break;
2366 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002367
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002368 case kEplNmtEventDllCeAsnd:
2369 { // ASnd has been received, but it may be not the requested one
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002370/*
2371 // report if SoA was correctly answered
2372 Ret = EplDllkAsyncFrameNotReceived(EplDllkInstance_g.m_LastReqServiceId,
2373 EplDllkInstance_g.m_uiLastTargetNodeId);
2374*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002375 if (EplDllkInstance_g.m_DllState ==
2376 kEplDllMsWaitAsnd) {
2377 EplDllkInstance_g.m_DllState =
2378 kEplDllMsWaitSocTrig;
2379 }
2380 break;
2381 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002382
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002383 default:
2384 break;
2385 }
2386 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002387#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
2388
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002389 default:
2390 break;
2391 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002392
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002393 if (DllEvent.m_ulDllErrorEvents != 0) { // error event set -> post it to error handler
2394 Event.m_EventSink = kEplEventSinkErrk;
2395 Event.m_EventType = kEplEventTypeDllError;
2396 // $$$ d.k. set Event.m_NetTime to current time
2397 Event.m_uiSize = sizeof(DllEvent);
2398 Event.m_pArg = &DllEvent;
2399 Ret = EplEventkPost(&Event);
2400 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002401
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002402 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002403}
2404
2405//---------------------------------------------------------------------------
2406//
2407// Function: EplDllkCbFrameReceived()
2408//
2409// Description: called from EdrvInterruptHandler()
2410//
2411// Parameters: pRxBuffer_p = receive buffer structure
2412//
2413// Returns: (none)
2414//
2415//
2416// State:
2417//
2418//---------------------------------------------------------------------------
2419
2420static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
2421{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002422 tEplKernel Ret = kEplSuccessful;
2423 tEplNmtState NmtState;
2424 tEplNmtEvent NmtEvent = kEplNmtEventNoEvent;
2425 tEplEvent Event;
2426 tEplFrame *pFrame;
2427 tEplFrame *pTxFrame;
2428 tEdrvTxBuffer *pTxBuffer = NULL;
2429 tEplFrameInfo FrameInfo;
2430 tEplMsgType MsgType;
2431 tEplDllReqServiceId ReqServiceId;
2432 unsigned int uiAsndServiceId;
2433 unsigned int uiNodeId;
2434 BYTE bFlag1;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002435
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002436 BENCHMARK_MOD_02_SET(3);
2437 NmtState = EplNmtkGetNmtState();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002438
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002439 if (NmtState <= kEplNmtGsResetConfiguration) {
2440 goto Exit;
2441 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002442
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002443 pFrame = (tEplFrame *) pRxBuffer_p->m_pbBuffer;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002444
2445#if EDRV_EARLY_RX_INT != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002446 switch (pRxBuffer_p->m_BufferInFrame) {
2447 case kEdrvBufferFirstInFrame:
2448 {
2449 MsgType =
2450 (tEplMsgType) AmiGetByteFromLe(&pFrame->
2451 m_le_bMessageType);
2452 if (MsgType == kEplMsgTypePreq) {
2453 if (EplDllkInstance_g.m_DllState == kEplDllCsWaitPreq) { // PReq expected and actually received
2454 // d.k.: The condition above is sufficent, because EPL cycle is active
2455 // and no non-EPL frame shall be received in isochronous phase.
2456 // start transmission PRes
2457 // $$$ What if Tx buffer is invalid?
2458 pTxBuffer =
2459 &EplDllkInstance_g.
2460 m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002461#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002462 Ret = EdrvTxMsgStart(pTxBuffer);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002463#else
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002464 pTxFrame =
2465 (tEplFrame *) pTxBuffer->m_pbBuffer;
2466 // update frame (NMT state, RD, RS, PR, MS, EN flags)
2467 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
2468 m_le_bNmtStatus,
2469 (BYTE) NmtState);
2470 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
2471 m_le_bFlag2,
2472 EplDllkInstance_g.
2473 m_bFlag2);
2474 if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op
2475 // $$$ reset only RD flag; set other flags appropriately
2476 AmiSetByteToLe(&pTxFrame->
2477 m_Data.m_Pres.
2478 m_le_bFlag1, 0);
2479 }
2480 // $$$ make function that updates Pres, StatusRes
2481 // send PRes frame
2482 Ret = EdrvSendTxMsg(pTxBuffer);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002483#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002484 }
2485 }
2486 goto Exit;
2487 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002488
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002489 case kEdrvBufferMiddleInFrame:
2490 {
2491 goto Exit;
2492 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002493
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002494 case kEdrvBufferLastInFrame:
2495 {
2496 break;
2497 }
2498 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002499#endif
2500
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002501 FrameInfo.m_pFrame = pFrame;
2502 FrameInfo.m_uiFrameSize = pRxBuffer_p->m_uiRxMsgLen;
2503 FrameInfo.m_NetTime.m_dwNanoSec = pRxBuffer_p->m_NetTime.m_dwNanoSec;
2504 FrameInfo.m_NetTime.m_dwSec = pRxBuffer_p->m_NetTime.m_dwSec;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002505
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002506 if (AmiGetWordFromBe(&pFrame->m_be_wEtherType) != EPL_C_DLL_ETHERTYPE_EPL) { // non-EPL frame
2507 //TRACE2("EplDllkCbFrameReceived: pfnCbAsync=0x%p SrcMAC=0x%llx\n", EplDllkInstance_g.m_pfnCbAsync, AmiGetQword48FromBe(pFrame->m_be_abSrcMac));
2508 if (EplDllkInstance_g.m_pfnCbAsync != NULL) { // handler for async frames is registered
2509 EplDllkInstance_g.m_pfnCbAsync(&FrameInfo);
2510 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002511
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002512 goto Exit;
2513 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002514
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002515 MsgType = (tEplMsgType) AmiGetByteFromLe(&pFrame->m_le_bMessageType);
2516 switch (MsgType) {
2517 case kEplMsgTypePreq:
2518 {
2519 // PReq frame
2520 // d.k.: (we assume that this PReq frame is intended for us and don't check DstNodeId)
2521 if (AmiGetByteFromLe(&pFrame->m_le_bDstNodeId) != EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // this PReq is not intended for us
2522 goto Exit;
2523 }
2524 NmtEvent = kEplNmtEventDllCePreq;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002525
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002526 if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type
2527 break;
2528 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002529#if EDRV_EARLY_RX_INT == FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002530 if (NmtState >= kEplNmtCsPreOperational2) { // respond to and process PReq frames only in PreOp2, ReadyToOp and Op
2531 // Does PRes exist?
2532 pTxBuffer =
2533 &EplDllkInstance_g.
2534 m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
2535 if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002536#if (EPL_DLL_PRES_READY_AFTER_SOA != FALSE) || (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002537 EdrvTxMsgStart(pTxBuffer);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002538#else
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002539 pTxFrame =
2540 (tEplFrame *) pTxBuffer->m_pbBuffer;
2541 // update frame (NMT state, RD, RS, PR, MS, EN flags)
2542 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
2543 m_le_bNmtStatus,
2544 (BYTE) NmtState);
2545 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
2546 m_le_bFlag2,
2547 EplDllkInstance_g.
2548 m_bFlag2);
2549 bFlag1 =
2550 AmiGetByteFromLe(&pFrame->m_Data.
2551 m_Preq.
2552 m_le_bFlag1);
2553 // save EA flag
2554 EplDllkInstance_g.m_bMnFlag1 =
2555 (EplDllkInstance_g.
2556 m_bMnFlag1 & ~EPL_FRAME_FLAG1_EA)
2557 | (bFlag1 & EPL_FRAME_FLAG1_EA);
2558 // preserve MS flag
2559 bFlag1 &= EPL_FRAME_FLAG1_MS;
2560 // add EN flag from Error signaling module
2561 bFlag1 |=
2562 EplDllkInstance_g.
2563 m_bFlag1 & EPL_FRAME_FLAG1_EN;
2564 if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op
2565 // reset only RD flag
2566 AmiSetByteToLe(&pTxFrame->
2567 m_Data.m_Pres.
2568 m_le_bFlag1,
2569 bFlag1);
2570 } else { // leave RD flag untouched
2571 AmiSetByteToLe(&pTxFrame->
2572 m_Data.m_Pres.
2573 m_le_bFlag1,
2574 (AmiGetByteFromLe
2575 (&pTxFrame->
2576 m_Data.m_Pres.
2577 m_le_bFlag1) &
2578 EPL_FRAME_FLAG1_RD)
2579 | bFlag1);
2580 }
2581 // $$$ update EPL_DLL_PRES_READY_AFTER_* code
2582 // send PRes frame
2583 Ret = EdrvSendTxMsg(pTxBuffer);
2584 if (Ret != kEplSuccessful) {
2585 goto Exit;
2586 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002587#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002588 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002589#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002590 // inform PDO module
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002591#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002592 if (NmtState >= kEplNmtCsReadyToOperate) { // inform PDO module only in ReadyToOp and Op
2593 if (NmtState != kEplNmtCsOperational) {
2594 // reset RD flag and all other flags, but that does not matter, because they were processed above
2595 AmiSetByteToLe(&pFrame->m_Data.
2596 m_Preq.
2597 m_le_bFlag1, 0);
2598 }
2599 // compares real frame size and PDO size
2600 if ((unsigned
2601 int)(AmiGetWordFromLe(&pFrame->
2602 m_Data.
2603 m_Preq.
2604 m_le_wSize) +
2605 24)
2606 > FrameInfo.m_uiFrameSize) { // format error
2607 tEplErrorHandlerkEvent DllEvent;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002608
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002609 DllEvent.m_ulDllErrorEvents =
2610 EPL_DLL_ERR_INVALID_FORMAT;
2611 DllEvent.m_uiNodeId =
2612 AmiGetByteFromLe(&pFrame->
2613 m_le_bSrcNodeId);
2614 DllEvent.m_NmtState = NmtState;
2615 Event.m_EventSink =
2616 kEplEventSinkErrk;
2617 Event.m_EventType =
2618 kEplEventTypeDllError;
2619 Event.m_NetTime =
2620 FrameInfo.m_NetTime;
2621 Event.m_uiSize =
2622 sizeof(DllEvent);
2623 Event.m_pArg = &DllEvent;
2624 Ret = EplEventkPost(&Event);
2625 break;
2626 }
2627 // forward PReq frame as RPDO to PDO module
2628 Ret = EplPdokCbPdoReceived(&FrameInfo);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002629
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002630 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002631#if (EPL_DLL_PRES_READY_AFTER_SOC != FALSE)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002632 if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist
2633 // inform PDO module about PRes after PReq
2634 FrameInfo.m_pFrame =
2635 (tEplFrame *) pTxBuffer->m_pbBuffer;
2636 FrameInfo.m_uiFrameSize =
2637 pTxBuffer->m_uiMaxBufferLen;
2638 Ret =
2639 EplPdokCbPdoTransmitted(&FrameInfo);
2640 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002641#endif
2642#endif
2643
2644#if EDRV_EARLY_RX_INT == FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002645 // $$$ inform emergency protocol handling (error signaling module) about flags
2646 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002647#endif
2648
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002649 // reset cycle counter
2650 EplDllkInstance_g.m_uiCycleCount = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002651
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002652 break;
2653 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002654
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002655 case kEplMsgTypePres:
2656 {
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002657#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002658 tEplDllkNodeInfo *pIntNodeInfo;
2659 tEplHeartbeatEvent HeartbeatEvent;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002660#endif
2661
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002662 // PRes frame
2663 NmtEvent = kEplNmtEventDllCePres;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002664
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002665 uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002666
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002667 if ((NmtState >= kEplNmtCsPreOperational2)
2668 && (NmtState <= kEplNmtCsOperational)) { // process PRes frames only in PreOp2, ReadyToOp and Op of CN
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002669
2670#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002671 pIntNodeInfo = EplDllkGetNodeInfo(uiNodeId);
2672 if (pIntNodeInfo == NULL) { // no node info structure available
2673 Ret = kEplDllNoNodeInfo;
2674 goto Exit;
2675 }
2676 } else if (EplDllkInstance_g.m_DllState == kEplDllMsWaitPres) { // or process PRes frames in MsWaitPres
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002677
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002678 pIntNodeInfo = EplDllkInstance_g.m_pCurNodeInfo;
2679 if ((pIntNodeInfo == NULL) || (pIntNodeInfo->m_uiNodeId != uiNodeId)) { // ignore PRes, because it is from wrong CN
2680 // $$$ maybe post event to NmtMn module
2681 goto Exit;
2682 }
2683 // forward Flag2 to asynchronous scheduler
2684 bFlag1 =
2685 AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.
2686 m_Payload.m_StatusResponse.
2687 m_le_bFlag2);
2688 Ret =
2689 EplDllkCalAsyncSetPendingRequests(uiNodeId,
2690 ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002691
2692#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002693 } else { // ignore PRes, because it was received in wrong NMT state
2694 // but execute EplDllkChangeState() and post event to NMT module
2695 break;
2696 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002697
2698#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002699 { // check NMT state of CN
2700 HeartbeatEvent.m_wErrorCode = EPL_E_NO_ERROR;
2701 HeartbeatEvent.m_NmtState =
2702 (tEplNmtState) (AmiGetByteFromLe
2703 (&pFrame->m_Data.m_Pres.
2704 m_le_bNmtStatus) |
2705 EPL_NMT_TYPE_CS);
2706 if (pIntNodeInfo->m_NmtState != HeartbeatEvent.m_NmtState) { // NMT state of CN has changed -> post event to NmtMnu module
2707 if (pIntNodeInfo->m_fSoftDelete == FALSE) { // normal isochronous CN
2708 HeartbeatEvent.m_uiNodeId =
2709 uiNodeId;
2710 Event.m_EventSink =
2711 kEplEventSinkNmtMnu;
2712 Event.m_EventType =
2713 kEplEventTypeHeartbeat;
2714 Event.m_uiSize =
2715 sizeof(HeartbeatEvent);
2716 Event.m_pArg = &HeartbeatEvent;
2717 } else { // CN shall be deleted softly
2718 Event.m_EventSink =
2719 kEplEventSinkDllkCal;
2720 Event.m_EventType =
2721 kEplEventTypeDllkSoftDelNode;
2722 Event.m_uiSize =
2723 sizeof(unsigned int);
2724 Event.m_pArg =
2725 &pIntNodeInfo->m_uiNodeId;
2726 }
2727 Event.m_NetTime = FrameInfo.m_NetTime;
2728 Ret = EplEventkPost(&Event);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002729
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002730 // save current NMT state of CN in internal node structure
2731 pIntNodeInfo->m_NmtState =
2732 HeartbeatEvent.m_NmtState;
2733 }
2734 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002735#endif
2736
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002737 // inform PDO module
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002738#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002739 if ((NmtState != kEplNmtCsPreOperational2)
2740 && (NmtState != kEplNmtMsPreOperational2)) { // inform PDO module only in ReadyToOp and Op
2741 // compare real frame size and PDO size?
2742 if (((unsigned
2743 int)(AmiGetWordFromLe(&pFrame->m_Data.
2744 m_Pres.m_le_wSize) +
2745 24)
2746 > FrameInfo.m_uiFrameSize)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002747#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002748 ||
2749 (AmiGetWordFromLe
2750 (&pFrame->m_Data.m_Pres.m_le_wSize) >
2751 pIntNodeInfo->m_wPresPayloadLimit)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002752#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002753 ) { // format error
2754 tEplErrorHandlerkEvent DllEvent;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002755
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002756 DllEvent.m_ulDllErrorEvents =
2757 EPL_DLL_ERR_INVALID_FORMAT;
2758 DllEvent.m_uiNodeId = uiNodeId;
2759 DllEvent.m_NmtState = NmtState;
2760 Event.m_EventSink = kEplEventSinkErrk;
2761 Event.m_EventType =
2762 kEplEventTypeDllError;
2763 Event.m_NetTime = FrameInfo.m_NetTime;
2764 Event.m_uiSize = sizeof(DllEvent);
2765 Event.m_pArg = &DllEvent;
2766 Ret = EplEventkPost(&Event);
2767 break;
2768 }
2769 if ((NmtState != kEplNmtCsOperational)
2770 && (NmtState != kEplNmtMsOperational)) {
2771 // reset RD flag and all other flags, but that does not matter, because they were processed above
2772 AmiSetByteToLe(&pFrame->m_Data.m_Pres.
2773 m_le_bFlag1, 0);
2774 }
2775 Ret = EplPdokCbPdoReceived(&FrameInfo);
2776 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002777#endif
2778
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002779 break;
2780 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002781
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002782 case kEplMsgTypeSoc:
2783 {
2784 // SoC frame
2785 NmtEvent = kEplNmtEventDllCeSoc;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002786
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002787 if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type
2788 break;
2789 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002790#if EPL_DLL_PRES_READY_AFTER_SOC != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002791 // post PRes to transmit FIFO of the ethernet controller, but don't start
2792 // transmission over bus
2793 pTxBuffer =
2794 &EplDllkInstance_g.
2795 m_pTxBuffer[EPL_DLLK_TXFRAME_PRES];
2796 // Does PRes exist?
2797 if (pTxBuffer->m_pbBuffer != NULL) { // PRes does exist
2798 pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
2799 // update frame (NMT state, RD, RS, PR, MS, EN flags)
2800 if (NmtState < kEplNmtCsPreOperational2) { // NMT state is not PreOp2, ReadyToOp or Op
2801 // fake NMT state PreOp2, because PRes will be sent only in PreOp2 or greater
2802 NmtState = kEplNmtCsPreOperational2;
2803 }
2804 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
2805 m_le_bNmtStatus,
2806 (BYTE) NmtState);
2807 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
2808 m_le_bFlag2,
2809 EplDllkInstance_g.m_bFlag2);
2810 if (NmtState != kEplNmtCsOperational) { // mark PDO as invalid in NMT state Op
2811 // $$$ reset only RD flag; set other flags appropriately
2812 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
2813 m_le_bFlag1, 0);
2814 }
2815 // $$$ make function that updates Pres, StatusRes
2816 // mark PRes frame as ready for transmission
2817 Ret = EdrvTxMsgReady(pTxBuffer);
2818 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002819#endif
2820
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002821 if (NmtState >= kEplNmtCsPreOperational2) { // SoC frames only in PreOp2, ReadyToOp and Op
2822 // trigger synchronous task
2823 Event.m_EventSink = kEplEventSinkSync;
2824 Event.m_EventType = kEplEventTypeSync;
2825 Event.m_uiSize = 0;
2826 Ret = EplEventkPost(&Event);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002827
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002828 // update cycle counter
2829 if (EplDllkInstance_g.m_DllConfigParam.m_uiMultiplCycleCnt > 0) { // multiplexed cycle active
2830 EplDllkInstance_g.m_uiCycleCount =
2831 (EplDllkInstance_g.m_uiCycleCount +
2832 1) %
2833 EplDllkInstance_g.m_DllConfigParam.
2834 m_uiMultiplCycleCnt;
2835 }
2836 }
2837 // reprogram timer
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002838#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002839 if (EplDllkInstance_g.m_ullFrameTimeout != 0) {
2840 Ret =
2841 EplTimerHighReskModifyTimerNs
2842 (&EplDllkInstance_g.m_TimerHdlCycle,
2843 EplDllkInstance_g.m_ullFrameTimeout,
2844 EplDllkCbCnTimer, 0L, FALSE);
2845 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002846#endif
2847
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002848 break;
2849 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002850
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002851 case kEplMsgTypeSoa:
2852 {
2853 // SoA frame
2854 NmtEvent = kEplNmtEventDllCeSoa;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002855
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002856 if (NmtState >= kEplNmtMsNotActive) { // MN is active -> wrong msg type
2857 break;
2858 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002859
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002860 pTxFrame = NULL;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002861
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002862 if ((NmtState & EPL_NMT_SUPERSTATE_MASK) != EPL_NMT_CS_EPLMODE) { // do not respond, if NMT state is < PreOp1 (i.e. not EPL_MODE)
2863 break;
2864 }
2865 // check TargetNodeId
2866 uiNodeId =
2867 AmiGetByteFromLe(&pFrame->m_Data.m_Soa.
2868 m_le_bReqServiceTarget);
2869 if (uiNodeId == EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) { // local node is the target of the current request
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002870
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002871 // check ServiceId
2872 ReqServiceId =
2873 (tEplDllReqServiceId)
2874 AmiGetByteFromLe(&pFrame->m_Data.m_Soa.
2875 m_le_bReqServiceId);
2876 if (ReqServiceId == kEplDllReqServiceStatus) { // StatusRequest
2877 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) { // StatusRes does exist
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002878
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002879 pTxFrame =
2880 (tEplFrame *)
2881 EplDllkInstance_g.
2882 m_pTxBuffer
2883 [EPL_DLLK_TXFRAME_STATUSRES].
2884 m_pbBuffer;
2885 // update StatusRes frame (NMT state, EN, EC, RS, PR flags)
2886 AmiSetByteToLe(&pTxFrame->
2887 m_Data.m_Asnd.
2888 m_Payload.
2889 m_StatusResponse.
2890 m_le_bNmtStatus,
2891 (BYTE) NmtState);
2892 AmiSetByteToLe(&pTxFrame->
2893 m_Data.m_Asnd.
2894 m_Payload.
2895 m_StatusResponse.
2896 m_le_bFlag1,
2897 EplDllkInstance_g.
2898 m_bFlag1);
2899 AmiSetByteToLe(&pTxFrame->
2900 m_Data.m_Asnd.
2901 m_Payload.
2902 m_StatusResponse.
2903 m_le_bFlag2,
2904 EplDllkInstance_g.
2905 m_bFlag2);
2906 // send StatusRes
2907 Ret =
2908 EdrvSendTxMsg
2909 (&EplDllkInstance_g.
2910 m_pTxBuffer
2911 [EPL_DLLK_TXFRAME_STATUSRES]);
2912 if (Ret != kEplSuccessful) {
2913 goto Exit;
2914 }
2915 TGT_DBG_SIGNAL_TRACE_POINT(8);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002916
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002917 // update error signaling
2918 bFlag1 =
2919 AmiGetByteFromLe(&pFrame->
2920 m_Data.
2921 m_Soa.
2922 m_le_bFlag1);
2923 if (((bFlag1 ^ EplDllkInstance_g.m_bMnFlag1) & EPL_FRAME_FLAG1_ER) != 0) { // exception reset flag was changed by MN
2924 // assume same state for EC in next cycle (clear all other bits)
2925 if ((bFlag1 &
2926 EPL_FRAME_FLAG1_ER)
2927 != 0) {
2928 // set EC and reset rest
2929 EplDllkInstance_g.
2930 m_bFlag1 =
2931 EPL_FRAME_FLAG1_EC;
2932 } else {
2933 // reset complete flag 1 (including EC and EN)
2934 EplDllkInstance_g.
2935 m_bFlag1 =
2936 0;
2937 }
2938 }
2939 // save flag 1 from MN for Status request response cycle
2940 EplDllkInstance_g.m_bMnFlag1 =
2941 bFlag1;
2942 }
2943 } else if (ReqServiceId == kEplDllReqServiceIdent) { // IdentRequest
2944 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) { // IdentRes does exist
2945 pTxFrame =
2946 (tEplFrame *)
2947 EplDllkInstance_g.
2948 m_pTxBuffer
2949 [EPL_DLLK_TXFRAME_IDENTRES].
2950 m_pbBuffer;
2951 // update IdentRes frame (NMT state, RS, PR flags)
2952 AmiSetByteToLe(&pTxFrame->
2953 m_Data.m_Asnd.
2954 m_Payload.
2955 m_IdentResponse.
2956 m_le_bNmtStatus,
2957 (BYTE) NmtState);
2958 AmiSetByteToLe(&pTxFrame->
2959 m_Data.m_Asnd.
2960 m_Payload.
2961 m_IdentResponse.
2962 m_le_bFlag2,
2963 EplDllkInstance_g.
2964 m_bFlag2);
2965 // send IdentRes
2966 Ret =
2967 EdrvSendTxMsg
2968 (&EplDllkInstance_g.
2969 m_pTxBuffer
2970 [EPL_DLLK_TXFRAME_IDENTRES]);
2971 if (Ret != kEplSuccessful) {
2972 goto Exit;
2973 }
2974 TGT_DBG_SIGNAL_TRACE_POINT(7);
2975 }
2976 } else if (ReqServiceId == kEplDllReqServiceNmtRequest) { // NmtRequest
2977 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) { // NmtRequest does exist
2978 // check if frame is not empty and not being filled
2979 if (EplDllkInstance_g.
2980 m_pTxBuffer
2981 [EPL_DLLK_TXFRAME_NMTREQ].
2982 m_uiTxMsgLen >
2983 EPL_DLLK_BUFLEN_FILLING) {
2984 /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN)
2985 { // pad frame
2986 EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN;
2987 } */
2988 // memorize transmission
2989 pTxFrame =
2990 (tEplFrame *) 1;
2991 // send NmtRequest
2992 Ret =
2993 EdrvSendTxMsg
2994 (&EplDllkInstance_g.
2995 m_pTxBuffer
2996 [EPL_DLLK_TXFRAME_NMTREQ]);
2997 if (Ret !=
2998 kEplSuccessful) {
2999 goto Exit;
3000 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003001
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003002 }
3003 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003004
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003005 } else if (ReqServiceId == kEplDllReqServiceUnspecified) { // unspecified invite
3006 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) { // non-EPL frame does exist
3007 // check if frame is not empty and not being filled
3008 if (EplDllkInstance_g.
3009 m_pTxBuffer
3010 [EPL_DLLK_TXFRAME_NONEPL].
3011 m_uiTxMsgLen >
3012 EPL_DLLK_BUFLEN_FILLING) {
3013 /*if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen < EPL_DLLK_BUFLEN_MIN)
3014 { // pad frame
3015 EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_uiTxMsgLen = EPL_DLLK_BUFLEN_MIN;
3016 } */
3017 // memorize transmission
3018 pTxFrame =
3019 (tEplFrame *) 1;
3020 // send non-EPL frame
3021 Ret =
3022 EdrvSendTxMsg
3023 (&EplDllkInstance_g.
3024 m_pTxBuffer
3025 [EPL_DLLK_TXFRAME_NONEPL]);
3026 if (Ret !=
3027 kEplSuccessful) {
3028 goto Exit;
3029 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003030
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003031 }
3032 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003033
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003034 } else if (ReqServiceId == kEplDllReqServiceNo) { // no async service requested -> do nothing
3035 }
3036 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003037#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003038 if (pTxFrame == NULL) { // signal process function readiness of PRes frame
3039 Event.m_EventSink = kEplEventSinkDllk;
3040 Event.m_EventType = kEplEventTypeDllkPresReady;
3041 Event.m_uiSize = 0;
3042 Event.m_pArg = NULL;
3043 Ret = EplEventkPost(&Event);
3044 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003045#endif
3046
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003047 // inform PDO module
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003048#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
3049// Ret = EplPdokCbSoa(&FrameInfo);
3050#endif
3051
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003052 // $$$ put SrcNodeId, NMT state and NetTime as HeartbeatEvent into eventqueue
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003053
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003054 // $$$ inform emergency protocol handling about flags
3055 break;
3056 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003057
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003058 case kEplMsgTypeAsnd:
3059 {
3060 // ASnd frame
3061 NmtEvent = kEplNmtEventDllCeAsnd;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003062
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003063 // ASnd service registered?
3064 uiAsndServiceId =
3065 (unsigned int)AmiGetByteFromLe(&pFrame->m_Data.
3066 m_Asnd.
3067 m_le_bServiceId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003068
3069#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003070 if ((EplDllkInstance_g.m_DllState >= kEplDllMsNonCyclic)
3071 &&
3072 ((((tEplDllAsndServiceId) uiAsndServiceId) ==
3073 kEplDllAsndStatusResponse)
3074 || (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse))) { // StatusRes or IdentRes received
3075 uiNodeId =
3076 AmiGetByteFromLe(&pFrame->m_le_bSrcNodeId);
3077 if ((EplDllkInstance_g.m_LastReqServiceId ==
3078 ((tEplDllReqServiceId) uiAsndServiceId))
3079 && (uiNodeId == EplDllkInstance_g.m_uiLastTargetNodeId)) { // mark request as responded
3080 EplDllkInstance_g.m_LastReqServiceId =
3081 kEplDllReqServiceNo;
3082 }
3083 if (((tEplDllAsndServiceId) uiAsndServiceId) == kEplDllAsndIdentResponse) { // memorize MAC address of CN for PReq
3084 tEplDllkNodeInfo *pIntNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003085
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003086 pIntNodeInfo =
3087 EplDllkGetNodeInfo(uiNodeId);
3088 if (pIntNodeInfo == NULL) { // no node info structure available
3089 Ret = kEplDllNoNodeInfo;
3090 } else {
3091 EPL_MEMCPY(pIntNodeInfo->
3092 m_be_abMacAddr,
3093 pFrame->
3094 m_be_abSrcMac, 6);
3095 }
3096 }
3097 // forward Flag2 to asynchronous scheduler
3098 bFlag1 =
3099 AmiGetByteFromLe(&pFrame->m_Data.m_Asnd.
3100 m_Payload.m_StatusResponse.
3101 m_le_bFlag2);
3102 Ret =
3103 EplDllkCalAsyncSetPendingRequests(uiNodeId,
3104 ((tEplDllAsyncReqPriority) ((bFlag1 & EPL_FRAME_FLAG2_PR) >> EPL_FRAME_FLAG2_PR_SHIFT)), (bFlag1 & EPL_FRAME_FLAG2_RS));
3105 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003106#endif
3107
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003108 if (uiAsndServiceId < EPL_DLL_MAX_ASND_SERVICE_ID) { // ASnd service ID is valid
3109 if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterAny) { // ASnd service ID is registered
3110 // forward frame via async receive FIFO to userspace
3111 Ret =
3112 EplDllkCalAsyncFrameReceived
3113 (&FrameInfo);
3114 } else if (EplDllkInstance_g.m_aAsndFilter[uiAsndServiceId] == kEplDllAsndFilterLocal) { // ASnd service ID is registered, but only local node ID or broadcasts
3115 // shall be forwarded
3116 uiNodeId =
3117 AmiGetByteFromLe(&pFrame->
3118 m_le_bDstNodeId);
3119 if ((uiNodeId ==
3120 EplDllkInstance_g.m_DllConfigParam.
3121 m_uiNodeId)
3122 || (uiNodeId == EPL_C_ADR_BROADCAST)) { // ASnd frame is intended for us
3123 // forward frame via async receive FIFO to userspace
3124 Ret =
3125 EplDllkCalAsyncFrameReceived
3126 (&FrameInfo);
3127 }
3128 }
3129 }
3130 break;
3131 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003132
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003133 default:
3134 {
3135 break;
3136 }
3137 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003138
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003139 if (NmtEvent != kEplNmtEventNoEvent) { // event for DLL and NMT state machine generated
3140 Ret = EplDllkChangeState(NmtEvent, NmtState);
3141 if (Ret != kEplSuccessful) {
3142 goto Exit;
3143 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003144
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003145 if ((NmtEvent != kEplNmtEventDllCeAsnd)
3146 && ((NmtState <= kEplNmtCsPreOperational1) || (NmtEvent != kEplNmtEventDllCePres))) { // NMT state machine is not interested in ASnd frames and PRes frames when not CsNotActive or CsPreOp1
3147 // inform NMT module
3148 Event.m_EventSink = kEplEventSinkNmtk;
3149 Event.m_EventType = kEplEventTypeNmtEvent;
3150 Event.m_uiSize = sizeof(NmtEvent);
3151 Event.m_pArg = &NmtEvent;
3152 Ret = EplEventkPost(&Event);
3153 }
3154 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003155
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003156 Exit:
3157 if (Ret != kEplSuccessful) {
3158 DWORD dwArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003159
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003160 BENCHMARK_MOD_02_TOGGLE(9);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003161
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003162 dwArg = EplDllkInstance_g.m_DllState | (NmtEvent << 8);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003163
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003164 // Error event for API layer
3165 Ret = EplEventkPostError(kEplEventSourceDllk,
3166 Ret, sizeof(dwArg), &dwArg);
3167 }
3168 BENCHMARK_MOD_02_RESET(3);
3169 return;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003170}
3171
3172//---------------------------------------------------------------------------
3173//
3174// Function: EplDllkCbFrameTransmitted()
3175//
3176// Description: called from EdrvInterruptHandler().
3177// It signals
3178//
3179// Parameters: pRxBuffer_p = receive buffer structure
3180//
3181// Returns: (none)
3182//
3183//
3184// State:
3185//
3186//---------------------------------------------------------------------------
3187
3188static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
3189{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003190 tEplKernel Ret = kEplSuccessful;
3191 tEplEvent Event;
3192 tEplDllAsyncReqPriority Priority;
3193 tEplNmtState NmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003194
3195#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
3196 && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003197 tEplFrameInfo FrameInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003198#endif
3199
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003200 NmtState = EplNmtkGetNmtState();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003201
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003202 if (NmtState <= kEplNmtGsResetConfiguration) {
3203 goto Exit;
3204 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003205
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003206 if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NMTREQ) { // frame from NMT request FIFO sent
3207 // mark Tx-buffer as empty
3208 pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003209
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003210 // post event to DLL
3211 Priority = kEplDllAsyncReqPrioNmt;
3212 Event.m_EventSink = kEplEventSinkDllk;
3213 Event.m_EventType = kEplEventTypeDllkFillTx;
3214 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
3215 Event.m_pArg = &Priority;
3216 Event.m_uiSize = sizeof(Priority);
3217 Ret = EplEventkPost(&Event);
3218 } else if ((pTxBuffer_p - EplDllkInstance_g.m_pTxBuffer) == EPL_DLLK_TXFRAME_NONEPL) { // frame from generic priority FIFO sent
3219 // mark Tx-buffer as empty
3220 pTxBuffer_p->m_uiTxMsgLen = EPL_DLLK_BUFLEN_EMPTY;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003221
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003222 // post event to DLL
3223 Priority = kEplDllAsyncReqPrioGeneric;
3224 Event.m_EventSink = kEplEventSinkDllk;
3225 Event.m_EventType = kEplEventTypeDllkFillTx;
3226 EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
3227 Event.m_pArg = &Priority;
3228 Event.m_uiSize = sizeof(Priority);
3229 Ret = EplEventkPost(&Event);
3230 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003231#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
3232 && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE)) \
3233 || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003234 else if ((pTxBuffer_p->m_EplMsgType == kEplMsgTypePreq)
3235 || (pTxBuffer_p->m_EplMsgType == kEplMsgTypePres)) { // PRes resp. PReq frame sent
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003236
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003237#if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0) \
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003238 && (EPL_DLL_PRES_READY_AFTER_SOC == FALSE))
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003239 {
3240 // inform PDO module
3241 FrameInfo.m_pFrame =
3242 (tEplFrame *) pTxBuffer_p->m_pbBuffer;
3243 FrameInfo.m_uiFrameSize = pTxBuffer_p->m_uiMaxBufferLen;
3244 Ret = EplPdokCbPdoTransmitted(&FrameInfo);
3245 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003246#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003247
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003248#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003249 {
3250 // if own Pres on MN, trigger SoA
3251 if ((NmtState >= kEplNmtMsPreOperational2)
3252 && (pTxBuffer_p ==
3253 &EplDllkInstance_g.
3254 m_pTxBuffer[EPL_DLLK_TXFRAME_PRES])) {
3255 Ret =
3256 EplDllkChangeState(kEplNmtEventDllMeSoaTrig,
3257 NmtState);
3258 }
3259 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003260#endif
3261
3262#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003263 goto Exit;
3264#endif
3265 }
3266#endif
3267#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
3268 else if (pTxBuffer_p->m_EplMsgType == kEplMsgTypeSoa) { // SoA frame sent
3269 tEplNmtEvent NmtEvent = kEplNmtEventDllMeSoaSent;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003270
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003271 // check if we are invited
3272 if (EplDllkInstance_g.m_uiLastTargetNodeId ==
3273 EplDllkInstance_g.m_DllConfigParam.m_uiNodeId) {
3274 tEplFrame *pTxFrame;
3275
3276 if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceStatus) { // StatusRequest
3277 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_STATUSRES].m_pbBuffer != NULL) { // StatusRes does exist
3278
3279 pTxFrame =
3280 (tEplFrame *) EplDllkInstance_g.
3281 m_pTxBuffer
3282 [EPL_DLLK_TXFRAME_STATUSRES].
3283 m_pbBuffer;
3284 // update StatusRes frame (NMT state, EN, EC, RS, PR flags)
3285 AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
3286 m_Payload.
3287 m_StatusResponse.
3288 m_le_bNmtStatus,
3289 (BYTE) NmtState);
3290 AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
3291 m_Payload.
3292 m_StatusResponse.
3293 m_le_bFlag1,
3294 EplDllkInstance_g.
3295 m_bFlag1);
3296 AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
3297 m_Payload.
3298 m_StatusResponse.
3299 m_le_bFlag2,
3300 EplDllkInstance_g.
3301 m_bFlag2);
3302 // send StatusRes
3303 Ret =
3304 EdrvSendTxMsg(&EplDllkInstance_g.
3305 m_pTxBuffer
3306 [EPL_DLLK_TXFRAME_STATUSRES]);
3307 if (Ret != kEplSuccessful) {
3308 goto Exit;
3309 }
3310 TGT_DBG_SIGNAL_TRACE_POINT(8);
3311
3312 }
3313 } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceIdent) { // IdentRequest
3314 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_IDENTRES].m_pbBuffer != NULL) { // IdentRes does exist
3315 pTxFrame =
3316 (tEplFrame *) EplDllkInstance_g.
3317 m_pTxBuffer
3318 [EPL_DLLK_TXFRAME_IDENTRES].
3319 m_pbBuffer;
3320 // update IdentRes frame (NMT state, RS, PR flags)
3321 AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
3322 m_Payload.
3323 m_IdentResponse.
3324 m_le_bNmtStatus,
3325 (BYTE) NmtState);
3326 AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
3327 m_Payload.
3328 m_IdentResponse.
3329 m_le_bFlag2,
3330 EplDllkInstance_g.
3331 m_bFlag2);
3332 // send IdentRes
3333 Ret =
3334 EdrvSendTxMsg(&EplDllkInstance_g.
3335 m_pTxBuffer
3336 [EPL_DLLK_TXFRAME_IDENTRES]);
3337 if (Ret != kEplSuccessful) {
3338 goto Exit;
3339 }
3340 TGT_DBG_SIGNAL_TRACE_POINT(7);
3341 }
3342 } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceNmtRequest) { // NmtRequest
3343 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NMTREQ].m_pbBuffer != NULL) { // NmtRequest does exist
3344 // check if frame is not empty and not being filled
3345 if (EplDllkInstance_g.
3346 m_pTxBuffer
3347 [EPL_DLLK_TXFRAME_NMTREQ].
3348 m_uiTxMsgLen >
3349 EPL_DLLK_BUFLEN_FILLING) {
3350 // check if this frame is a NMT command,
3351 // then forward this frame back to NmtMnu module,
3352 // because it needs the time, when this frame is
3353 // actually sent, to start the timer for monitoring
3354 // the NMT state change.
3355
3356 pTxFrame =
3357 (tEplFrame *)
3358 EplDllkInstance_g.
3359 m_pTxBuffer
3360 [EPL_DLLK_TXFRAME_NMTREQ].
3361 m_pbBuffer;
3362 if ((AmiGetByteFromLe
3363 (&pTxFrame->
3364 m_le_bMessageType)
3365 == (BYTE) kEplMsgTypeAsnd)
3366 &&
3367 (AmiGetByteFromLe
3368 (&pTxFrame->m_Data.m_Asnd.
3369 m_le_bServiceId)
3370 == (BYTE) kEplDllAsndNmtCommand)) { // post event directly to NmtMnu module
3371 Event.m_EventSink =
3372 kEplEventSinkNmtMnu;
3373 Event.m_EventType =
3374 kEplEventTypeNmtMnuNmtCmdSent;
3375 Event.m_uiSize =
3376 EplDllkInstance_g.
3377 m_pTxBuffer
3378 [EPL_DLLK_TXFRAME_NMTREQ].
3379 m_uiTxMsgLen;
3380 Event.m_pArg = pTxFrame;
3381 Ret =
3382 EplEventkPost
3383 (&Event);
3384
3385 }
3386 // send NmtRequest
3387 Ret =
3388 EdrvSendTxMsg
3389 (&EplDllkInstance_g.
3390 m_pTxBuffer
3391 [EPL_DLLK_TXFRAME_NMTREQ]);
3392 if (Ret != kEplSuccessful) {
3393 goto Exit;
3394 }
3395
3396 }
3397 }
3398
3399 } else if (EplDllkInstance_g.m_LastReqServiceId == kEplDllReqServiceUnspecified) { // unspecified invite
3400 if (EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_NONEPL].m_pbBuffer != NULL) { // non-EPL frame does exist
3401 // check if frame is not empty and not being filled
3402 if (EplDllkInstance_g.
3403 m_pTxBuffer
3404 [EPL_DLLK_TXFRAME_NONEPL].
3405 m_uiTxMsgLen >
3406 EPL_DLLK_BUFLEN_FILLING) {
3407 // send non-EPL frame
3408 Ret =
3409 EdrvSendTxMsg
3410 (&EplDllkInstance_g.
3411 m_pTxBuffer
3412 [EPL_DLLK_TXFRAME_NONEPL]);
3413 if (Ret != kEplSuccessful) {
3414 goto Exit;
3415 }
3416
3417 }
3418 }
3419 }
3420 // ASnd frame was sent, remove the request
3421 EplDllkInstance_g.m_LastReqServiceId =
3422 kEplDllReqServiceNo;
3423 }
3424 // forward event to ErrorHandler and PDO module
3425 Event.m_EventSink = kEplEventSinkNmtk;
3426 Event.m_EventType = kEplEventTypeNmtEvent;
3427 Event.m_uiSize = sizeof(NmtEvent);
3428 Event.m_pArg = &NmtEvent;
3429 Ret = EplEventkPost(&Event);
3430 if (Ret != kEplSuccessful) {
3431 goto Exit;
3432 }
3433 }
3434#endif
3435
3436#if EPL_DLL_PRES_READY_AFTER_SOA != FALSE
3437 else { // d.k.: Why that else? on CN it is entered on IdentRes and StatusRes
3438 goto Exit;
3439 }
3440
3441 // signal process function readiness of PRes frame
3442 Event.m_EventSink = kEplEventSinkDllk;
3443 Event.m_EventType = kEplEventTypeDllkPresReady;
3444 Event.m_uiSize = 0;
3445 Event.m_pArg = NULL;
3446 Ret = EplEventkPost(&Event);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003447
3448#endif
3449
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003450 Exit:
3451 if (Ret != kEplSuccessful) {
3452 DWORD dwArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003453
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003454 BENCHMARK_MOD_02_TOGGLE(9);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003455
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003456 dwArg =
3457 EplDllkInstance_g.m_DllState | (pTxBuffer_p->
3458 m_EplMsgType << 16);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003459
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003460 // Error event for API layer
3461 Ret = EplEventkPostError(kEplEventSourceDllk,
3462 Ret, sizeof(dwArg), &dwArg);
3463 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003464
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003465 return;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003466}
3467
3468//---------------------------------------------------------------------------
3469//
3470// Function: EplDllkCheckFrame()
3471//
3472// Description: check frame and set missing information
3473//
3474// Parameters: pFrame_p = ethernet frame
3475// uiFrameSize_p = size of frame
3476//
3477// Returns: tEplKernel = error code
3478//
3479//
3480// State:
3481//
3482//---------------------------------------------------------------------------
3483
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003484static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
3485 unsigned int uiFrameSize_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003486{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003487 tEplMsgType MsgType;
3488 WORD wEtherType;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003489
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003490 // check frame
3491 if (pFrame_p != NULL) {
3492 // check SrcMAC
3493 if (AmiGetQword48FromBe(pFrame_p->m_be_abSrcMac) == 0) {
3494 // source MAC address
3495 EPL_MEMCPY(&pFrame_p->m_be_abSrcMac[0],
3496 &EplDllkInstance_g.m_be_abSrcMac[0], 6);
3497 }
3498 // check ethertype
3499 wEtherType = AmiGetWordFromBe(&pFrame_p->m_be_wEtherType);
3500 if (wEtherType == 0) {
3501 // assume EPL frame
3502 wEtherType = EPL_C_DLL_ETHERTYPE_EPL;
3503 AmiSetWordToBe(&pFrame_p->m_be_wEtherType, wEtherType);
3504 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003505
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003506 if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL) {
3507 // source node ID
3508 AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId,
3509 (BYTE) EplDllkInstance_g.
3510 m_DllConfigParam.m_uiNodeId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003511
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003512 // check message type
3513 MsgType =
3514 AmiGetByteFromLe(&pFrame_p->m_le_bMessageType);
3515 if (MsgType == 0) {
3516 MsgType = kEplMsgTypeAsnd;
3517 AmiSetByteToLe(&pFrame_p->m_le_bMessageType,
3518 (BYTE) MsgType);
3519 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003520
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003521 if (MsgType == kEplMsgTypeAsnd) {
3522 // destination MAC address
3523 AmiSetQword48ToBe(&pFrame_p->m_be_abDstMac[0],
3524 EPL_C_DLL_MULTICAST_ASND);
3525 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003526
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003527 }
3528 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003529
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003530 return kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003531}
3532
3533//---------------------------------------------------------------------------
3534//
3535// Function: EplDllkCbCnTimer()
3536//
3537// Description: called by timer module. It monitors the EPL cycle when it is a CN.
3538//
3539// Parameters: pEventArg_p = timer event argument
3540//
3541// Returns: tEplKernel = error code
3542//
3543//
3544// State:
3545//
3546//---------------------------------------------------------------------------
3547
3548#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003549static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003550{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003551 tEplKernel Ret = kEplSuccessful;
3552 tEplNmtState NmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003553
3554#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003555 if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) { // zombie callback
3556 // just exit
3557 goto Exit;
3558 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003559#endif
3560
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003561 NmtState = EplNmtkGetNmtState();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003562
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003563 if (NmtState <= kEplNmtGsResetConfiguration) {
3564 goto Exit;
3565 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003566
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003567 Ret = EplDllkChangeState(kEplNmtEventDllCeFrameTimeout, NmtState);
3568 if (Ret != kEplSuccessful) {
3569 goto Exit;
3570 }
3571 // 2008/10/15 d.k. reprogramming of timer not necessary,
3572 // because it will be programmed, when SoC is received.
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003573/*
3574 // reprogram timer
3575#if EPL_TIMER_USE_HIGHRES != FALSE
3576 if ((NmtState > kEplNmtCsPreOperational1)
3577 && (EplDllkInstance_g.m_ullFrameTimeout != 0))
3578 {
3579 Ret = EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.m_TimerHdlCycle, EplDllkInstance_g.m_ullFrameTimeout, EplDllkCbCnTimer, 0L, FALSE);
3580 }
3581#endif
3582*/
3583
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003584 Exit:
3585 if (Ret != kEplSuccessful) {
3586 DWORD dwArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003587
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003588 BENCHMARK_MOD_02_TOGGLE(9);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003589
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003590 dwArg =
3591 EplDllkInstance_g.
3592 m_DllState | (kEplNmtEventDllCeFrameTimeout << 8);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003593
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003594 // Error event for API layer
3595 Ret = EplEventkPostError(kEplEventSourceDllk,
3596 Ret, sizeof(dwArg), &dwArg);
3597 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003598
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003599 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003600}
3601#endif
3602
3603#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
3604
3605//---------------------------------------------------------------------------
3606//
3607// Function: EplDllkCbMnTimerCycle()
3608//
3609// Description: called by timer module. It triggers the SoC when it is a MN.
3610//
3611// Parameters: pEventArg_p = timer event argument
3612//
3613// Returns: tEplKernel = error code
3614//
3615//
3616// State:
3617//
3618//---------------------------------------------------------------------------
3619
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003620static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003621{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003622 tEplKernel Ret = kEplSuccessful;
3623 tEplNmtState NmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003624
3625#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003626 if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlCycle) { // zombie callback
3627 // just exit
3628 goto Exit;
3629 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003630#endif
3631
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003632 NmtState = EplNmtkGetNmtState();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003633
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003634 if (NmtState <= kEplNmtGsResetConfiguration) {
3635 goto Exit;
3636 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003637
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003638 Ret = EplDllkChangeState(kEplNmtEventDllMeSocTrig, NmtState);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003639
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003640 Exit:
3641 if (Ret != kEplSuccessful) {
3642 DWORD dwArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003643
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003644 BENCHMARK_MOD_02_TOGGLE(9);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003645
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003646 dwArg =
3647 EplDllkInstance_g.
3648 m_DllState | (kEplNmtEventDllMeSocTrig << 8);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003649
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003650 // Error event for API layer
3651 Ret = EplEventkPostError(kEplEventSourceDllk,
3652 Ret, sizeof(dwArg), &dwArg);
3653 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003654
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003655 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003656}
3657
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003658//---------------------------------------------------------------------------
3659//
3660// Function: EplDllkCbMnTimerResponse()
3661//
3662// Description: called by timer module. It monitors the PRes timeout.
3663//
3664// Parameters: pEventArg_p = timer event argument
3665//
3666// Returns: tEplKernel = error code
3667//
3668//
3669// State:
3670//
3671//---------------------------------------------------------------------------
3672
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003673static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
3674 pEventArg_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003675{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003676 tEplKernel Ret = kEplSuccessful;
3677 tEplNmtState NmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003678
3679#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003680 if (pEventArg_p->m_TimerHdl != EplDllkInstance_g.m_TimerHdlResponse) { // zombie callback
3681 // just exit
3682 goto Exit;
3683 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003684#endif
3685
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003686 NmtState = EplNmtkGetNmtState();
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003687
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003688 if (NmtState <= kEplNmtGsResetConfiguration) {
3689 goto Exit;
3690 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003691
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003692 Ret = EplDllkChangeState(kEplNmtEventDllMePresTimeout, NmtState);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003693
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003694 Exit:
3695 if (Ret != kEplSuccessful) {
3696 DWORD dwArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003697
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003698 BENCHMARK_MOD_02_TOGGLE(9);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003699
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003700 dwArg =
3701 EplDllkInstance_g.
3702 m_DllState | (kEplNmtEventDllMePresTimeout << 8);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003703
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003704 // Error event for API layer
3705 Ret = EplEventkPostError(kEplEventSourceDllk,
3706 Ret, sizeof(dwArg), &dwArg);
3707 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003708
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003709 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003710}
3711
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003712//---------------------------------------------------------------------------
3713//
3714// Function: EplDllkGetNodeInfo()
3715//
3716// Description: returns node info structure of the specified node.
3717//
3718// Parameters: uiNodeId_p = node ID
3719//
3720// Returns: tEplDllkNodeInfo* = pointer to internal node info structure
3721//
3722//
3723// State:
3724//
3725//---------------------------------------------------------------------------
3726
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003727static tEplDllkNodeInfo *EplDllkGetNodeInfo(unsigned int uiNodeId_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003728{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003729 // $$$ d.k.: use hash algorithm to retrieve the appropriate node info structure
3730 // if size of array is less than 254.
3731 uiNodeId_p--; // node ID starts at 1 but array at 0
3732 if (uiNodeId_p >= tabentries(EplDllkInstance_g.m_aNodeInfo)) {
3733 return NULL;
3734 } else {
3735 return &EplDllkInstance_g.m_aNodeInfo[uiNodeId_p];
3736 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003737}
3738
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003739//---------------------------------------------------------------------------
3740//
3741// Function: EplDllkMnSendSoa()
3742//
3743// Description: it updates and transmits the SoA.
3744//
3745// Parameters: NmtState_p = current NMT state
3746// pDllStateProposed_p = proposed DLL state
3747// fEnableInvitation_p = enable invitation for asynchronous phase
3748// it will be disabled for EPL_C_DLL_PREOP1_START_CYCLES SoAs
3749//
3750// Returns: tEplKernel = error code
3751//
3752//
3753// State:
3754//
3755//---------------------------------------------------------------------------
3756
3757static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003758 tEplDllState * pDllStateProposed_p,
3759 BOOL fEnableInvitation_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003760{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003761 tEplKernel Ret = kEplSuccessful;
3762 tEdrvTxBuffer *pTxBuffer = NULL;
3763 tEplFrame *pTxFrame;
3764 tEplDllkNodeInfo *pNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003765
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003766 *pDllStateProposed_p = kEplDllMsNonCyclic;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003767
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003768 pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOA];
3769 if (pTxBuffer->m_pbBuffer != NULL) { // SoA does exist
3770 pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003771
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003772 if (fEnableInvitation_p != FALSE) { // fetch target of asynchronous phase
3773 if (EplDllkInstance_g.m_bFlag2 == 0) { // own queues are empty
3774 EplDllkInstance_g.m_LastReqServiceId =
3775 kEplDllReqServiceNo;
3776 } else if (((tEplDllAsyncReqPriority) (EplDllkInstance_g.m_bFlag2 >> EPL_FRAME_FLAG2_PR_SHIFT)) == kEplDllAsyncReqPrioNmt) { // frames in own NMT request queue available
3777 EplDllkInstance_g.m_LastReqServiceId =
3778 kEplDllReqServiceNmtRequest;
3779 } else {
3780 EplDllkInstance_g.m_LastReqServiceId =
3781 kEplDllReqServiceUnspecified;
3782 }
3783 Ret =
3784 EplDllkCalAsyncGetSoaRequest(&EplDllkInstance_g.
3785 m_LastReqServiceId,
3786 &EplDllkInstance_g.
3787 m_uiLastTargetNodeId);
3788 if (Ret != kEplSuccessful) {
3789 goto Exit;
3790 }
3791 if (EplDllkInstance_g.m_LastReqServiceId != kEplDllReqServiceNo) { // asynchronous phase will be assigned to one node
3792 if (EplDllkInstance_g.m_uiLastTargetNodeId == EPL_C_ADR_INVALID) { // exchange invalid node ID with local node ID
3793 EplDllkInstance_g.m_uiLastTargetNodeId =
3794 EplDllkInstance_g.m_DllConfigParam.
3795 m_uiNodeId;
3796 // d.k. DLL state WaitAsndTrig is not helpful;
3797 // so just step over to WaitSocTrig,
3798 // because own ASnd is sent automatically in CbFrameTransmitted() after SoA.
3799 //*pDllStateProposed_p = kEplDllMsWaitAsndTrig;
3800 *pDllStateProposed_p =
3801 kEplDllMsWaitSocTrig;
3802 } else { // assignment to CN
3803 *pDllStateProposed_p =
3804 kEplDllMsWaitAsnd;
3805 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003806
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003807 pNodeInfo =
3808 EplDllkGetNodeInfo(EplDllkInstance_g.
3809 m_uiLastTargetNodeId);
3810 if (pNodeInfo == NULL) { // no node info structure available
3811 Ret = kEplDllNoNodeInfo;
3812 goto Exit;
3813 }
3814 // update frame (EA, ER flags)
3815 AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
3816 m_le_bFlag1,
3817 pNodeInfo->
3818 m_bSoaFlag1 & (EPL_FRAME_FLAG1_EA
3819 |
3820 EPL_FRAME_FLAG1_ER));
3821 } else { // no assignment of asynchronous phase
3822 *pDllStateProposed_p = kEplDllMsWaitSocTrig;
3823 EplDllkInstance_g.m_uiLastTargetNodeId =
3824 EPL_C_ADR_INVALID;
3825 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003826
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003827 // update frame (target)
3828 AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
3829 m_le_bReqServiceId,
3830 (BYTE) EplDllkInstance_g.
3831 m_LastReqServiceId);
3832 AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
3833 m_le_bReqServiceTarget,
3834 (BYTE) EplDllkInstance_g.
3835 m_uiLastTargetNodeId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003836
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003837 } else { // invite nobody
3838 // update frame (target)
3839 AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
3840 m_le_bReqServiceId, (BYTE) 0);
3841 AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
3842 m_le_bReqServiceTarget, (BYTE) 0);
3843 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003844
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003845 // update frame (NMT state)
3846 AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus,
3847 (BYTE) NmtState_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003848
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003849 // send SoA frame
3850 Ret = EdrvSendTxMsg(pTxBuffer);
3851 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003852
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003853 Exit:
3854 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003855}
3856
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003857//---------------------------------------------------------------------------
3858//
3859// Function: EplDllkMnSendSoc()
3860//
3861// Description: it updates and transmits the SoA.
3862//
3863// Parameters: (none)
3864//
3865// Returns: tEplKernel = error code
3866//
3867//
3868// State:
3869//
3870//---------------------------------------------------------------------------
3871
3872static tEplKernel EplDllkMnSendSoc(void)
3873{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003874 tEplKernel Ret = kEplSuccessful;
3875 tEdrvTxBuffer *pTxBuffer = NULL;
3876 tEplFrame *pTxFrame;
3877 tEplEvent Event;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003878
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003879 pTxBuffer = &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_SOC];
3880 if (pTxBuffer->m_pbBuffer != NULL) { // SoC does exist
3881 pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003882
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003883 // $$$ update NetTime
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003884
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003885 // send SoC frame
3886 Ret = EdrvSendTxMsg(pTxBuffer);
3887 if (Ret != kEplSuccessful) {
3888 goto Exit;
3889 }
3890 // trigger synchronous task
3891 Event.m_EventSink = kEplEventSinkSync;
3892 Event.m_EventType = kEplEventTypeSync;
3893 Event.m_uiSize = 0;
3894 Ret = EplEventkPost(&Event);
3895 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003896
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003897 Exit:
3898 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003899}
3900
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003901//---------------------------------------------------------------------------
3902//
3903// Function: EplDllkMnSendPreq()
3904//
3905// Description: it updates and transmits the PReq for the next isochronous CN
3906// or own PRes if enabled.
3907//
3908// Parameters: NmtState_p = current NMT state
3909// pDllStateProposed_p = proposed DLL state
3910//
3911// Returns: tEplKernel = error code
3912//
3913//
3914// State:
3915//
3916//---------------------------------------------------------------------------
3917
3918static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003919 tEplDllState * pDllStateProposed_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003920{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003921 tEplKernel Ret = kEplSuccessful;
3922 tEdrvTxBuffer *pTxBuffer = NULL;
3923 tEplFrame *pTxFrame;
3924 BYTE bFlag1 = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003925
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003926 if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // start with first isochronous CN
3927 EplDllkInstance_g.m_pCurNodeInfo =
3928 EplDllkInstance_g.m_pFirstNodeInfo;
3929 } else { // iterate to next isochronous CN
3930 EplDllkInstance_g.m_pCurNodeInfo =
3931 EplDllkInstance_g.m_pCurNodeInfo->m_pNextNodeInfo;
3932 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003933
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003934 if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // last isochronous CN reached
3935 Ret = EplDllkMnSendSoa(NmtState_p, pDllStateProposed_p, TRUE);
3936 goto Exit;
3937 } else {
3938 pTxBuffer = EplDllkInstance_g.m_pCurNodeInfo->m_pPreqTxBuffer;
3939 bFlag1 =
3940 EplDllkInstance_g.m_pCurNodeInfo->
3941 m_bSoaFlag1 & EPL_FRAME_FLAG1_EA;
3942 *pDllStateProposed_p = kEplDllMsWaitPres;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003943
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003944 // start PRes Timer
3945 // $$$ d.k.: maybe move this call to CbFrameTransmitted(), because the time should run from there
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003946#if EPL_TIMER_USE_HIGHRES != FALSE
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003947 Ret =
3948 EplTimerHighReskModifyTimerNs(&EplDllkInstance_g.
3949 m_TimerHdlResponse,
3950 EplDllkInstance_g.
3951 m_pCurNodeInfo->
3952 m_dwPresTimeout,
3953 EplDllkCbMnTimerResponse, 0L,
3954 FALSE);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003955#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003956 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003957
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003958 if (pTxBuffer == NULL) { // PReq does not exist
3959 Ret = kEplDllTxBufNotReady;
3960 goto Exit;
3961 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003962
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003963 pTxFrame = (tEplFrame *) pTxBuffer->m_pbBuffer;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003964
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003965 if (pTxFrame != NULL) { // PReq does exist
3966 if (NmtState_p == kEplNmtMsOperational) { // leave RD flag untouched
3967 bFlag1 |=
3968 AmiGetByteFromLe(&pTxFrame->m_Data.m_Preq.
3969 m_le_bFlag1) & EPL_FRAME_FLAG1_RD;
3970 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003971
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003972 if (pTxBuffer == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]) { // PRes of MN will be sent
3973 // update NMT state
3974 AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus,
3975 (BYTE) NmtState_p);
3976 *pDllStateProposed_p = kEplDllMsWaitSoaTrig;
3977 }
3978 // $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary
3979 // update frame (Flag1)
3980 AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, bFlag1);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003981
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003982 // calculate frame size from payload size
3983 pTxBuffer->m_uiTxMsgLen =
3984 AmiGetWordFromLe(&pTxFrame->m_Data.m_Preq.m_le_wSize) + 24;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003985
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003986 // send PReq frame
3987 Ret = EdrvSendTxMsg(pTxBuffer);
3988 } else {
3989 Ret = kEplDllTxFrameInvalid;
3990 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003991
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08003992 Exit:
3993 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003994}
3995
Daniel Krueger9d7164c2008-12-19 11:41:57 -08003996//---------------------------------------------------------------------------
3997//
3998// Function: EplDllkAsyncFrameNotReceived()
3999//
4000// Description: passes empty ASnd frame to receive FIFO.
4001// It will be called only for frames with registered AsndServiceIds
4002// (only kEplDllAsndFilterAny).
4003//
4004// Parameters: none
4005//
4006// Returns: tEplKernel = error code
4007//
4008//
4009// State:
4010//
4011//---------------------------------------------------------------------------
4012
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08004013static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
4014 ReqServiceId_p,
4015 unsigned int uiNodeId_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08004016{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08004017 tEplKernel Ret = kEplSuccessful;
4018 BYTE abBuffer[18];
4019 tEplFrame *pFrame = (tEplFrame *) abBuffer;
4020 tEplFrameInfo FrameInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08004021
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08004022 // check if previous SoA invitation was not answered
4023 switch (ReqServiceId_p) {
4024 case kEplDllReqServiceIdent:
4025 case kEplDllReqServiceStatus:
4026 // ASnd service registered?
4027 if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny) { // ASnd service ID is registered
4028 AmiSetByteToLe(&pFrame->m_le_bSrcNodeId,
4029 (BYTE) uiNodeId_p);
4030 // EPL MsgType ASnd
4031 AmiSetByteToLe(&pFrame->m_le_bMessageType,
4032 (BYTE) kEplMsgTypeAsnd);
4033 // ASnd Service ID
4034 AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
4035 (BYTE) ReqServiceId_p);
4036 // create frame info structure
4037 FrameInfo.m_pFrame = pFrame;
4038 FrameInfo.m_uiFrameSize = 18; // empty non existing ASnd frame
4039 // forward frame via async receive FIFO to userspace
4040 Ret = EplDllkCalAsyncFrameReceived(&FrameInfo);
4041 }
4042 break;
4043 default:
4044 // no invitation issued or it was successfully answered or it is uninteresting
4045 break;
4046 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08004047
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08004048 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08004049}
4050
Daniel Krueger9d7164c2008-12-19 11:41:57 -08004051#endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
4052
Daniel Krueger9d7164c2008-12-19 11:41:57 -08004053#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
4054// EOF