qlge: bugfix: Pad outbound frames smaller than 60 bytes.
[safe/jmp/linux-2.6] / drivers / staging / epl / EplErrorHandlerk.c
1 /****************************************************************************
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 error handler 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: EplErrorHandlerk.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.9 $  $Date: 2008/10/17 15:32:32 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                     GCC V3.4
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/10/02 d.k.:   start of the implementation
68
69 ****************************************************************************/
70
71 #include "kernel/EplErrorHandlerk.h"
72 #include "EplNmt.h"
73 #include "kernel/EplEventk.h"
74 #include "kernel/EplObdk.h"     // function prototyps of the EplOBD-Modul
75 #include "kernel/EplDllk.h"
76
77 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
78
79 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
80 #error "EPL ErrorHandler module needs EPL module OBDK!"
81 #endif
82
83 /***************************************************************************/
84 /*                                                                         */
85 /*                                                                         */
86 /*          G L O B A L   D E F I N I T I O N S                            */
87 /*                                                                         */
88 /*                                                                         */
89 /***************************************************************************/
90
91 //---------------------------------------------------------------------------
92 // const defines
93 //---------------------------------------------------------------------------
94
95 //---------------------------------------------------------------------------
96 // local types
97 //---------------------------------------------------------------------------
98
99 typedef struct {
100         DWORD m_dwCumulativeCnt;        // subindex 1
101         DWORD m_dwThresholdCnt; // subindex 2
102         DWORD m_dwThreshold;    // subindex 3
103
104 } tEplErrorHandlerkErrorCounter;
105
106 typedef struct {
107         tEplErrorHandlerkErrorCounter m_CnLossSoc;      // object 0x1C0B
108         tEplErrorHandlerkErrorCounter m_CnLossPreq;     // object 0x1C0D
109         tEplErrorHandlerkErrorCounter m_CnCrcErr;       // object 0x1C0F
110         unsigned long m_ulDllErrorEvents;
111
112 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
113         tEplErrorHandlerkErrorCounter m_MnCrcErr;       // object 0x1C00
114         tEplErrorHandlerkErrorCounter m_MnCycTimeExceed;        // object 0x1C02
115         DWORD m_adwMnCnLossPresCumCnt[254];     // object 0x1C07
116         DWORD m_adwMnCnLossPresThrCnt[254];     // object 0x1C08
117         DWORD m_adwMnCnLossPresThreshold[254];  // object 0x1C09
118         BOOL m_afMnCnLossPresEvent[254];
119 #endif
120
121 } tEplErrorHandlerkInstance;
122
123 //---------------------------------------------------------------------------
124 // modul globale vars
125 //---------------------------------------------------------------------------
126
127 static tEplErrorHandlerkInstance EplErrorHandlerkInstance_g;
128
129 //---------------------------------------------------------------------------
130 // local function prototypes
131 //---------------------------------------------------------------------------
132
133 static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
134                                                    * pErrorCounter_p,
135                                                    unsigned int uiIndex_p);
136
137 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
138 static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
139                                             unsigned int uiValueCount_p,
140                                             unsigned int uiIndex_p);
141 #endif
142
143 /***************************************************************************/
144 /*                                                                         */
145 /*                                                                         */
146 /*          C L A S S  <Epl-Kernelspace-Error-Handler>                     */
147 /*                                                                         */
148 /*                                                                         */
149 /***************************************************************************/
150 //
151 // Description:
152 //
153 //
154 /***************************************************************************/
155
156 //=========================================================================//
157 //                                                                         //
158 //          P U B L I C   F U N C T I O N S                                //
159 //                                                                         //
160 //=========================================================================//
161
162 //---------------------------------------------------------------------------
163 //
164 // Function:    EplErrorHandlerkInit
165 //
166 // Description: function initialize the first instance
167 //
168 //
169 //
170 // Parameters:
171 //
172 //
173 // Returns:      tEpKernel  = errorcode
174 //
175 //
176 // State:
177 //
178 //---------------------------------------------------------------------------
179 tEplKernel PUBLIC EplErrorHandlerkInit(void)
180 {
181         tEplKernel Ret;
182
183         Ret = EplErrorHandlerkAddInstance();
184
185         return Ret;
186
187 }
188
189 //---------------------------------------------------------------------------
190 //
191 // Function:    EplErrorHandlerkAddInstance
192 //
193 // Description: function add one more instance
194 //
195 //
196 //
197 // Parameters:
198 //
199 //
200 // Returns:      tEpKernel  = errorcode
201 //
202 //
203 // State:
204 //
205 //---------------------------------------------------------------------------
206 tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
207 {
208         tEplKernel Ret;
209
210         Ret = kEplSuccessful;
211
212         // reset only event variable,
213         // all other instance members are reset by OD or may keep their current value
214         // d.k.: this is necessary for the cumulative counters, which shall not be reset
215         EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0;
216
217         // link counters to OD
218         // $$$ d.k. if OD resides in userspace, fetch pointer to shared memory,
219         //          which shall have the same structure as the instance (needs to be declared globally).
220         //          Other idea: error counter shall belong to the process image
221         //          (reset of counters by SDO write are a little bit tricky).
222
223         Ret =
224             EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
225                                              m_CnLossSoc, 0x1C0B);
226         if (Ret != kEplSuccessful) {
227                 goto Exit;
228         }
229
230         Ret =
231             EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
232                                              m_CnLossPreq, 0x1C0D);
233         // ignore return code, because object 0x1C0D is conditional
234
235         Ret =
236             EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
237                                              m_CnCrcErr, 0x1C0F);
238         if (Ret != kEplSuccessful) {
239                 goto Exit;
240         }
241 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
242         Ret =
243             EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
244                                              m_MnCrcErr, 0x1C00);
245         if (Ret != kEplSuccessful) {
246                 goto Exit;
247         }
248
249         Ret =
250             EplErrorHandlerkLinkErrorCounter(&EplErrorHandlerkInstance_g.
251                                              m_MnCycTimeExceed, 0x1C02);
252         if (Ret != kEplSuccessful) {
253                 goto Exit;
254         }
255
256         Ret =
257             EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g.
258                                       m_adwMnCnLossPresCumCnt,
259                                       tabentries(EplErrorHandlerkInstance_g.
260                                                  m_adwMnCnLossPresCumCnt),
261                                       0x1C07);
262         if (Ret != kEplSuccessful) {
263                 goto Exit;
264         }
265
266         Ret =
267             EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g.
268                                       m_adwMnCnLossPresThrCnt,
269                                       tabentries(EplErrorHandlerkInstance_g.
270                                                  m_adwMnCnLossPresThrCnt),
271                                       0x1C08);
272         if (Ret != kEplSuccessful) {
273                 goto Exit;
274         }
275
276         Ret =
277             EplErrorHandlerkLinkArray(EplErrorHandlerkInstance_g.
278                                       m_adwMnCnLossPresThreshold,
279                                       tabentries(EplErrorHandlerkInstance_g.
280                                                  m_adwMnCnLossPresThreshold),
281                                       0x1C09);
282         if (Ret != kEplSuccessful) {
283                 goto Exit;
284         }
285 #endif
286
287       Exit:
288         return Ret;
289
290 }
291
292 //---------------------------------------------------------------------------
293 //
294 // Function:    EplErrorHandlerkDelInstance
295 //
296 // Description: function delete instance an free the bufferstructure
297 //
298 //
299 //
300 // Parameters:
301 //
302 //
303 // Returns:      tEpKernel  = errorcode
304 //
305 //
306 // State:
307 //
308 //---------------------------------------------------------------------------
309 tEplKernel PUBLIC EplErrorHandlerkDelInstance()
310 {
311         tEplKernel Ret;
312
313         Ret = kEplSuccessful;
314
315         return Ret;
316
317 }
318
319 //---------------------------------------------------------------------------
320 //
321 // Function:    EplErrorHandlerkProcess
322 //
323 // Description: processes error events from DLL
324 //
325 //
326 //
327 // Parameters:  pEvent_p = pointer to event-structur from buffer
328 //
329 //
330 // Returns:      tEpKernel  = errorcode
331 //
332 //
333 // State:
334 //
335 //---------------------------------------------------------------------------
336 tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p)
337 {
338         tEplKernel Ret;
339         unsigned long ulDllErrorEvents;
340         tEplEvent Event;
341         tEplNmtEvent NmtEvent;
342
343         Ret = kEplSuccessful;
344
345         // check m_EventType
346         switch (pEvent_p->m_EventType) {
347         case kEplEventTypeDllError:
348                 {
349                         tEplErrorHandlerkEvent *pErrHandlerEvent =
350                             (tEplErrorHandlerkEvent *) pEvent_p->m_pArg;
351
352                         ulDllErrorEvents = pErrHandlerEvent->m_ulDllErrorEvents;
353
354                         // check the several error events
355                         if ((EplErrorHandlerkInstance_g.m_CnLossSoc.
356                              m_dwThreshold > 0)
357                             && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) != 0)) {   // loss of SoC event occured
358                                 // increment cumulative counter by 1
359                                 EplErrorHandlerkInstance_g.m_CnLossSoc.
360                                     m_dwCumulativeCnt++;
361                                 // increment threshold counter by 8
362                                 EplErrorHandlerkInstance_g.m_CnLossSoc.
363                                     m_dwThresholdCnt += 8;
364                                 if (EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossSoc.m_dwThreshold) {  // threshold is reached
365                                         // $$$ d.k.: generate error history entry E_DLL_LOSS_SOC_TH
366
367                                         // post event to NMT state machine
368                                         NmtEvent = kEplNmtEventNmtCycleError;
369                                         Event.m_EventSink = kEplEventSinkNmtk;
370                                         Event.m_EventType =
371                                             kEplEventTypeNmtEvent;
372                                         Event.m_pArg = &NmtEvent;
373                                         Event.m_uiSize = sizeof(NmtEvent);
374                                         Ret = EplEventkPost(&Event);
375                                 }
376                                 EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
377                                     EPL_DLL_ERR_CN_LOSS_SOC;
378                         }
379
380                         if ((EplErrorHandlerkInstance_g.m_CnLossPreq.
381                              m_dwThreshold > 0)
382                             && ((ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_PREQ) != 0)) {  // loss of PReq event occured
383                                 // increment cumulative counter by 1
384                                 EplErrorHandlerkInstance_g.m_CnLossPreq.
385                                     m_dwCumulativeCnt++;
386                                 // increment threshold counter by 8
387                                 EplErrorHandlerkInstance_g.m_CnLossPreq.
388                                     m_dwThresholdCnt += 8;
389                                 if (EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnLossPreq.m_dwThreshold) {        // threshold is reached
390                                         // $$$ d.k.: generate error history entry E_DLL_LOSS_PREQ_TH
391
392                                         // post event to NMT state machine
393                                         NmtEvent = kEplNmtEventNmtCycleError;
394                                         Event.m_EventSink = kEplEventSinkNmtk;
395                                         Event.m_EventType =
396                                             kEplEventTypeNmtEvent;
397                                         Event.m_pArg = &NmtEvent;
398                                         Event.m_uiSize = sizeof(NmtEvent);
399                                         Ret = EplEventkPost(&Event);
400                                 }
401                         }
402
403                         if ((EplErrorHandlerkInstance_g.m_CnLossPreq.
404                              m_dwThresholdCnt > 0)
405                             && ((ulDllErrorEvents & EPL_DLL_ERR_CN_RECVD_PREQ) != 0)) { // PReq correctly received
406                                 // decrement threshold counter by 1
407                                 EplErrorHandlerkInstance_g.m_CnLossPreq.
408                                     m_dwThresholdCnt--;
409                         }
410
411                         if ((EplErrorHandlerkInstance_g.m_CnCrcErr.
412                              m_dwThreshold > 0)
413                             && ((ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) != 0)) {        // CRC error event occured
414                                 // increment cumulative counter by 1
415                                 EplErrorHandlerkInstance_g.m_CnCrcErr.
416                                     m_dwCumulativeCnt++;
417                                 // increment threshold counter by 8
418                                 EplErrorHandlerkInstance_g.m_CnCrcErr.
419                                     m_dwThresholdCnt += 8;
420                                 if (EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_CnCrcErr.m_dwThreshold) {    // threshold is reached
421                                         // $$$ d.k.: generate error history entry E_DLL_CRC_TH
422
423                                         // post event to NMT state machine
424                                         NmtEvent = kEplNmtEventNmtCycleError;
425                                         Event.m_EventSink = kEplEventSinkNmtk;
426                                         Event.m_EventType =
427                                             kEplEventTypeNmtEvent;
428                                         Event.m_pArg = &NmtEvent;
429                                         Event.m_uiSize = sizeof(NmtEvent);
430                                         Ret = EplEventkPost(&Event);
431                                 }
432                                 EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
433                                     EPL_DLL_ERR_CN_CRC;
434                         }
435
436                         if ((ulDllErrorEvents & EPL_DLL_ERR_INVALID_FORMAT) != 0) {     // invalid format error occured (only direct reaction)
437                                 // $$$ d.k.: generate error history entry E_DLL_INVALID_FORMAT
438 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
439                                 if (pErrHandlerEvent->m_NmtState >= kEplNmtMsNotActive) {       // MN is active
440                                         if (pErrHandlerEvent->m_uiNodeId != 0) {
441                                                 tEplHeartbeatEvent
442                                                     HeartbeatEvent;
443
444                                                 // remove node from isochronous phase
445                                                 Ret =
446                                                     EplDllkDeleteNode
447                                                     (pErrHandlerEvent->
448                                                      m_uiNodeId);
449
450                                                 // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
451                                                 HeartbeatEvent.m_uiNodeId =
452                                                     pErrHandlerEvent->
453                                                     m_uiNodeId;
454                                                 HeartbeatEvent.m_NmtState =
455                                                     kEplNmtCsNotActive;
456                                                 HeartbeatEvent.m_wErrorCode =
457                                                     EPL_E_DLL_INVALID_FORMAT;
458                                                 Event.m_EventSink =
459                                                     kEplEventSinkNmtMnu;
460                                                 Event.m_EventType =
461                                                     kEplEventTypeHeartbeat;
462                                                 Event.m_uiSize =
463                                                     sizeof(HeartbeatEvent);
464                                                 Event.m_pArg = &HeartbeatEvent;
465                                                 Ret = EplEventkPost(&Event);
466                                         }
467                                         // $$$ and else should lead to InternComError
468                                 } else
469 #endif
470                                 {       // CN is active
471                                         // post event to NMT state machine
472                                         NmtEvent = kEplNmtEventInternComError;
473                                         Event.m_EventSink = kEplEventSinkNmtk;
474                                         Event.m_EventType =
475                                             kEplEventTypeNmtEvent;
476                                         Event.m_pArg = &NmtEvent;
477                                         Event.m_uiSize = sizeof(NmtEvent);
478                                         Ret = EplEventkPost(&Event);
479                                 }
480                         }
481 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
482                         if ((EplErrorHandlerkInstance_g.m_MnCrcErr.
483                              m_dwThreshold > 0)
484                             && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) != 0)) {        // CRC error event occured
485                                 // increment cumulative counter by 1
486                                 EplErrorHandlerkInstance_g.m_MnCrcErr.
487                                     m_dwCumulativeCnt++;
488                                 // increment threshold counter by 8
489                                 EplErrorHandlerkInstance_g.m_MnCrcErr.
490                                     m_dwThresholdCnt += 8;
491                                 if (EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCrcErr.m_dwThreshold) {    // threshold is reached
492                                         // $$$ d.k.: generate error history entry E_DLL_CRC_TH
493
494                                         // post event to NMT state machine
495                                         NmtEvent = kEplNmtEventNmtCycleError;
496                                         Event.m_EventSink = kEplEventSinkNmtk;
497                                         Event.m_EventType =
498                                             kEplEventTypeNmtEvent;
499                                         Event.m_pArg = &NmtEvent;
500                                         Event.m_uiSize = sizeof(NmtEvent);
501                                         Ret = EplEventkPost(&Event);
502                                 }
503                                 EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
504                                     EPL_DLL_ERR_MN_CRC;
505                         }
506
507                         if ((EplErrorHandlerkInstance_g.m_MnCycTimeExceed.
508                              m_dwThreshold > 0)
509                             && ((ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) != 0)) {      // cycle time exceeded event occured
510                                 // increment cumulative counter by 1
511                                 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.
512                                     m_dwCumulativeCnt++;
513                                 // increment threshold counter by 8
514                                 EplErrorHandlerkInstance_g.m_MnCycTimeExceed.
515                                     m_dwThresholdCnt += 8;
516                                 if (EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThresholdCnt >= EplErrorHandlerkInstance_g.m_MnCycTimeExceed.m_dwThreshold) {      // threshold is reached
517                                         // $$$ d.k.: generate error history entry E_DLL_CYCLE_EXCEED_TH
518
519                                         // post event to NMT state machine
520                                         NmtEvent = kEplNmtEventNmtCycleError;
521                                         Event.m_EventSink = kEplEventSinkNmtk;
522                                         Event.m_EventType =
523                                             kEplEventTypeNmtEvent;
524                                         Event.m_pArg = &NmtEvent;
525                                         Event.m_uiSize = sizeof(NmtEvent);
526                                         Ret = EplEventkPost(&Event);
527                                 }
528                                 // $$$ d.k.: else generate error history entry E_DLL_CYCLE_EXCEED
529                                 EplErrorHandlerkInstance_g.m_ulDllErrorEvents |=
530                                     EPL_DLL_ERR_MN_CYCTIMEEXCEED;
531                         }
532
533                         if ((ulDllErrorEvents & EPL_DLL_ERR_MN_CN_LOSS_PRES) != 0) {    // CN loss PRes event occured
534                                 unsigned int uiNodeId;
535
536                                 uiNodeId = pErrHandlerEvent->m_uiNodeId - 1;
537                                 if ((uiNodeId <
538                                      tabentries(EplErrorHandlerkInstance_g.
539                                                 m_adwMnCnLossPresCumCnt))
540                                     && (EplErrorHandlerkInstance_g.
541                                         m_adwMnCnLossPresThreshold[uiNodeId] >
542                                         0)) {
543                                         // increment cumulative counter by 1
544                                         EplErrorHandlerkInstance_g.
545                                             m_adwMnCnLossPresCumCnt[uiNodeId]++;
546                                         // increment threshold counter by 8
547                                         EplErrorHandlerkInstance_g.
548                                             m_adwMnCnLossPresThrCnt[uiNodeId] +=
549                                             8;
550                                         if (EplErrorHandlerkInstance_g.
551                                             m_adwMnCnLossPresThrCnt[uiNodeId]
552                                             >= EplErrorHandlerkInstance_g.m_adwMnCnLossPresThreshold[uiNodeId]) {       // threshold is reached
553                                                 tEplHeartbeatEvent
554                                                     HeartbeatEvent;
555
556                                                 // $$$ d.k.: generate error history entry E_DLL_LOSS_PRES_TH
557
558                                                 // remove node from isochronous phase
559                                                 Ret =
560                                                     EplDllkDeleteNode
561                                                     (pErrHandlerEvent->
562                                                      m_uiNodeId);
563
564                                                 // inform NmtMnu module about state change, which shall send NMT command ResetNode to this CN
565                                                 HeartbeatEvent.m_uiNodeId =
566                                                     pErrHandlerEvent->
567                                                     m_uiNodeId;
568                                                 HeartbeatEvent.m_NmtState =
569                                                     kEplNmtCsNotActive;
570                                                 HeartbeatEvent.m_wErrorCode =
571                                                     EPL_E_DLL_LOSS_PRES_TH;
572                                                 Event.m_EventSink =
573                                                     kEplEventSinkNmtMnu;
574                                                 Event.m_EventType =
575                                                     kEplEventTypeHeartbeat;
576                                                 Event.m_uiSize =
577                                                     sizeof(HeartbeatEvent);
578                                                 Event.m_pArg = &HeartbeatEvent;
579                                                 Ret = EplEventkPost(&Event);
580                                         }
581                                         EplErrorHandlerkInstance_g.
582                                             m_afMnCnLossPresEvent[uiNodeId] =
583                                             TRUE;
584                                 }
585                         }
586 #endif
587
588                         break;
589                 }
590
591                 // NMT event
592         case kEplEventTypeNmtEvent:
593                 {
594                         if ((*(tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllCeSoa) {     // SoA event of CN -> decrement threshold counters
595
596                                 if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_LOSS_SOC) == 0) {   // decrement loss of SoC threshold counter, because it didn't occur last cycle
597                                         if (EplErrorHandlerkInstance_g.
598                                             m_CnLossSoc.m_dwThresholdCnt > 0) {
599                                                 EplErrorHandlerkInstance_g.
600                                                     m_CnLossSoc.
601                                                     m_dwThresholdCnt--;
602                                         }
603                                 }
604
605                                 if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_CN_CRC) == 0) {        // decrement CRC threshold counter, because it didn't occur last cycle
606                                         if (EplErrorHandlerkInstance_g.
607                                             m_CnCrcErr.m_dwThresholdCnt > 0) {
608                                                 EplErrorHandlerkInstance_g.
609                                                     m_CnCrcErr.
610                                                     m_dwThresholdCnt--;
611                                         }
612                                 }
613                         }
614 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
615                         else if ((*(tEplNmtEvent *) pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent) {    // SoA event of MN -> decrement threshold counters
616                                 tEplDllkNodeInfo *pIntNodeInfo;
617                                 unsigned int uiNodeId;
618
619                                 Ret = EplDllkGetFirstNodeInfo(&pIntNodeInfo);
620                                 if (Ret != kEplSuccessful) {
621                                         break;
622                                 }
623                                 // iterate through node info structure list
624                                 while (pIntNodeInfo != NULL) {
625                                         uiNodeId = pIntNodeInfo->m_uiNodeId - 1;
626                                         if (uiNodeId <
627                                             tabentries
628                                             (EplErrorHandlerkInstance_g.
629                                              m_adwMnCnLossPresCumCnt)) {
630                                                 if (EplErrorHandlerkInstance_g.
631                                                     m_afMnCnLossPresEvent
632                                                     [uiNodeId] == FALSE) {
633                                                         if (EplErrorHandlerkInstance_g.m_adwMnCnLossPresThrCnt[uiNodeId] > 0) {
634                                                                 EplErrorHandlerkInstance_g.
635                                                                     m_adwMnCnLossPresThrCnt
636                                                                     [uiNodeId]--;
637                                                         }
638                                                 } else {
639                                                         EplErrorHandlerkInstance_g.
640                                                             m_afMnCnLossPresEvent
641                                                             [uiNodeId] = FALSE;
642                                                 }
643                                         }
644                                         pIntNodeInfo =
645                                             pIntNodeInfo->m_pNextNodeInfo;
646                                 }
647
648                                 if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CRC) == 0) {        // decrement CRC threshold counter, because it didn't occur last cycle
649                                         if (EplErrorHandlerkInstance_g.
650                                             m_MnCrcErr.m_dwThresholdCnt > 0) {
651                                                 EplErrorHandlerkInstance_g.
652                                                     m_MnCrcErr.
653                                                     m_dwThresholdCnt--;
654                                         }
655                                 }
656
657                                 if ((EplErrorHandlerkInstance_g.m_ulDllErrorEvents & EPL_DLL_ERR_MN_CYCTIMEEXCEED) == 0) {      // decrement cycle exceed threshold counter, because it didn't occur last cycle
658                                         if (EplErrorHandlerkInstance_g.
659                                             m_MnCycTimeExceed.m_dwThresholdCnt >
660                                             0) {
661                                                 EplErrorHandlerkInstance_g.
662                                                     m_MnCycTimeExceed.
663                                                     m_dwThresholdCnt--;
664                                         }
665                                 }
666                         }
667 #endif
668
669                         // reset error events
670                         EplErrorHandlerkInstance_g.m_ulDllErrorEvents = 0L;
671
672                         break;
673                 }
674
675                 // unknown type
676         default:
677                 {
678                 }
679
680         }                       // end of switch(pEvent_p->m_EventType)
681
682         return Ret;
683
684 }
685
686 //=========================================================================//
687 //                                                                         //
688 //          P R I V A T E   F U N C T I O N S                              //
689 //                                                                         //
690 //=========================================================================//
691
692 //---------------------------------------------------------------------------
693 //
694 // Function:    EplErrorHandlerkLinkErrorCounter
695 //
696 // Description: link specified error counter structure to OD entry
697 //
698 // Parameters:  pErrorCounter_p         = pointer to error counter structure
699 //              uiIndex_p               = OD index
700 //
701 // Returns:     tEplKernel              = error code
702 //
703 //
704 // State:
705 //
706 //---------------------------------------------------------------------------
707
708 static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
709                                                    * pErrorCounter_p,
710                                                    unsigned int uiIndex_p)
711 {
712         tEplKernel Ret = kEplSuccessful;
713         tEplVarParam VarParam;
714
715         VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt;
716         VarParam.m_Size = sizeof(DWORD);
717         VarParam.m_uiIndex = uiIndex_p;
718         VarParam.m_uiSubindex = 0x01;
719         VarParam.m_ValidFlag = kVarValidAll;
720         Ret = EplObdDefineVar(&VarParam);
721         if (Ret != kEplSuccessful) {
722                 goto Exit;
723         }
724
725         VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt;
726         VarParam.m_Size = sizeof(DWORD);
727         VarParam.m_uiIndex = uiIndex_p;
728         VarParam.m_uiSubindex = 0x02;
729         VarParam.m_ValidFlag = kVarValidAll;
730         Ret = EplObdDefineVar(&VarParam);
731         if (Ret != kEplSuccessful) {
732                 goto Exit;
733         }
734
735         VarParam.m_pData = &pErrorCounter_p->m_dwThreshold;
736         VarParam.m_Size = sizeof(DWORD);
737         VarParam.m_uiIndex = uiIndex_p;
738         VarParam.m_uiSubindex = 0x03;
739         VarParam.m_ValidFlag = kVarValidAll;
740         Ret = EplObdDefineVar(&VarParam);
741         if (Ret != kEplSuccessful) {
742                 goto Exit;
743         }
744
745       Exit:
746         return Ret;
747 }
748
749 //---------------------------------------------------------------------------
750 //
751 // Function:    EplErrorHandlerkLinkErrorCounter
752 //
753 // Description: link specified error counter structure to OD entry
754 //
755 // Parameters:  pErrorCounter_p         = pointer to error counter structure
756 //              uiIndex_p               = OD index
757 //
758 // Returns:     tEplKernel              = error code
759 //
760 //
761 // State:
762 //
763 //---------------------------------------------------------------------------
764
765 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
766 static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
767                                             unsigned int uiValueCount_p,
768                                             unsigned int uiIndex_p)
769 {
770         tEplKernel Ret = kEplSuccessful;
771         tEplVarParam VarParam;
772         tEplObdSize EntrySize;
773         BYTE bIndexEntries;
774
775         EntrySize = (tEplObdSize) sizeof(bIndexEntries);
776         Ret = EplObdReadEntry(uiIndex_p,
777                               0x00, (void GENERIC *)&bIndexEntries, &EntrySize);
778
779         if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00)) {
780                 // Object doesn't exist or invalid entry number
781                 Ret = kEplObdIndexNotExist;
782                 goto Exit;
783         }
784
785         if (bIndexEntries < uiValueCount_p) {
786                 uiValueCount_p = bIndexEntries;
787         }
788
789         VarParam.m_Size = sizeof(DWORD);
790         VarParam.m_uiIndex = uiIndex_p;
791         VarParam.m_ValidFlag = kVarValidAll;
792
793         for (VarParam.m_uiSubindex = 0x01;
794              VarParam.m_uiSubindex <= uiValueCount_p; VarParam.m_uiSubindex++) {
795                 VarParam.m_pData = pdwValue_p;
796                 Ret = EplObdDefineVar(&VarParam);
797                 if (Ret != kEplSuccessful) {
798                         goto Exit;
799                 }
800                 pdwValue_p++;
801         }
802
803       Exit:
804         return Ret;
805 }
806 #endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
807
808 #endif //(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
809
810 // EOF