Staging: add epl stack
[safe/jmp/linux-2.6] / drivers / staging / epl / EplNmtCnu.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 NMT-CN-Userspace-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: EplNmtCnu.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.6 $  $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/06/09 k.t.:   start of the implementation
68
69 ****************************************************************************/
70
71 #include "EplInc.h"
72 #include "user/EplNmtCnu.h"
73 #include "user/EplDlluCal.h"
74
75 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
76
77 /***************************************************************************/
78 /*                                                                         */
79 /*                                                                         */
80 /*          G L O B A L   D E F I N I T I O N S                            */
81 /*                                                                         */
82 /*                                                                         */
83 /***************************************************************************/
84
85 //---------------------------------------------------------------------------
86 // const defines
87 //---------------------------------------------------------------------------
88
89 //---------------------------------------------------------------------------
90 // local types
91 //---------------------------------------------------------------------------
92
93 typedef struct
94 {
95     unsigned int                m_uiNodeId;
96     tEplNmtuCheckEventCallback  m_pfnCheckEventCb;
97
98 } tEplNmtCnuInstance;
99
100 //---------------------------------------------------------------------------
101 // modul globale vars
102 //---------------------------------------------------------------------------
103
104 static tEplNmtCnuInstance   EplNmtCnuInstance_g;
105
106 //---------------------------------------------------------------------------
107 // local function prototypes
108 //---------------------------------------------------------------------------
109
110 static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
111
112 static BOOL EplNmtCnuNodeIdList(BYTE* pbNmtCommandDate_p);
113
114 static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
115
116
117
118 //=========================================================================//
119 //                                                                         //
120 //          P U B L I C   F U N C T I O N S                                //
121 //                                                                         //
122 //=========================================================================//
123
124 //---------------------------------------------------------------------------
125 //
126 // Function:    EplNmtCnuInit
127 //
128 // Description: init the first instance of the module
129 //
130 //
131 //
132 // Parameters:      uiNodeId_p = NodeId of the local node
133 //
134 //
135 // Returns:         tEplKernel = errorcode
136 //
137 //
138 // State:
139 //
140 //---------------------------------------------------------------------------
141 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
142 {
143 tEplKernel Ret;
144
145     Ret = EplNmtCnuAddInstance(uiNodeId_p);
146
147     return Ret;
148 }
149
150 //---------------------------------------------------------------------------
151 //
152 // Function:    EplNmtCnuAddInstance
153 //
154 // Description: init the add new instance of the module
155 //
156 //
157 //
158 // Parameters:      uiNodeId_p = NodeId of the local node
159 //
160 //
161 // Returns:         tEplKernel = errorcode
162 //
163 //
164 // State:
165 //
166 //---------------------------------------------------------------------------
167 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
168 {
169 tEplKernel Ret;
170
171     Ret = kEplSuccessful;
172
173     // reset instance structure
174     EPL_MEMSET(&EplNmtCnuInstance_g, 0, sizeof (EplNmtCnuInstance_g));
175
176     // save nodeid
177     EplNmtCnuInstance_g.m_uiNodeId = uiNodeId_p;
178
179     // register callback-function for NMT-commands
180 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
181     Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
182                                    EplNmtCnuCommandCb,
183                                    kEplDllAsndFilterLocal);
184 #endif
185
186
187     return Ret;
188
189 }
190
191 //---------------------------------------------------------------------------
192 //
193 // Function:    EplNmtCnuDelInstance
194 //
195 // Description: delte instance of the module
196 //
197 //
198 //
199 // Parameters:
200 //
201 //
202 // Returns:         tEplKernel = errorcode
203 //
204 //
205 // State:
206 //
207 //---------------------------------------------------------------------------
208 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
209 {
210 tEplKernel Ret;
211
212     Ret = kEplSuccessful;
213
214 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
215     // deregister callback function from DLL
216     Ret = EplDlluCalRegAsndService(kEplDllAsndNmtCommand,
217                                    NULL,
218                                    kEplDllAsndFilterNone);
219 #endif
220
221     return Ret;
222 }
223
224 //---------------------------------------------------------------------------
225 //
226 // Function:    EplNmtCnuSendNmtRequest
227 //
228 // Description: Send an NMT-Request to the MN
229 //
230 //
231 //
232 // Parameters:      uiNodeId_p = NodeId of the local node
233 //                  NmtCommand_p = requested NMT-Command
234 //
235 //
236 // Returns:         tEplKernel = errorcode
237 //
238 //
239 // State:
240 //
241 //---------------------------------------------------------------------------
242 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(
243                                     unsigned int uiNodeId_p,
244                                     tEplNmtCommand NmtCommand_p)
245 {
246 tEplKernel      Ret;
247 tEplFrameInfo   NmtRequestFrameInfo;
248 tEplFrame       NmtRequestFrame;
249
250
251     Ret = kEplSuccessful;
252
253     // build frame
254     EPL_MEMSET(&NmtRequestFrame.m_be_abDstMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abDstMac)); // set by DLL
255     EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac)); // set by DLL
256     AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType, EPL_C_DLL_ETHERTYPE_EPL);
257     AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (BYTE) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
258     AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType, (BYTE)kEplMsgTypeAsnd);
259     AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId, (BYTE) kEplDllAsndNmtRequest);
260     AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bNmtCommandId,
261         (BYTE)NmtCommand_p);
262     AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId,
263         (BYTE)uiNodeId_p); // target for the nmt command
264     EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_abNmtCommandData[0], 0x00, sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_abNmtCommandData));
265
266
267
268     // build info-structure
269     NmtRequestFrameInfo.m_NetTime.m_dwNanoSec = 0;
270     NmtRequestFrameInfo.m_NetTime.m_dwSec = 0;
271     NmtRequestFrameInfo.m_pFrame = &NmtRequestFrame;
272     NmtRequestFrameInfo.m_uiFrameSize = EPL_C_DLL_MINSIZE_NMTREQ; // sizeof(NmtRequestFrame);
273
274     // send NMT-Request
275 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
276     Ret = EplDlluCalAsyncSend(&NmtRequestFrameInfo,    // pointer to frameinfo
277                            kEplDllAsyncReqPrioNmt); // priority
278 #endif
279
280
281     return Ret;
282 }
283
284
285 //---------------------------------------------------------------------------
286 //
287 // Function:    EplNmtCnuRegisterStateChangeCb
288 //
289 // Description: register Callback-function go get informed about a
290 //              NMT-Change-State-Event
291 //
292 //
293 //
294 // Parameters:  pfnEplNmtStateChangeCb_p = functionpointer
295 //
296 //
297 // Returns:     tEplKernel  = errorcode
298 //
299 //
300 // State:
301 //
302 //---------------------------------------------------------------------------
303
304 EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuRegisterCheckEventCb(
305             tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p)
306 {
307 tEplKernel Ret;
308
309     Ret = kEplSuccessful;
310
311     // save callback-function in modul global var
312     EplNmtCnuInstance_g.m_pfnCheckEventCb = pfnEplNmtCheckEventCb_p;
313
314     return Ret;
315
316 }
317
318 //=========================================================================//
319 //                                                                         //
320 //          P R I V A T E   F U N C T I O N S                              //
321 //                                                                         //
322 //=========================================================================//
323
324
325 //---------------------------------------------------------------------------
326 //
327 // Function:    EplNmtCnuCommandCb
328 //
329 // Description: callback funktion for NMT-Commands
330 //
331 //
332 //
333 // Parameters:      pFrameInfo_p = Frame with the NMT-Commando
334 //
335 //
336 // Returns:         tEplKernel = errorcode
337 //
338 //
339 // State:
340 //
341 //---------------------------------------------------------------------------
342 static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p)
343 {
344 tEplKernel      Ret = kEplSuccessful;
345 tEplNmtCommand  NmtCommand;
346 BOOL            fNodeIdInList;
347 tEplNmtEvent    NmtEvent = kEplNmtEventNoEvent;
348
349
350     if(pFrameInfo_p == NULL)
351     {
352         Ret = kEplNmtInvalidFramePointer;
353         goto Exit;
354     }
355
356     NmtCommand = EplNmtCnuGetNmtCommand(pFrameInfo_p);
357
358     // check NMT-Command
359     switch(NmtCommand)
360     {
361
362         //------------------------------------------------------------------------
363         // plain NMT state commands
364         case kEplNmtCmdStartNode:
365         {   // send NMT-Event to state maschine kEplNmtEventStartNode
366             NmtEvent = kEplNmtEventStartNode;
367             break;
368         }
369
370         case kEplNmtCmdStopNode:
371         {   // send NMT-Event to state maschine kEplNmtEventStopNode
372             NmtEvent = kEplNmtEventStopNode;
373             break;
374         }
375
376         case kEplNmtCmdEnterPreOperational2:
377         {   // send NMT-Event to state maschine kEplNmtEventEnterPreOperational2
378             NmtEvent = kEplNmtEventEnterPreOperational2;
379             break;
380         }
381
382         case kEplNmtCmdEnableReadyToOperate:
383         {   // send NMT-Event to state maschine kEplNmtEventEnableReadyToOperate
384             NmtEvent = kEplNmtEventEnableReadyToOperate;
385             break;
386         }
387
388         case kEplNmtCmdResetNode:
389         {   // send NMT-Event to state maschine kEplNmtEventResetNode
390             NmtEvent = kEplNmtEventResetNode;
391             break;
392         }
393
394         case kEplNmtCmdResetCommunication:
395         {   // send NMT-Event to state maschine kEplNmtEventResetCom
396             NmtEvent = kEplNmtEventResetCom;
397             break;
398         }
399
400         case kEplNmtCmdResetConfiguration:
401         {   // send NMT-Event to state maschine kEplNmtEventResetConfig
402             NmtEvent = kEplNmtEventResetConfig;
403             break;
404         }
405
406         case kEplNmtCmdSwReset:
407         {   // send NMT-Event to state maschine kEplNmtEventSwReset
408             NmtEvent = kEplNmtEventSwReset;
409             break;
410         }
411
412         //------------------------------------------------------------------------
413         // extended NMT state commands
414
415         case kEplNmtCmdStartNodeEx:
416         {
417             // check if own nodeid is in EPL node list
418             fNodeIdInList = EplNmtCnuNodeIdList(&(pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]));
419             if(fNodeIdInList != FALSE)
420             {   // own nodeid in list
421                 // send event to process command
422                 NmtEvent = kEplNmtEventStartNode;
423             }
424             break;
425         }
426
427         case kEplNmtCmdStopNodeEx:
428         {   // check if own nodeid is in EPL node list
429             fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
430             if(fNodeIdInList != FALSE)
431             {   // own nodeid in list
432                 // send event to process command
433                 NmtEvent = kEplNmtEventStopNode;
434             }
435             break;
436         }
437
438         case kEplNmtCmdEnterPreOperational2Ex:
439         {   // check if own nodeid is in EPL node list
440             fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
441             if(fNodeIdInList != FALSE)
442             {   // own nodeid in list
443                 // send event to process command
444                 NmtEvent = kEplNmtEventEnterPreOperational2;
445             }
446             break;
447         }
448
449         case kEplNmtCmdEnableReadyToOperateEx:
450         {   // check if own nodeid is in EPL node list
451             fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
452             if(fNodeIdInList != FALSE)
453             {   // own nodeid in list
454                 // send event to process command
455                 NmtEvent = kEplNmtEventEnableReadyToOperate;
456             }
457             break;
458         }
459
460         case kEplNmtCmdResetNodeEx:
461         {// check if own nodeid is in EPL node list
462             fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
463             if(fNodeIdInList != FALSE)
464             {   // own nodeid in list
465                 // send event to process command
466                 NmtEvent = kEplNmtEventResetNode;
467             }
468             break;
469         }
470
471         case kEplNmtCmdResetCommunicationEx:
472         {   // check if own nodeid is in EPL node list
473             fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
474             if(fNodeIdInList != FALSE)
475             {   // own nodeid in list
476                 // send event to process command
477                 NmtEvent = kEplNmtEventResetCom;
478             }
479             break;
480         }
481
482         case kEplNmtCmdResetConfigurationEx:
483         {   // check if own nodeid is in EPL node list
484             fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
485             if(fNodeIdInList != FALSE)
486             {   // own nodeid in list
487                 // send event to process command
488                 NmtEvent = kEplNmtEventResetConfig;
489             }
490             break;
491         }
492
493         case kEplNmtCmdSwResetEx:
494         {   // check if own nodeid is in EPL node list
495             fNodeIdInList = EplNmtCnuNodeIdList(&pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.m_le_abNmtCommandData[0]);
496             if(fNodeIdInList != FALSE)
497             {   // own nodeid in list
498                 // send event to process command
499                 NmtEvent = kEplNmtEventSwReset;
500             }
501             break;
502         }
503
504         //------------------------------------------------------------------------
505         // NMT managing commands
506
507         // TODO: add functions to process managing command (optional)
508
509         case kEplNmtCmdNetHostNameSet:
510         {
511             break;
512         }
513
514         case kEplNmtCmdFlushArpEntry:
515         {
516             break;
517         }
518
519         //------------------------------------------------------------------------
520         // NMT info services
521
522         // TODO: forward event with infos to the application (optional)
523
524         case kEplNmtCmdPublishConfiguredCN:
525         {
526             break;
527         }
528
529         case kEplNmtCmdPublishActiveCN:
530         {
531             break;
532         }
533
534         case kEplNmtCmdPublishPreOperational1:
535         {
536             break;
537         }
538
539         case kEplNmtCmdPublishPreOperational2:
540         {
541             break;
542         }
543
544         case kEplNmtCmdPublishReadyToOperate:
545         {
546             break;
547         }
548
549         case kEplNmtCmdPublishOperational:
550         {
551             break;
552         }
553
554         case kEplNmtCmdPublishStopped:
555         {
556             break;
557         }
558
559         case kEplNmtCmdPublishEmergencyNew:
560         {
561             break;
562         }
563
564         case kEplNmtCmdPublishTime:
565         {
566             break;
567         }
568
569         //-----------------------------------------------------------------------
570         // error from MN
571         // -> requested command not supported by MN
572         case kEplNmtCmdInvalidService:
573         {
574
575             // TODO: errorevent to application
576             break;
577         }
578
579         //------------------------------------------------------------------------
580         // default
581         default:
582         {
583             Ret = kEplNmtUnknownCommand;
584             goto Exit;
585         }
586
587     }// end of switch(NmtCommand)
588
589     if (NmtEvent != kEplNmtEventNoEvent)
590     {
591         if (EplNmtCnuInstance_g.m_pfnCheckEventCb != NULL)
592         {
593             Ret = EplNmtCnuInstance_g.m_pfnCheckEventCb(NmtEvent);
594             if (Ret == kEplReject)
595             {
596                 Ret = kEplSuccessful;
597                 goto Exit;
598             }
599             else if (Ret != kEplSuccessful)
600             {
601                 goto Exit;
602             }
603         }
604 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
605         Ret = EplNmtuNmtEvent(NmtEvent);
606 #endif
607     }
608
609 Exit:
610     return Ret;
611
612 }
613
614 //---------------------------------------------------------------------------
615 //
616 // Function:    EplNmtCnuGetNmtCommand()
617 //
618 // Description: returns the NMT-Command from the frame
619 //
620 //
621 //
622 // Parameters:      pFrameInfo_p = pointer to the Frame
623 //                                 with the NMT-Command
624 //
625 //
626 // Returns:         tEplNmtCommand = NMT-Command
627 //
628 //
629 // State:
630 //
631 //---------------------------------------------------------------------------
632 static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p)
633 {
634 tEplNmtCommand          NmtCommand;
635 tEplNmtCommandService*  pNmtCommandService;
636
637     pNmtCommandService = &pFrameInfo_p->m_pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService;
638
639     NmtCommand = (tEplNmtCommand)AmiGetByteFromLe(&pNmtCommandService->m_le_bNmtCommandId);
640
641     return NmtCommand;
642 }
643
644 //---------------------------------------------------------------------------
645 //
646 // Function:    EplNmtCnuNodeIdList()
647 //
648 // Description: check if the own nodeid is set in EPL Node List
649 //
650 //
651 //
652 // Parameters:      pbNmtCommandDate_p = pointer to the data of the NMT Command
653 //
654 //
655 // Returns:         BOOL = TRUE if nodeid is set in EPL Node List
656 //                         FALSE if nodeid not set in EPL Node List
657 //
658 //
659 // State:
660 //
661 //---------------------------------------------------------------------------
662 static BOOL EplNmtCnuNodeIdList(BYTE* pbNmtCommandDate_p)
663 {
664 BOOL            fNodeIdInList;
665 unsigned int    uiByteOffset;
666 BYTE            bBitOffset;
667 BYTE            bNodeListByte;
668
669     // get byte-offset of the own nodeid in NodeIdList
670     // devide though 8
671     uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3);
672     // get bitoffset
673     bBitOffset = (BYTE) EplNmtCnuInstance_g.m_uiNodeId % 8;
674
675     bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
676     if((bNodeListByte & bBitOffset) == 0)
677     {
678         fNodeIdInList = FALSE;
679     }
680     else
681     {
682         fNodeIdInList = TRUE;
683     }
684
685 return  fNodeIdInList;
686 }
687
688 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
689
690 // EOF
691