Adding rules.make to makefiles - PSDK5.0
[apps/tidep0079.git] / EC_Master_SysBios_Am572x / Workspace / SYSBIOS_AM57xx / emllICSS / icss_emac_ec_device.c
1 /*-----------------------------------------------------------------------------
2  * Based on Acontis EcDeviceCPSW.cpp
3  * Description             ICSS EMAC EtherCAT linklayer driver.
4  *---------------------------------------------------------------------------*/
6 /*-INCLUDES------------------------------------------------------------------*/
8 #include <xdc/std.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <assert.h> // //PC-- added TTS test
14 #include <xdc/runtime/Error.h>
15 #include <xdc/runtime/System.h>
16 #include <xdc/runtime/knl/Cache.h>
17 #include <ti/sysbios/BIOS.h>
18 #include <ti/sysbios/knl/Task.h>
19 #include <ti/sysbios/hal/Core.h>
21 #include <ti/csl/src/ip/icss/V1/cslr_icss_intc.h>
22 #include <ti/csl/src/ip/icss/V1/cslr_icss_iep.h> //PC-- added TTS test
23 #include <ti/csl/cslr_device.h>
25 #include <ti/drv/pruss/soc/am572x/pruicss_soc.c>
26 #include <ti/csl/soc/am572x/src/csl_device_xbar.h>
28 #include <ti/drv/uart/UART_stdio.h>
29 #include <ti/drv/icss_emac/test/src/tiemac_pruss_intc_mapping.h>
30 #include <ti/drv/icss_emac/src/icss_emacLoc.h>
31 #include <ti/drv/icss_emac/icss_emacDrv.h>
32 #include <ti/drv/icss_emac/firmware/icss_dualemac/config/icss_emacFwVersion.h>
33 #include <ti/drv/icss_emac/firmware/icss_dualemac/config/icss_emacFwConfig.h>
34 #include <ti/drv/icss_emac/test/src/fw_mem_section.h>
35 #include <ti/csl/soc.h>
36 #include <ti/csl/csl_armGicAux.h>
38 #include <ti/board/board.h>
40 #include <EcOs.h>
41 #include <EcError.h>
42 #include <EthernetServices.h>
43 #include <EcLink.h>
46 #include "icssEmacEcDevice.h"
48 /*-DEFINES-------------------------------------------------------------------*/
49 #define CPSWID "ICSS_EMAC"
50 #ifdef __cplusplus
51 #  define CCALLING extern "C" 
52 #else
53 #  define CCALLING
54 #endif /* ifdef __cplusplus */
56 #undef TRACE
58 #ifndef PRINT
59 #  if 0 // Used for tracing
60 #    define PRINT(msg, ...) fprintf(stdout, (msg), __VA_ARGS__); fflush(stdout) 
61 #  elif defined __GNUC__
62 #    define PRINT(msg, ...) LinkOsDbgMsg((msg), ##__VA_ARGS__)
63 #  else
64 #    define PRINT(msg, ...) LinkOsDbgMsg((msg), __VA_ARGS__)
65 #  endif
66 #endif
68 #ifdef DEBUG
69 #  if defined STARTERWARE_NOOS
70 int G_bCPSWverbose;
71 #    define DBG if (G_bCPSWverbose) PRINT
72 #  elif defined __GNUC__
73 #    define DBG(msg, ...) PRINT(CPSWID " DBG: " msg, ##__VA_ARGS__)
74 #  else
75 #    define DBG(msg, ...) PRINT(CPSWID " DBG: " msg, __VA_ARGS__)
76 #  endif
77 #else
78 #  define DBG(msg, ...)
79 #endif
81 #ifdef TRACE
82 #  if defined __GNUC__
83 #    define TRC(msg, ...) PRINT(CPSWID " TRC: " msg, ##__VA_ARGS__)
84 #  else
85 #    define TRC(msg, ...) PRINT(CPSWID " TRC: " msg, __VA_ARGS__)
86 #  endif
87 #else
88 #  define TRC(msg, ...)
89 #endif
91 #define _TRC(msg, ...) // Noop. Disabled TRC()
92 #if defined STARTERWARE_NOOS
93 #  define INF PRINT
94 #  define ERR PRINT
95 #elif defined __GNUC__
96 #  define INF(msg, ...) PRINT(CPSWID " INF: " msg, ##__VA_ARGS__)
97 #  define ERR(msg, ...) PRINT(CPSWID " ERR: " msg, ##__VA_ARGS__)
98 #else
99 #define INF(msg, ...) PRINT(CPSWID " INF: " msg, __VA_ARGS__)
100 #define ERR(msg, ...) PRINT(CPSWID " ERR: " msg, __VA_ARGS__)
101 #endif
103 #if defined STARTERWARE_NOOS && defined ADAPTER_DESC_FROM_UC_MEM
104 CCALLING EC_T_DWORD GetStartAddrDdrUc(void);
105 #endif
107 #define    ICSS_PORT0_PHY_ADDR          1
108 #define    ICSS_PORT1_PHY_ADDR          2
109 #define    ICSS_PORT1_PHY_ADDR_ICE2     3
110 unsigned int uartInstance =0;
112 #define RX_BUF_PTR(idx)  ((T_CPSW_FRAMEBUFENTRY *) (pAdapter->pRxBuffer + (idx) * sizeof(T_CPSW_FRAMEBUFENTRY)))
113 #define TX_BUF_PTR(idx)  ((T_CPSW_FRAMEBUFENTRY *) (pAdapter->pTxBuffer + (idx) * ICSS_TXBUFLEN))
114 /**This value in the MDIO Reg means 10 mbps mode is enabled*/
115 #define Ten_Mbps  0xa
116 /**This value in the MDIO Reg means 100 mbps mode is enabled*/
117 #define Hundread_Mbps 0x64
118 #define PKT_TX_COUNT 10
119 #define PRU2ETH0    2
120 #define PRU2ETH1    3
121 #ifdef  TTS
122 /*  TTS Macros  */
123 #define ICSS_EMAC_TTS_CONFIG_TIME               120000
124 #endif
127 /***************************************************************************************************
128 *                                 FORWARD DECLARATIONS
129 */
131 static EC_T_DWORD EcLinkOpen(void* pvLinkParms, EC_T_RECEIVEFRAMECALLBACK pfReceiveFrameCallback, EC_T_LINK_NOTIFY pfLinkNotifyCallback, void* pvContext, void** ppvInstance);
132 static EC_T_DWORD EcLinkClose(void *pvInstance);
133 static EC_T_LINKSTATUS EcLinkGetStatus(void *pvInstance);
135 static EC_T_BOOL ListAddOI(PT_ICSS_EC_INTERNAL poAdapter);
136 static EC_T_BOOL ListRmOI(PT_ICSS_EC_INTERNAL poAdapter);
138 static void ICSSRegisterSet(PT_ICSS_EC_INTERNAL pAdapter,uint8_t PRUSSinstance);
139 static void ICSSSetupBuffers(PT_ICSS_EC_INTERNAL pAdapter);
141 EC_T_DWORD emllPRUTestFrameRcv(void* pvContext, struct _EC_T_LINK_FRAMEDESC* pLinkFrameDesc, EC_T_BOOL* pbFrameProcessed);
142 EC_T_DWORD emllPRUTestNotify(EC_T_DWORD dwCode, struct _EC_T_LINK_NOTIFYPARMS* pParms);
144 static EC_T_BOOL sendAllFrames(EC_T_BYTE *frame, EC_T_DWORD frameLen, EC_T_BYTE dstAddr[6], EC_T_BYTE srcAddr[6], EC_T_DWORD *frameCounter, int txFrames);
145 static EC_T_BOOL sendFrame(EC_T_BYTE *frame, EC_T_DWORD frameLen, EC_T_BYTE dstAddr[6], EC_T_BYTE srcAddr[6]);
147 static EC_T_DWORD EcLinkGetEthernetAddress(void* pvInstance,EC_T_BYTE* pbyEthernetAddress );
148 static EC_T_LINKMODE EcLinkGetMode(void* pvInstance);
149 static EC_T_DWORD EcLinkGetSpeed(void* pvInstance);
150 static EC_T_DWORD EcLinkIoctl(void* pvInstance, EC_T_DWORD dwCode, EC_T_LINK_IOCTLPARMS*   pParms);
152 /***************************************************************************************************
153  * PRU-ICSS EMAC functions
154  */
155 static EC_T_DWORD ICSSPhyUpdateLinkStatus(PT_ICSS_EC_INTERNAL pAdapter,ICSS_EmacHandle icssemacHandle);
156 void ICSS_HardwareInit(EC_T_LINK_PARMS_ICSS *pLinkParmsAdapter);
157 int32_t ICSS_EMAC_PruIcssInstance2Setup(void);
158 void ICSS_EMAC_PruIcssFirmwareLoad(uint8_t instance);
159 void ICSS_EMAC_SocCtrlGetPortMacAddr(uint32_t portNum, uint8_t *pMacAddr);
160 void ICSS_EMAC_DrvInit(ICSS_EmacHandle handle, uint8_t instance);
161 void ICSS_EMAC_InterruptInit(ICSS_EmacHandle icssEmacHandle);
162 Bool ICSS_EMAC_IMemInit(PRUICSS_Handle ICSS_EMAC_PruIcssHandle );
163 Bool ICSS_EMAC_FwVerValidate(ICSS_EmacHandle icssEmacHandle);
164 Bool ICSS_EMAC_DMemInit(PRUICSS_Handle ICSS_EMAC_PruIcssHandle );
166 /* Call back functions registered with ICSS-EMAC LLD */
167 void ICSS_EMAC_CallbackRxPacket2(uint8_t* queueNum, void* ICSS_EmacSubSysHandle);
168 void ICSS_EMAC_CallbackRxPacket3(uint8_t* queueNum, void* ICSS_EmacSubSysHandle);
169 void ICSS_EMAC_CallbackTxComplete(void* ICSS_EmacSubSysHandle, void* arg2);
171 #ifdef  TTS
172 int8_t  ttsSemCreate();
173 /*  TTS Callback and Local functions    */
174 void ICSS_EMAC_TtsCycPort1Callback();
175 void ICSS_EMAC_TtsCycPort2Callback();
176 uint32_t deInitTTS(ICSS_EmacHandle icssEmacHandle);
177 EC_T_BYTE initTTS(ICSS_EmacHandle icssEmacHandle, uint32_t cyclePeriod);
178 /*  TTS Global Variables    */
179 SemaphoreP_Handle   ttsP1TxSem;
180 SemaphoreP_Handle   ttsP2TxSem;
181 #endif
182 /***************************************************************************************************
184 /***************************************************************************************************
185 *                                 LOCALS
186 */
187 static EC_T_INT                  S_nOpenedInstances;
188 static PT_ICSS_EC_INTERNAL       S_oOpenInstanceRoot;
190 /***************************************************************************************************
191 *                                 Variables
192 */
193 extern ICSS_EmacBaseAddrCfgParams icss_EmacBaseAddrCfgParams[3];
194 //extern uint8_t board_type; //PC-- Need to check if works May 19 2016
195 extern uint8_t ICSS_EMAC_testEvmType; //PC-- 03/14/2017
196 Board_IDInfo info;
198 PRUICSS_Handle pruIcssHandle2;
199 ICSS_EmacHandle emachandle2;
200 ICSS_EmacHandle emachandle3;
202 uint8_t lclMac2[6] = {0x01, 0xbb, 0xce, 0xdd, 0xee, 0xff};
203 uint8_t lclMac3[6] = {0x01, 0xb4, 0xc4, 0xd4, 0xe4, 0xff};
206 uint32_t packetLength = 0;
207 uint8_t packet_array[256] = {0};
209 void* pvLLInstance; //used in TestAppl
210 PT_BUF_QUEUE RxBufQueue;
211 PT_CPSW_FRAMEBUFENTRY pBufEntry_base;
213 uint32_t packetRcvd_port2 = 0;
214 uint32_t packetRcvd_port3 = 0;
215 uint32_t packetTxComplete_port2 = 0;
216 uint32_t packetTxComplete_port3 = 0;
218 #ifdef  TTS
219 uint8_t tts_enabled = EC_FALSE;
220 uint32_t max_jitter = 0;
221 #endif
223 uint32_t linkIsr_pru2eth0 = 0;
224 uint32_t linkIsr_pru2eth1 = 0;
226 //PC-- TX Priority Queue number. For TX callback function. Used to classify Cyc/Acycl
227 uint32_t TxPrioQueueNum = 0;
230 /***************************************************************************************************
231 *                                 DRIVER API
232 */
234 /********************************************************************************/
235 /** \brief Open Link Layer connection.
237 * \return EC_E_NOERROR or error code.
238 */
239 static EC_T_DWORD EcLinkOpen
240 (   
241    void*                      pvLinkParms,            /* [in]  link parameters */
242    EC_T_RECEIVEFRAMECALLBACK  pfReceiveFrameCallback, /* [in]  pointer to rx callback function */
243    EC_T_LINK_NOTIFY           pfLinkNotifyCallback,   /* [in]  pointer to notification callback function */
244    void*                      pvContext,              /* [in]  caller context, to be used in callback functions */
245    void**                     ppvInstance             /* [out] instance handle */
246  )
248     EC_T_DWORD dwRetVal = EC_E_ERROR;
249     EC_T_LINK_PARMS_ICSS *pLinkParmsAdapter = (EC_T_LINK_PARMS_ICSS*)pvLinkParms;
250     PT_ICSS_EC_INTERNAL pAdapter = EC_NULL;
252     EC_UNREFPARM(pfLinkNotifyCallback);
254     /* check parameters */
255     if (ppvInstance == EC_NULL)
256     {
257         System_printf("ICSS_EMAC-EcLinkOpen(): No memory for Driver Instance handle provided (ppvInstance may not be EC_NULL)!\n");
258         dwRetVal = EC_E_INVALIDPARM;
259         goto Exit;
260     }
261     if (pLinkParmsAdapter == EC_NULL)
262     {
263         System_printf("ICSS_EMAC-EcLinkOpen(): Missing Configuration for ICSS Link Layer!\n");
264         dwRetVal = EC_E_INVALIDPARM;
265         goto Exit;
266     }
267     if (pLinkParmsAdapter->linkParms.dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS)
268     {
269         System_printf("ICSS_EMAC-EcLinkOpen(): Invalid Configuration for ICSS Link Layer!\n");
270         dwRetVal = EC_E_INVALIDPARM;
271         goto Exit;
272     }
273     if ((EC_NULL == pfReceiveFrameCallback) && (EcLinkMode_INTERRUPT == pLinkParmsAdapter->linkParms.eLinkMode) )
274     {
275         System_printf("ICSS_EMAC-EcLinkOpen(): Missing receive frame callback for interrupt mode!\n");
276         dwRetVal = EC_E_INVALIDPARM;
277         goto Exit;
278     }
279     if ((pLinkParmsAdapter->linkParms.dwInstance < 1) || (pLinkParmsAdapter->linkParms.dwInstance > 2))
280     {
281         System_printf("ICSS_EMAC-EcLinkOpen(): Instance must be 1 or 2!\n");
282         dwRetVal = EC_E_INVALIDPARM;
283         goto Exit;
284     }
286     System_printf( "Instance %d, Port %d\n",
287            pLinkParmsAdapter->linkParms.dwInstance,
288            pLinkParmsAdapter->dwPort);
290    /* create instance */
291    *ppvInstance = EC_NULL;
293    pAdapter = (PT_ICSS_EC_INTERNAL) LinkOsMalloc(sizeof(T_ICSS_EC_INTERNAL));
294    LinkOsMemset(pAdapter, 0, sizeof(T_ICSS_EC_INTERNAL));
295    LinkOsMemcpy(&(pAdapter->oInitParms), pLinkParmsAdapter, sizeof(EC_T_LINK_PARMS_ICSS));
297    pAdapter->dwLosalHandle = LinkOsOpen();
299    //if (pAdapter->oInitParms.bMaster)
300    {
301       LinkOsPlatformInit();
302    }
304    //PC-- ICSS EMAC hardware Init
305    ICSS_HardwareInit(pLinkParmsAdapter); //PC-- ICSS and PRU init. PHY and MAC init. RX interrupt and RX tast init. PRU firmware load
306    ICSSRegisterSet(pAdapter,(uint8_t)pLinkParmsAdapter->linkParms.dwInstance);
308    /* configure new instance */
309    pAdapter->dwSignature            = EC_LINK_PARMS_SIGNATURE_ICSS;
310    pAdapter->pfReceiveFrameCallback = pfReceiveFrameCallback; //PC-- TODO: I think this callback function is not required since Receive works in polling mode only. Need to confirm
311    pAdapter->pvCallbackContext      = pvContext;
313    RxBufQueue=QueueBufCreate(); //PC-- RX ring buffer
314    pBufEntry_base= FrameBufEntryCreate(); //PC-- experimental trying to match Acontis buffers
316 // Store address of RX buffers
317    pAdapter->pRxBuffer = (EC_T_BYTE *)pBufEntry_base;
319    ICSSSetupBuffers(pAdapter); //PC-- experimental trying to match Acontis buffers
321    LinkOsSleep(2000); // wait until status is connected
323    //PC-- Update/Check Link status
324    EcLinkIoctl(pAdapter, EC_LINKIOCTL_UPDATE_LINKSTATUS, 0); // Update link status
325     if (EcLinkGetStatus(pAdapter) != eLinkStatus_OK)
326        {
327          System_printf("EcLinkOpen: LINK IS DOWN\n");
328        }else{
329          System_printf("EcLinkOpen: LINK IS UP\n");
330        }
332 // enqueue adapter
333    ListAddOI(pAdapter);
335 // increment instance counter
336    S_nOpenedInstances++;
338 // return "handle"
339   *ppvInstance = pAdapter;
341   // no errors
342   dwRetVal = EC_E_NOERROR;
344 Exit:
346    if (EC_E_NOERROR != dwRetVal && EC_E_INVALIDSTATE != dwRetVal)
347    {
348       *ppvInstance = EC_NULL;
350       if (EC_NULL != pAdapter)
351       {
352          EcLinkClose(pAdapter);
353          pAdapter = EC_NULL;
354       }
355    }
357    return dwRetVal;
358 };
360 /********************************************************************************/
361 /** \brief Close Link Layer connection.
363 * \return EC_E_NOERROR or error code.
364 */
365 static EC_T_DWORD EcLinkClose(
366                               void* pvInstance         /* [in] instance handle */
367                               )
369    EC_T_DWORD              dwRetVal    = EC_E_ERROR;
370    PT_ICSS_EC_INTERNAL     pAdapter    = (PT_ICSS_EC_INTERNAL) pvInstance;
372 #if defined DEBUG
373    // check for Type Signature */
374    if (EC_NULL == pAdapter || pAdapter->dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS)
375    {
376       dwRetVal = EC_E_INVALIDPARM;
377       goto Exit;
378    }
379 #endif
381    if ( EcLinkMode_INTERRUPT == pAdapter->oInitParms.linkParms.eLinkMode )
382    {
383       // Disable interrupt
384       LinkOsInterruptDisable( &pAdapter->oIrqParms );
385    }
387    //PC-- free RX ring FIFO buffer
388    QueueBufDestroy(RxBufQueue);
390    // Remove adapter instance from instance-list
391    ListRmOI(pAdapter);
392    S_nOpenedInstances--;
394    LinkOsFree(pAdapter);
396    dwRetVal = EC_E_NOERROR;
397    goto Exit;
399 Exit:
400    return dwRetVal;
401 };
403 /*****************************************************************************/
404 /** \brief Send data frame
406 * \return EC_E_NOERROR or error code.
407 */
408 //PC-- TODO: Set/Get the right pLinkFrameDesc input
409 static EC_T_DWORD EcLinkSendFrame(void* pvInstance, EC_T_LINK_FRAMEDESC* pLinkFrameDesc)
411    EC_T_DWORD                  dwRetVal    = EC_E_ERROR;
412    PT_ICSS_EC_INTERNAL         pAdapter    = (PT_ICSS_EC_INTERNAL) pvInstance;
413    ICSS_EmacTxArgument txArg;
414    EC_T_DWORD dwErr;
415    memset(&txArg, 0, sizeof(ICSS_EmacTxArgument));
416    txArg.srcAddress = pLinkFrameDesc->pbyFrame;
417    txArg.portNumber = (pAdapter->oInitParms.dwPort + 1);
418    txArg.queuePriority = 3;
419    txArg.lengthOfPacket = pLinkFrameDesc->dwSize;
421       if(pAdapter->oInitParms.linkParms.dwInstance==2 && pAdapter->oInitParms.dwPort==0){
422           txArg.icssEmacHandle = emachandle2;
423       }else if(pAdapter->oInitParms.linkParms.dwInstance==2 && pAdapter->oInitParms.dwPort==1){
424           txArg.icssEmacHandle = emachandle3;
425       }
427 #ifdef  TTS
428     uint8_t tts_cyc_byte_val;
429 #endif
431    if (pLinkFrameDesc->dwSize < 60)
432      {
433         ERR("Can't handle short TX frame (%u Bytes)\n", pLinkFrameDesc->dwSize);
434         dwRetVal = EC_E_ERROR;
435         goto Exit;
436      }
438     txArg.icssEmacHandle = emachandle2;
439     txArg.lengthOfPacket = pLinkFrameDesc->dwSize;
440     txArg.portNumber = (pAdapter->oInitParms.dwPort + 1);
441     txArg.srcAddress = pLinkFrameDesc->pbyFrame;
442     txArg.queuePriority = ICSS_EMAC_QUEUE4;
443     TxPrioQueueNum=4;
444 #ifdef  TTS
445     if(tts_enabled == EC_TRUE)
446     {
447         //Hack to queue cyclic frames in queue 1 and others in queue 2.
448         //TODO: Change this to use Acontis structure to find if packet is cyclic or acyclic.
449         tts_cyc_byte_val = HW_RD_REG8((uint32_t)((uint32_t)(pLinkFrameDesc->pbyFrame) + 44));
450         if(tts_cyc_byte_val==0xc)   //Cyclic Frame --> Queue 1
451         {
452             txArg.queuePriority = ICSS_EMAC_QUEUE1;
453             TxPrioQueueNum=1;
454         }
455         else    //Acyclic Frame --> Queue 2
456         {
457             txArg.queuePriority = ICSS_EMAC_QUEUE2;
458             TxPrioQueueNum=2;
459         }
460    }
461 #endif
463     dwRetVal = ICSS_EmacTxPacket(&txArg, NULL);
464     if (dwRetVal != EC_E_NOERROR)
465     {
466         System_printf( "ICSS_EmacTxPacket returned error 0x%x\n", dwRetVal);
467         return EC_E_ERROR;
468     }
469     // no errors
470     dwRetVal = EC_E_NOERROR;
472 Exit:
474    return dwRetVal;
475 };
477 /********************************************************************************/
478 /** \brief Send data frame and free the frame buffer. This function must be
479 *          supported if EcLinkAllocSendFrame() is supported
481 * \return EC_E_NOERROR or error code.
482 */
483 //PC-- TODO: Set/Get the right pLinkFrameDesc input
484 static EC_T_DWORD EcLinkSendAndFreeFrame(
485    void*           pvInstance,
486    EC_T_LINK_FRAMEDESC* pLinkFrameDesc      /* [in]  link frame descriptor */
487    )
489    EC_T_DWORD dwRetVal = EC_E_ERROR;
491    /* free-ing of buffers and descriptors is done during EcLinkAllocSendFrame so
492    * calling the send routine is enough */
493    dwRetVal = EcLinkSendFrame(pvInstance, pLinkFrameDesc);
495    return dwRetVal;
496 };
498 /********************************************************************************/
499 /** \brief Allocate a frame buffer used for send
501 *    If the link layer doesn't support frame allocation, this function must return
502 *    EC_E_NOTSUPPORTED
504 * \return EC_E_NOERROR or error code.
505 */
506 static EC_T_DWORD EcLinkAllocSendFrame(
507                                        void*           pvInstance,
508                                        EC_T_LINK_FRAMEDESC* pLinkFrameDesc,     /* [in/out]  link frame descriptor */
509                                        EC_T_DWORD           dwSize              /* [in]      size of the frame to allocate */
510                                        )
513 #if defined DEBUG
514    PT_ICSS_EC_INTERNAL      pAdapter    = (PT_ICSS_EC_INTERNAL) pvInstance;
515    /* check for Type Signature */
516    if (EC_NULL == pAdapter || pAdapter->dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS)
517    {
518       ERR("Can't alloc TX buffer (Invalid param)\n");
519       return EC_E_INVALIDPARM;
520    }
521 #endif
523    return EC_E_NOTSUPPORTED;;
524 };
526 /********************************************************************************/
527 /** \brief Release a frame buffer previously allocated with EcLinkAllocFrame()
529 */
530 static void  EcLinkFreeSendFrame(
531                                       void*           pvInstance,
532                                       EC_T_LINK_FRAMEDESC* pLinkFrameDesc      /* [in]  link frame descriptor */
533                                       )
535    EC_UNREFPARM(pvInstance);
537    if (!pLinkFrameDesc || !pLinkFrameDesc->pbyFrame)
538    {
539       return; // wrong parameter
540    }
541 //PC-- TODO: free TX buffer
543 };
546 /********************************************************************************/
547 /** \brief Poll for received frame. This function is called by the ethercat Master
548 *          if the function EcLinkGetMode() returns EcLinkMode_POLLING
550 * \return EC_E_NOERROR or error code.
551 */
552 static EC_T_DWORD EcLinkRecvFrame(void* pvInstance, EC_T_LINK_FRAMEDESC* pLinkFrameDesc)
555     EC_T_DWORD               dwRetVal = EC_E_ERROR;
557     // Needed by upper layer
558     pLinkFrameDesc->pbyFrame = NULL;
559     pLinkFrameDesc->dwSize = 0;
561     //PC-- check if there are buffers ready to be processed
562     if(RxBufQueue->NumWriteBuf>0)
563     {
564         pLinkFrameDesc->pbyFrame = (EC_T_BYTE*)(RxBufQueue->buffer + (RxBufQueue->head*BUF_SIZE));
565         pLinkFrameDesc->dwSize = (EC_T_DWORD)RxBufQueue->PktLength[RxBufQueue->head];
566     }
567     if(RxBufQueue->NumWriteBuf>MAX_NUM_BUF)
568     {
569         dwRetVal = EC_E_ERROR; //PC-- need to define an error.. it shouldn't happen
570         goto Exit;
571     }
573     dwRetVal = EC_E_NOERROR;
575     Exit:
577     return dwRetVal;
578 };
580 /********************************************************************************/
581 /** \brief Release a frame buffer given to the ethercat master through the receive
582 *          callback function
584 * \return Number of buffers that can be free.
585 */
586 EC_T_INT  EcLinkFreeRecvFrame(void* pvInstance, EC_T_LINK_FRAMEDESC* pLinkFrameDesc)
588    EC_T_INT             RemainingBuf=0;
589    RemainingBuf= QueueFreeBuf(RxBufQueue); //PC-- Free a buffer in Rx DDR ring Queue
591     return RemainingBuf;
592 };
594 /********************************************************************************/
595 /** \brief Determine link layer MAC address
597 * \return EC_E_NOERROR or error code.
598 */
599 static EC_T_DWORD EcLinkGetEthernetAddress(
600    void* pvInstance,
601    EC_T_BYTE* pbyEthernetAddress )   /* [out]  Ethernet MAC address */
603    PT_ICSS_EC_INTERNAL     pAdapter    = (PT_ICSS_EC_INTERNAL) pvInstance;
604    EC_T_DWORD              dwRetVal    = EC_E_ERROR;
606    /* check for Type Signature */
607    if ( (EC_NULL == pAdapter) || (pAdapter->dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS) )
608    {
609       dwRetVal = EC_E_INVALIDPARM;
610       goto Exit;
611    }
612    // TODO do nothing OsMemcpy(pbyEthernetAddress, pAdapter->oInitParms.abyStationAddress, 6);
613    dwRetVal = EC_E_NOERROR;
615 Exit:
616    return dwRetVal;
617 };
619 /********************************************************************************/
620 /** \brief Determine current link status.
621 * This routine is called in the EtherCAT main cycle. Be fast...
623 * \return Current link status.
624 */
625 static EC_T_LINKSTATUS EcLinkGetStatus(void* pvInstance)
627     PT_ICSS_EC_INTERNAL    pAdapter    = (PT_ICSS_EC_INTERNAL) pvInstance;
628     EC_T_DWORD linkStatus;
630 #if defined DEBUG
631    /* check for Type Signature */
632    if (EC_NULL == pAdapter || pAdapter->dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS)
633    {
634       return eLinkStatus_UNDEFINED;
635    }
636 #endif
637    linkStatus = pAdapter->dwLinkStatus;
638    if (linkStatus & ICSS_LINKFLAG_LINKOK)
639    {
640       if (linkStatus &
641             (ICSS_LINKFLAG_1000baseT_Half | ICSS_LINKFLAG_100baseT_Half | ICSS_LINKFLAG_10baseT_Half))
642       {
643          return eLinkStatus_HALFDUPLEX;
644       }
645       return eLinkStatus_OK;
646    }
647    return eLinkStatus_DISCONNECTED;
648 };
650 /********************************************************************************/
651 /** \brief Determine link speed.
653 * \return link speed in MBit/sec
654 */
655 static EC_T_DWORD EcLinkGetSpeed(void* pvInstance)
657    PT_ICSS_EC_INTERNAL     pAdapter    = (PT_ICSS_EC_INTERNAL) pvInstance;
658    EC_T_DWORD              dwSpeed     = 10;
660 #if defined DEBUG
661    /* check for Type Signature */
662    if (EC_NULL == pAdapter || pAdapter->dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS)
663    {
664       dwSpeed = EC_E_INVALIDPARM;
665       goto Exit;
666    }
667 #endif
669    if (pAdapter->dwLinkStatus & (ICSS_LINKFLAG_1000baseT_Full | ICSS_LINKFLAG_1000baseT_Half))
670    {
671       dwSpeed = 1000;
672    }
673    else if (pAdapter->dwLinkStatus & (ICSS_LINKFLAG_100baseT_Full | ICSS_LINKFLAG_100baseT_Half))
674    {
675       dwSpeed = 100;
676    }
677    goto Exit;
679 Exit:
680    return dwSpeed;
681 };
683 /********************************************************************************/
684 /** \brief Determine link mode
686 * \return link mode
687 */
688 static EC_T_LINKMODE EcLinkGetMode(void* pvInstance)
690    PT_ICSS_EC_INTERNAL      pAdapter    = (PT_ICSS_EC_INTERNAL)pvInstance;
691    EC_T_LINKMODE           oLink       = EcLinkMode_UNDEFINED;
693 #if defined DEBUG
694    /* check for Type Signature */
695    if (EC_NULL == pAdapter || pAdapter->dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS)
696    {
697       goto Exit;
698    }
699 #endif
701    oLink = pAdapter->oInitParms.linkParms.eLinkMode;
702    goto Exit;
704 Exit:
705    return oLink;
706 };
708 /********************************************************************************/
709 /** \brief Multi Purpose LinkLayer IOCTL
711 * \return EC_E_NOERROR or error code.
712 */
714 static EC_T_DWORD      EcLinkIoctl(
715                                    void*              pvInstance,
716                                    EC_T_DWORD              dwCode,
717                                    EC_T_LINK_IOCTLPARMS*   pParms
718                                    )
720    EC_T_DWORD          dwRetVal    = EC_E_ERROR;
721    PT_ICSS_EC_INTERNAL  pAdapter    = (PT_ICSS_EC_INTERNAL)pvInstance;
723 #if defined DEBUG
724    /* check for Type Signature */
725    if (EC_NULL == pAdapter || pAdapter->dwSignature != EC_LINK_PARMS_SIGNATURE_ICSS)
726    {
727       goto Exit;
728    }
729 #endif
731    /* fan out IOCTL functions */
734    switch( dwCode )
735    {
737    case EC_LINKIOCTL_UPDATE_LINKSTATUS:
738       {
739          //EC_T_DWORD dwOldLinkStatus = pAdapter->dwLinkStatus;
740           if(pAdapter->oInitParms.linkParms.dwInstance==2 && pAdapter->oInitParms.dwPort==0){
741               pAdapter->dwLinkStatus = ICSSPhyUpdateLinkStatus(pAdapter, emachandle2);
742           }else if(pAdapter->oInitParms.linkParms.dwInstance==2 && pAdapter->oInitParms.dwPort==1){
743               pAdapter->dwLinkStatus = ICSSPhyUpdateLinkStatus(pAdapter, emachandle3);
744           }
745          // Reconfigure MAC if PHY speed has changed
746 //         if (dwOldLinkStatus != pAdapter->dwLinkStatus)
747 //         {
748 //            CPSWUpdateMacSpeed(pAdapter);
749 //         }
750       } break;
752    case EC_LINKIOCTL_GET_ETHERNET_ADDRESS:
753         {
754             if ((EC_NULL == pParms) || (EC_NULL == pParms->pbyOutBuf) || (pParms->dwOutBufSize < 6))
755             {
756                 dwRetVal = EC_E_INVALIDPARM;
757                 goto Exit;
758             }
760             dwRetVal = EcLinkGetEthernetAddress(pAdapter, pParms->pbyOutBuf);
761         } break;
763    default:
764       {
765          dwRetVal = EC_E_INVALIDCMD;
766          goto Exit;
767       }
768    }
770    /* no error */
772    dwRetVal = EC_E_NOERROR;
774 Exit:
775    if( EC_E_NOERROR != dwRetVal )
776    {
777 #if (defined __RCX__)
778       if( bAllocIrq )
779       {
780          static RX_RESULT rxRes = RX_OK;
781          rxRes = rX_MemFreeMemory(pAdapter->hInterrupt);
782          OsDbgAssert(rxRes == RX_OK);
783       }
784 #else
785       ;;
786 #endif
787    }
788    return dwRetVal;
789 };
791 EC_T_DWORD emllPRUTestFrameRcv
792    (   void* pvContext,
793        struct _EC_T_LINK_FRAMEDESC* pLinkFrameDesc,
794        EC_T_BOOL* pbFrameProcessed
795    )
797     PT_ICSS_EC_INTERNAL pAdapter = (PT_ICSS_EC_INTERNAL) pvLLInstance;
798    EC_UNREFPARM(pvContext);
799    EC_UNREFPARM(pbFrameProcessed);
801 #ifdef TRACE
802    // Print frame
803    emllDumpFrame(EC_FALSE, (EC_T_BYTE *) pLinkFrameDesc->pbyFrame, pLinkFrameDesc->dwSize);
804 #endif
806    // Frame release
807    EcLinkFreeRecvFrame(pAdapter, pLinkFrameDesc);
809    return EC_E_NOERROR;
810 };
813 EC_T_DWORD emllPRUTestNotify(EC_T_DWORD dwCode, struct _EC_T_LINK_NOTIFYPARMS* pParms)
815    EC_UNREFPARM(dwCode);
816    EC_UNREFPARM(pParms);
817    return EC_E_NOERROR;
818 };
820 static EC_T_LINKSTATUS emllPRUTestGetStatus(void *pvLLInstance) // Query PHY's link status and reconfigure MAC
822    EcLinkIoctl(pvLLInstance, EC_LINKIOCTL_UPDATE_LINKSTATUS, 0); // Update link status
823    return EcLinkGetStatus(pvLLInstance);
824 };
826 static EC_T_BOOL sendAllFrames(
827    EC_T_BYTE *frame, EC_T_DWORD frameLen,
828    EC_T_BYTE dstAddr[6], EC_T_BYTE srcAddr[6],
829    EC_T_DWORD *frameCounter, int txFrames)
831     int j=0;
832     for (j = 0; j < txFrames; ++j)
833    {
834      if (!sendFrame(frame, frameLen, dstAddr, srcAddr)) return EC_FALSE; //PC-- for a quick test dst and src are not updated
835      System_printf("emllPRUTest: Sent frame %d\n",j);
836      (*frameCounter)++;
837    }
838    return EC_TRUE;
839 };
841 static EC_T_BOOL sendFrame(
842   EC_T_BYTE *frame, EC_T_DWORD frameLen,
843   EC_T_BYTE dstAddr[6], EC_T_BYTE srcAddr[6])
845    EC_T_DWORD dwStatus;
847    ICSS_EmacTxArgument txArg;
848    memset(&txArg, 0, sizeof(ICSS_EmacTxArgument));
849        txArg.srcAddress = frame;
850        txArg.portNumber = 1;
851        txArg.queuePriority = 3;
852        txArg.lengthOfPacket = frameLen;
853        txArg.icssEmacHandle = emachandle2;
855       dwStatus = ICSS_EmacTxPacket(&txArg, NULL);
857    if (dwStatus != EC_E_NOERROR)
858    {
859        System_printf( "ICSS_EmacTxPacket returned error 0x%x\n", dwStatus);
860       return EC_FALSE;
861    }
863     return EC_TRUE;
864 };
867 /********************************************************************************/
868 /** \brief Register link layer driver.
870 * \return EC_E_NOERROR or error code.
871 */
872 CCALLING EC_T_DWORD emllRegisterICSS(
873     EC_T_LINK_DRV_DESC*  pLinkDrvDesc        /* [in,out] link layer driver descriptor */
874    ,EC_T_DWORD           dwLinkDrvDescSize   /* [in]     size in bytes of link layer driver descriptor */
875    )
877    EC_T_DWORD dwResult = EC_E_NOERROR;
878    EC_T_BOOL bInterfaceSupported = EC_FALSE;
880    if (pLinkDrvDesc->dwValidationPattern != LINK_LAYER_DRV_DESC_PATTERN)
881    {
883       ERR("emllRegister: invalid descriptor pattern 0x%x instead of 0x%x\n",
884          pLinkDrvDesc->dwValidationPattern, LINK_LAYER_DRV_DESC_PATTERN);
885       dwResult = EC_E_INVALIDPARM;
886       goto Exit;
887    }
889    /* Check the size of the given link layer driver descriptor */
890    if (dwLinkDrvDescSize > sizeof(EC_T_LINK_DRV_DESC))
891    {
892       ERR("emllRegister: link layer driver descriptor size too large\n");
893       dwResult = EC_E_INVALIDPARM;
894       goto Exit;
895    }
897    bInterfaceSupported = EC_FALSE;
899    /* Check if the version of the interface is supported  */
900    if (   (sizeof(EC_T_LINK_DRV_DESC) == dwLinkDrvDescSize)
901       && (pLinkDrvDesc->dwInterfaceVersion == LINK_LAYER_DRV_DESC_VERSION) )
902    {
903       bInterfaceSupported = EC_TRUE;
904    }
906    /* Interface is not supported. */
907    if (! bInterfaceSupported)
908    {
909       ERR("emllRegister: invalid descriptor interface version 0x%x instead of 0x%x\n",
910          pLinkDrvDesc->dwInterfaceVersion, LINK_LAYER_DRV_DESC_VERSION);
911       dwResult = EC_E_INVALIDPARM;
912       goto Exit;
913    }
915    pLinkDrvDesc->pfEcLinkOpen = EcLinkOpen;
916    pLinkDrvDesc->pfEcLinkClose = EcLinkClose;
917    pLinkDrvDesc->pfEcLinkSendFrame = EcLinkSendFrame;
918    pLinkDrvDesc->pfEcLinkSendAndFreeFrame = EcLinkSendAndFreeFrame;
919    pLinkDrvDesc->pfEcLinkRecvFrame = EcLinkRecvFrame;
920    pLinkDrvDesc->pfEcLinkAllocSendFrame = EcLinkAllocSendFrame;
921    pLinkDrvDesc->pfEcLinkFreeSendFrame = EcLinkFreeSendFrame;
922    pLinkDrvDesc->pfEcLinkFreeRecvFrame = EcLinkFreeRecvFrame;
923    pLinkDrvDesc->pfEcLinkGetEthernetAddress = EcLinkGetEthernetAddress;
924    pLinkDrvDesc->pfEcLinkGetStatus = EcLinkGetStatus;
925    pLinkDrvDesc->pfEcLinkGetSpeed = EcLinkGetSpeed;
926    pLinkDrvDesc->pfEcLinkGetMode = EcLinkGetMode;
927    pLinkDrvDesc->pfEcLinkIoctl = EcLinkIoctl;
929    /* store DBG Message hook */
930    LinkOsAddDbgMsgHook(pLinkDrvDesc->pfOsDbgMsgHook);
932 Exit:
934    return dwResult;
935 };
937 /***************************************************************************************************
938 *                                 ICSS-PRU Initialization
939 */
941 /*
942  *    ---function to setup Timer for Receive Packet pacing---
943  */
945 int32_t ICSS_EMAC_TimerSetup(ICSS_EmacHandle icssEmacHandle)
947     void * timerHandle = NULL;
948     TimerP_Params timerParams;
950     memset(&timerParams, 0, sizeof(TimerP_Params));
951     ICSS_EMAC_osalTimerParamsInit(&timerParams);
953     timerParams.runMode = TimerP_RunMode_CONTINUOUS;
954     timerParams.startMode = TimerP_StartMode_USER;
955     timerParams.periodType = TimerP_PeriodType_MICROSECS;
956     timerParams.period = ICSS_EMAC_TEST_TIMER_PERIOD;
958     timerParams.arg = (void*)icssEmacHandle;
960     /*Create Interrupt Pacing Timer*/
961     timerHandle = ICSS_EMAC_osalTimerCreate(ICSS_EMAC_TEST_TIMER_ID, (TimerP_Fxn)ICSS_EmacInterruptPacingISR, &timerParams);
963     if ( timerHandle == NULL)
964     {
965        return -1;
966     }
967     else
968     {
969         ((ICSS_EmacObject*)icssEmacHandle->object)->rxPacingTimerHandle = timerHandle;
970         return 0;
971     }
972 };
974 void ICSS_HardwareInit(EC_T_LINK_PARMS_ICSS *pLinkParmsAdapter)
976         ICSS_EMAC_PruIcssInstance2Setup();
977         ICSS_EMAC_PruIcssFirmwareLoad(2);
978 };
980 int32_t ICSS_EMAC_PruIcssInstance2Setup(void)
982     PRUICSS_IntcInitData pruss_intc_initdata = PRUSS_INTC_INITDATA;
983     PRUICSS_Config  *cfg;
984     ICSS_EmacInitConfig* icss_emacInitCfg0;
985     ICSS_EmacInitConfig* icss_emacInitCfg1;
986     ICSS_EmacFwStaticMmap *pIcssEmacStaticMMap;
987     ICSS_EmacFwDynamicMmap *pIcssEmacDynamicMMap;
989     Task_Params taskParams;
990     int32_t ret  = PRUICSS_socGetInitCfg(&cfg);
991     if (ret  != PRUICSS_RETURN_SUCCESS)
992     {
993         return (ret);
994     }
996     pruIcssHandle2 = PRUICSS_create((PRUICSS_Config*)cfg,PRUICCSS_INSTANCE_TWO);
998     /* For PRU2 Eth0 */
999     CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_127, CSL_XBAR_PRUSS2_IRQ_HOST8);  /* link ISR */
1000     CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_137, CSL_XBAR_PRUSS2_IRQ_HOST2);  /* RX PKT ISR */
1001     CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_129, CSL_XBAR_PRUSS2_IRQ_HOST4);  /* TX PKT ISR */
1003     /* For PRU2 Eth1 */
1004         CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_134, CSL_XBAR_PRUSS2_IRQ_HOST9);  /* link ISR */
1005         CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_135, CSL_XBAR_PRUSS2_IRQ_HOST3);  /* RX PKT ISR */
1006         CSL_xbarMpuIrqConfigure(CSL_XBAR_INST_MPU_IRQ_136, CSL_XBAR_PRUSS2_IRQ_HOST5);  /* TX PKT ISR */
1008     /*PRU2 ETH0 initializations*/
1009     emachandle2 = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig));
1011     icss_emacInitCfg0 = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig));
1012     if ((emachandle2 == NULL) || (icss_emacInitCfg0 == NULL))
1013     {
1014         PRINT("main: malloc returned null\n");
1015     }
1017     icss_emacInitCfg0->phyAddr[0]=BOARD_ICSS_EMAC_PORT0_PHY_ADDR;
1018     icss_emacInitCfg0->portMask = ICSS_EMAC_MODE_MAC1;
1019     icss_emacInitCfg0->ethPrioQueue = ICSS_EMAC_QUEUE1;
1020     icss_emacInitCfg0->halfDuplexEnable = 0;
1021     icss_emacInitCfg0->enableIntrPacing = ICSS_EMAC_ENABLE_PACING;//ICSS_EMAC_ENABLE_PACING;
1022     icss_emacInitCfg0->ICSS_EmacIntrPacingMode = ICSS_EMAC_INTR_PACING_MODE2;
1023     icss_emacInitCfg0->pacingThreshold = 0;
1024     icss_emacInitCfg0->learningEn = 0;
1025     icss_emacInitCfg0->macId = lclMac2;
1027     ICSS_EMAC_DrvInit(emachandle2,2);
1028 #ifdef TTS
1029     /*Enable interrupt mode for TTS Cyclic Packet    */
1030     icss_emacInitCfg0->ICSS_EmacTTSEnableCycPktInterrupt = ICSS_EMAC_TTS_CYC_INTERRUPT_ENABLE;
1031 #endif
1032     icss_emacInitCfg0->rxIntNum = CSL_armGicGetGicIdForIrqInputLine(137);
1033     icss_emacInitCfg0->linkIntNum=CSL_armGicGetGicIdForIrqInputLine(127);
1034     icss_emacInitCfg0->txIntNum = CSL_armGicGetGicIdForIrqInputLine(129);
1036     ((ICSS_EmacObject*)emachandle2->object)->pruIcssHandle = pruIcssHandle2;
1037     ((ICSS_EmacObject*)emachandle2->object)->emacInitcfg = icss_emacInitCfg0;
1039     if (icss_emacGetFwMMapInitConfig(1, &pIcssEmacStaticMMap, &pIcssEmacDynamicMMap) != 0)
1040     {
1041         PRINT("ICSS_EMAC_PruIcssInstance2Setup: invalid instance Id when calling icss_emacGetFwStaticConfig\n");
1042         return -1;
1043     }
1045     icss_emacSetFwMMapInitConfig(emachandle2, 1, pIcssEmacStaticMMap, pIcssEmacDynamicMMap);
1047     ICSS_EmacInit(emachandle2,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC1|ICSS_EMAC_MODE_DUALMAC);
1048     ICSS_EmacRegisterHwIntRx(emachandle2, (ICSS_EmacCallBack)ICSS_EMAC_CallbackRxPacket2);
1049     ICSS_EmacRegisterHwIntTx(emachandle2, (ICSS_EmacCallBack)ICSS_EMAC_CallbackTxComplete);
1050     #ifdef TTS
1051     ICSS_EmacRegisterHwIntTTSCyc(emachandle2, (ICSS_EmacCallBack)ICSS_EMAC_TtsCycPort1Callback);
1052     #endif
1054         /*PRU2 ETH1 initializations*/
1055         emachandle3 = (ICSS_EmacHandle)malloc(sizeof(ICSS_EmacConfig));
1058         icss_emacInitCfg1 = (ICSS_EmacInitConfig*)malloc(sizeof(ICSS_EmacInitConfig));
1059         if ((emachandle3 == NULL) || (icss_emacInitCfg1 == NULL))
1060         {
1061             PRINT("main: malloc returned null\n");
1062         }
1063         icss_emacInitCfg1->phyAddr[0]= BOARD_ICSS_EMAC_PORT1_PHY_ADDR;
1065         icss_emacInitCfg1->portMask = ICSS_EMAC_MODE_MAC2;
1066         icss_emacInitCfg1->ethPrioQueue = ICSS_EMAC_QUEUE3;
1067         icss_emacInitCfg1->enableIntrPacing = ICSS_EMAC_DISABLE_PACING;
1068         icss_emacInitCfg1->pacingThreshold = 100;
1070         icss_emacInitCfg1->learningEn = 0;
1073         icss_emacInitCfg1->macId = lclMac3;
1075         ICSS_EMAC_DrvInit(emachandle3, 2);
1076 #ifdef TTS
1077         /*    Enable interrupt mode for TTS Cyclic Packet    */
1078         icss_emacInitCfg1->ICSS_EmacTTSEnableCycPktInterrupt = ICSS_EMAC_TTS_CYC_INTERRUPT_ENABLE;
1079 #endif
1081         icss_emacInitCfg1->rxIntNum = CSL_armGicGetGicIdForIrqInputLine(135);
1082         icss_emacInitCfg1->linkIntNum=CSL_armGicGetGicIdForIrqInputLine(134);
1083         icss_emacInitCfg1->txIntNum = CSL_armGicGetGicIdForIrqInputLine(136);
1085         ((ICSS_EmacObject*)emachandle3->object)->pruIcssHandle = pruIcssHandle2;
1086         ((ICSS_EmacObject*)emachandle3->object)->emacInitcfg = icss_emacInitCfg1;
1088          if (icss_emacGetFwMMapInitConfig(1, &pIcssEmacStaticMMap, &pIcssEmacDynamicMMap) != 0)
1089          {
1090              PRINT("ICSS_EMAC_PruIcssInstance2Setup: invalid instance Id when calling icss_emacGetFwStaticConfig\n");
1091              return -1;
1092          }
1093          icss_emacSetFwMMapInitConfig(emachandle3, 1, pIcssEmacStaticMMap, pIcssEmacDynamicMMap);
1096         ICSS_EmacInit(emachandle3,&pruss_intc_initdata,ICSS_EMAC_MODE_MAC2|ICSS_EMAC_MODE_DUALMAC);
1097         ICSS_EmacRegisterHwIntRx(emachandle3, (ICSS_EmacCallBack)ICSS_EMAC_CallbackRxPacket3);
1098         ICSS_EmacRegisterHwIntTx(emachandle3, (ICSS_EmacCallBack)ICSS_EMAC_CallbackTxComplete);
1099 #ifdef TTS
1100         ICSS_EmacRegisterHwIntTTSCyc(emachandle3, (ICSS_EmacCallBack)ICSS_EMAC_TtsCycPort2Callback);
1101 #endif
1103     Task_Params_init(&taskParams);
1104     taskParams.priority = 15;
1105     taskParams.instance->name = (char*)"port2_rxTaskFnc";
1106     taskParams.stackSize = 0x1000;
1107     taskParams.arg0 = (UArg)emachandle2;
1109     ((ICSS_EmacObject*)emachandle2->object)->rxTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsRxTaskFnc, &taskParams, NULL);
1110     if(((ICSS_EmacObject*)emachandle2->object)->rxTaskHandle==NULL)
1111     {
1112         return -2;
1113     }
1115     Task_Params_init(&taskParams);
1116     taskParams.priority = 15;
1117     taskParams.instance->name = (char*)"port2_txTaskFnc";
1118     taskParams.stackSize = 0x1000;
1119     taskParams.arg0 = (UArg)emachandle2;
1120     ((ICSS_EmacObject*)emachandle2->object)->txTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsTxTaskFnc, &taskParams, NULL);
1122     if(((ICSS_EmacObject*)emachandle2->object)->txTaskHandle==NULL)
1123     {
1124         return -2;
1125     }
1127     Task_Params_init(&taskParams);
1128     taskParams.priority = 15;
1129     taskParams.instance->name = (char*)"port2_linkTaskFnc";
1130     taskParams.stackSize = 0x1000;
1131     taskParams.arg0 = (UArg)emachandle2;
1132     ((ICSS_EmacObject*)emachandle2->object)->linkTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsLinkTaskFnc, &taskParams, NULL);
1134     if(((ICSS_EmacObject*)emachandle2->object)->linkTaskHandle==NULL)
1135     {
1136         return -2;
1137     }
1139 #ifdef TTS
1140     Task_Params_init(&taskParams);
1141     taskParams.priority = 15;
1142     taskParams.instance->name = (char*)"port2_ttsCycTaskFnc";
1143     taskParams.stackSize = 0x1000;
1144     taskParams.arg0 = (UArg)emachandle2;
1145     ((ICSS_EmacObject*)emachandle2->object)->ttsCycTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsTTSCycTaskFnc, &taskParams, NULL);
1147     if(((ICSS_EmacObject*)emachandle2->object)->ttsCycTaskHandle==NULL)
1148     {
1149         return -2;
1150     }
1151 #endif
1153         Task_Params_init(&taskParams);
1154         taskParams.priority = 15;
1155         taskParams.instance->name = (char*)"port3_rxTaskFnc";
1156         taskParams.stackSize = 0x1000;
1157         taskParams.arg0 = (UArg)emachandle3;
1159         ((ICSS_EmacObject*)emachandle3->object)->rxTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsRxTaskFnc, &taskParams, NULL);
1160         if(((ICSS_EmacObject*)emachandle3->object)->rxTaskHandle==NULL)
1161         {
1162             return -2;
1163         }
1165         Task_Params_init(&taskParams);
1166         taskParams.priority = 15;
1167         taskParams.instance->name = (char*)"port3_txTaskFnc";
1168         taskParams.stackSize = 0x1000;
1169         taskParams.arg0 = (UArg)emachandle3;
1170         ((ICSS_EmacObject*)emachandle3->object)->txTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsTxTaskFnc, &taskParams, NULL);
1173         if(((ICSS_EmacObject*)emachandle3->object)->txTaskHandle==NULL)
1174         {
1175             return -2;
1176         }
1179     Task_Params_init(&taskParams);
1180     taskParams.priority = 15;
1181     taskParams.instance->name = (char*)"port3_linkTaskFnc";
1182     taskParams.stackSize = 0x1000;
1183     taskParams.arg0 = (UArg)emachandle3;
1184     ((ICSS_EmacObject*)emachandle3->object)->linkTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsLinkTaskFnc, &taskParams, NULL);
1186     if(((ICSS_EmacObject*)emachandle3->object)->linkTaskHandle==NULL)
1187     {
1188         return -2;
1189     }
1191 #ifdef TTS
1192         Task_Params_init(&taskParams);
1193         taskParams.priority = 15;
1194         taskParams.instance->name = (char*)"port3_ttsCycTaskFnc";
1195         taskParams.stackSize = 0x1000;
1196         taskParams.arg0 = (UArg)emachandle3;
1197         ((ICSS_EmacObject*)emachandle3->object)->ttsCycTaskHandle = Task_create((ti_sysbios_knl_Task_FuncPtr)ICSS_EMacOsTTSCycTaskFnc, &taskParams, NULL);
1199         if(((ICSS_EmacObject*)emachandle3->object)->ttsCycTaskHandle==NULL)
1200         {
1201             return -2;
1202         }
1203 #endif
1205     ICSS_EMAC_InterruptInit(emachandle2);
1206     ICSS_EMAC_TimerSetup(emachandle2);
1207     ICSS_EMAC_InterruptInit(emachandle3);
1209     return 0;
1210 };
1212 Bool ICSS_EMAC_IMemInit(PRUICSS_Handle ICSS_EMAC_PruIcssHandle )
1214     Bool retVal = FALSE;
1215     uint32_t ICSS_EMAC_PgVersion = (HW_RD_REG32(CSL_MPU_CTRL_MODULE_WKUP_CORE_REGISTERS_REGS + CTRL_WKUP_ID_CODE) & 0xf0000000) >> 28;
1216     if (ICSS_EMAC_PgVersion >= 2)
1217         {
1218             if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_IRAM(0) ,0,
1219                                   (uint32_t *) &pru_imem0_rev2_start,
1220                               &pru_imem0_rev2_end - &pru_imem0_rev2_start))
1221             {
1222                 if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_IRAM(1) ,0,
1223                                       (uint32_t *) &pru_imem1_rev2_start,
1224                                   &pru_imem1_rev2_end - &pru_imem1_rev2_start))
1225                 {
1226                     retVal = TRUE;
1227                 }
1228             }
1229         }
1230         else
1231         {
1232             if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_IRAM(0) ,0,
1233                                   (uint32_t *) &pru_imem0_rev1_start,
1234                               &pru_imem0_rev1_end - &pru_imem0_rev1_start))
1235             {
1236                 if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_IRAM(1) ,0,
1237                                       (uint32_t *) &pru_imem1_rev1_start,
1238                                   &pru_imem1_rev1_end - &pru_imem1_rev1_start))
1239                 {
1240                     retVal = TRUE;
1241                 }
1242             }
1243         }
1244     return retVal;
1245 };
1247 Bool ICSS_EMAC_FwVerValidate(ICSS_EmacHandle icssEmacHandle)
1249     ICSS_EmacFwStaticMmap *pStaticMMap = (&((ICSS_EmacObject*)icssEmacHandle->object)->fwStaticMMap);
1251     if (HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr +pStaticMMap->versionOffset) != ICSS_FIRMWARE_RELEASE_1)
1252     {
1253         PRINT("ICSS_EMAC_FwVerValidate: Firmware validate failure\n");
1254         return FALSE;
1255     }
1256     else
1257     {
1258         if (HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr +pStaticMMap->version2Offset) != ICSS_FIRMWARE_RELEASE_2)
1259         {
1260             PRINT("ICSS_EMAC_FwVerValidate: Firmware validate failure\n");
1261             return FALSE;
1262         }
1263     }
1264     if (HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam1BaseAddr +pStaticMMap->versionOffset) != ICSS_FIRMWARE_RELEASE_1)
1265     {
1266         PRINT("ICSS_EMAC_FwVerValidate: Firmware validate failure\n");
1267         return FALSE;
1268     }
1269     else
1270     {
1271         if (HW_RD_REG32((((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam1BaseAddr +pStaticMMap->version2Offset) != ICSS_FIRMWARE_RELEASE_2)
1272         {
1273             PRINT("ICSS_EMAC_FwVerValidate: Firmware validate failure\n");
1274             return FALSE;
1275         }
1276     }
1277     PRINT("Validate PRU-ICSS EMAC Firmware: Release1: 0x%x, Release2: 0x%x\n", ICSS_FIRMWARE_RELEASE_1, ICSS_FIRMWARE_RELEASE_2);
1278     return TRUE;
1279 };
1281 Bool ICSS_EMAC_DMemInit(PRUICSS_Handle ICSS_EMAC_PruIcssHandle )
1284     Bool retVal = FALSE;
1285     uint32_t size = 16U;
1286     uint32_t ICSS_EMAC_PgVersion = (HW_RD_REG32(CSL_MPU_CTRL_MODULE_WKUP_CORE_REGISTERS_REGS + CTRL_WKUP_ID_CODE) & 0xf0000000) >> 28;
1287     if (ICSS_EMAC_PgVersion >= 2)
1288     {
1289         if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_DATARAM(0) ,0,
1290                               (uint32_t *) &pru_dmem0_rev2_start,
1291                               size))
1292         {
1293             if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_DATARAM(1) ,0,
1294                                   (uint32_t *) &pru_dmem1_rev2_start,
1295                               size))
1296             {
1297                 retVal = TRUE;
1298             }
1299         }
1300     }
1301     else
1302     {
1303         if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_DATARAM(0) ,0,
1304                               (uint32_t *) &pru_dmem0_rev1_start,
1305                               size))
1306         {
1307             if(PRUICSS_pruWriteMemory(ICSS_EMAC_PruIcssHandle,PRU_ICSS_DATARAM(1) ,0,
1308                                   (uint32_t *) &pru_dmem1_rev1_start,
1309                               size))
1310             {
1311                 retVal = TRUE;
1312             }
1313         }
1314     }
1315     return retVal;
1316 };
1318 void ICSS_EMAC_PruIcssFirmwareLoad(uint8_t instance)
1320         Bool retVal = FALSE;
1322         PRUICSS_pruDisable(pruIcssHandle2, ICSS_EMAC_PORT_1-1);
1323         PRUICSS_pruDisable(pruIcssHandle2, ICSS_EMAC_PORT_2-1);
1325            retVal = ICSS_EMAC_DMemInit(pruIcssHandle2);
1326            if (!retVal)
1327            {
1328                return;
1329            }
1330            retVal = ICSS_EMAC_FwVerValidate(emachandle2);
1331            if (!retVal)
1332            {
1333                return;
1334            }
1335            retVal = ICSS_EMAC_IMemInit(pruIcssHandle2);
1337            if( retVal)
1338            {
1339                PRUICSS_pruEnable(pruIcssHandle2, ICSS_EMAC_PORT_1-1);
1340                PRUICSS_pruEnable(pruIcssHandle2, ICSS_EMAC_PORT_2-1);
1341            }
1342 };
1344 void ICSS_EMAC_DrvInit(ICSS_EmacHandle handle, uint8_t instance) {
1346     /* LLD attributes mallocs */
1347     handle->object = (ICSS_EmacObject*)malloc(sizeof(ICSS_EmacObject));
1348     handle->hwAttrs= (ICSS_EmacHwAttrs*)malloc(sizeof(ICSS_EmacHwAttrs));
1350     /* Callback mallocs */
1351     ICSS_EmacCallBackObject* callBackObj = (ICSS_EmacCallBackObject*)malloc(sizeof(ICSS_EmacCallBackObject));
1353     callBackObj->learningExCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
1354     callBackObj->rxRTCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
1355     callBackObj->rxCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
1356     callBackObj->txCallBack=(ICSS_EmacCallBackConfig*)malloc(sizeof(ICSS_EmacCallBackConfig));
1357     ((ICSS_EmacObject*)handle->object)->callBackHandle = callBackObj;
1359     /*Allocate memory for learning*/
1360     ((ICSS_EmacObject*)handle->object)->macTablePtr = (HashTable_t*)malloc(NUM_PORTS * sizeof(HashTable_t));
1362     /*Allocate memory for PRU Statistics*/
1363     ((ICSS_EmacObject*)handle->object)->pruStat = (ICSS_EmacPruStatistics_t*)malloc(NUM_PORTS * sizeof(ICSS_EmacPruStatistics_t));
1365     /*Allocate memory for Host Statistics*/
1366     ((ICSS_EmacObject*)handle->object)->hostStat = (ICSS_EmacHostStatistics_t*)malloc(NUM_PORTS * sizeof(ICSS_EmacHostStatistics_t));
1368     /*Allocate memory for Storm Prevention*/
1369     ((ICSS_EmacObject*)handle->object)->stormPrevPtr = (stormPrevention_t*)malloc(NUM_PORTS * sizeof(stormPrevention_t));
1371     /* Base address initialization */
1372     if(NULL == ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg) {
1373         ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg =
1374                         (ICSS_EmacBaseAddressHandle_T)malloc(sizeof(ICSS_EmacBaseAddrCfgParams));
1375     }
1376     ICSS_EmacBaseAddressHandle_T emacBaseAddr = ((ICSS_EmacHwAttrs*)handle->hwAttrs)->emacBaseAddrCfg;
1378     ICSS_EmacSocGetInitCfg((instance-1), emacBaseAddr );
1380     /*    Restricting l3OcmcBaseAddr to 0x40xxxx00.
1381      *  This is done because L3 OCMC Base Address must be 256 byte aligned and to support OCMC memory usage for Linux Power Management.
1382      */
1383     emacBaseAddr->l3OcmcBaseAddr =  (((emacBaseAddr->l3OcmcBaseAddr)&0xFFFF00)|0x40000000);
1384     ICSS_EmacSocSetInitCfg((instance-1), emacBaseAddr );
1387     ICSS_EmacSocGetInitCfg((instance-1), emacBaseAddr );
1388 //    PRINT("ICSS_EMAC_DrvInit: instance: %d, data0RamSize: 0x%x, data1RamSize: 0x%x, sharedDataRamSize: 0x%x, l3OcmcSize: 0x%x\n",
1389 //                instance, emacBaseAddr->dataRam0Size, emacBaseAddr->dataRam1Size, emacBaseAddr->sharedDataRamSize, emacBaseAddr->l3OcmcSize);
1390 };
1392 /**
1393 * @internal
1394 * @brief Registering Interrupts and Enabling global interrupts
1396 * @param icssEmacHandle  icssEmacHandle handle to ICSS_EMAC Instance.
1398 * @retval none
1399 */
1400 void ICSS_EMAC_InterruptInit(ICSS_EmacHandle icssEmacHandle)
1402     HwiP_Handle rxHwiHandle;
1403     HwiP_Handle linkHwiHandle;
1404     HwiP_Handle txHwiHandle;
1406     static uint32_t cookie = 0;
1407     uint32_t linkIntrN = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->linkIntNum;
1409     uint32_t rxIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->rxIntNum;
1411     uint32_t txIntrN =   (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->txIntNum;
1413     cookie = ICSS_EMAC_osalHardwareIntDisable();
1415     HwiP_Params hwiParams;
1417     ICSS_EMAC_osalHwiParamsInit(&hwiParams);
1419     hwiParams.arg = (uintptr_t)icssEmacHandle;
1420     hwiParams.evtId = 0;
1421     hwiParams.priority = 20;
1424     rxHwiHandle = ICSS_EMAC_osalRegisterInterrupt(rxIntrN, (HwiP_Fxn)ICSS_EmacRxInterruptHandler, &hwiParams);
1425     if (rxHwiHandle == NULL ){
1426         return;
1427     }
1430     hwiParams.arg = (uintptr_t)icssEmacHandle;
1431     hwiParams.evtId = 0;
1432     hwiParams.priority = 20;
1433     linkHwiHandle = ICSS_EMAC_osalRegisterInterrupt(linkIntrN, (HwiP_Fxn)ICSS_EmacLinkISR, &hwiParams);
1435     if (linkHwiHandle == NULL) {
1436         return;
1437     }
1439     hwiParams.arg = (uintptr_t)icssEmacHandle;
1440     hwiParams.evtId = 0;
1441     hwiParams.priority = 20;
1442     txHwiHandle = ICSS_EMAC_osalRegisterInterrupt(txIntrN, (HwiP_Fxn)ICSS_EmacTxInterruptHandler, &hwiParams);
1445     if (txHwiHandle == NULL) {
1446         return;
1447     }
1448     ((ICSS_EmacObject*)icssEmacHandle->object)->txintHandle = txHwiHandle;
1450     ((ICSS_EmacObject*)icssEmacHandle->object)->rxintHandle = rxHwiHandle;
1451     ((ICSS_EmacObject*)icssEmacHandle->object)->linkintHandle = linkHwiHandle;
1453     ICSS_EMAC_osalHardwareIntRestore(cookie);
1454 };
1456 static void ICSSRegisterSet(PT_ICSS_EC_INTERNAL pAdapter, uint8_t PRUSSinstance)
1458    PICSS_EC_REGSET pRegs = &pAdapter->regs;
1459    EC_T_LINK_PLATFORMDATA_ICSS *pPCfg = &pAdapter->oInitParms.oPlatCfg;
1461    //PC-- TODO: need to check if Regs are required on both (pAdapter->regs and pAdapter->oInitParms.oPlatCfg) or if I can avoid double copy
1463            pPCfg->dwDataRam0BaseAddr = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].dataRam0BaseAddr;
1464            pPCfg->dwDataRam1BaseAddr = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].dataRam1BaseAddr;
1465            pPCfg->dwL3OcmcBaseAddr =  icss_EmacBaseAddrCfgParams[PRUSSinstance-1].l3OcmcBaseAddr;
1466            pPCfg->dwPrussCfgRegs =  icss_EmacBaseAddrCfgParams[PRUSSinstance-1].prussCfgRegs;
1467            pPCfg->dwPrussIepRegs =  icss_EmacBaseAddrCfgParams[PRUSSinstance-1].prussIepRegs;
1468            pPCfg->dwPrussIntcRegs = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].prussIntcRegs;
1469            pPCfg->dwPrussMiiMdioRegs = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].prussMiiMdioRegs;
1470            pPCfg->dwPrussMiiRtCfgRegsBaseAddr = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].prussMiiRtCfgRegsBaseAddr;
1471            pPCfg->dwPrussPru0CtrlRegs = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].prussPru0CtrlRegs;
1472            pPCfg->dwPrussPru1CtrlRegs = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].prussPru1CtrlRegs;
1473            pPCfg->dwSharedDataRamBaseAddrs = icss_EmacBaseAddrCfgParams[PRUSSinstance-1].sharedDataRamBaseAddr;
1474            pRegs->dwPrussMiiMdioRegs = pPCfg->dwPrussMiiMdioRegs;
1475            pRegs->dwDataRam0BaseAddr = pPCfg->dwDataRam0BaseAddr;
1476            pRegs->dwDataRam1BaseAddr = pPCfg->dwDataRam1BaseAddr;
1477            pRegs->dwL3OcmcBaseAddr = pPCfg->dwL3OcmcBaseAddr;
1478            pRegs->dwPrussCfgRegs = pPCfg->dwPrussCfgRegs;
1479            pRegs->dwPrussIepRegs = pPCfg->dwPrussIepRegs;
1480            pRegs->dwPrussIntcRegs = pPCfg->dwPrussIntcRegs;
1481            pRegs->dwPrussMiiRtCfgRegsBaseAddr = pPCfg->dwPrussMiiRtCfgRegsBaseAddr;
1482            pRegs->dwPrussPru0CtrlRegs = pPCfg->dwPrussPru0CtrlRegs;
1483            pRegs->dwPrussPru1CtrlRegs = pPCfg->dwPrussPru1CtrlRegs;
1484            pRegs->dwSharedDataRamBaseAddrs = pPCfg->dwSharedDataRamBaseAddrs;
1485 };
1487 #ifdef TTS
1488 /*  ---function to create TTS Semaphores---*/
1489 int8_t  ttsSemCreate()
1491     SemaphoreP_Params semParams;
1493     /*  Creating semaphores for TTS Task Port 1 */
1495     ICSS_EMAC_osalSemParamsInit(&semParams);
1496     semParams.mode = SemaphoreP_Mode_BINARY;
1497     semParams.name = "ttsPort1TxSemaphore";
1498     ttsP1TxSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
1499     if(ttsP1TxSem == NULL)
1500     {
1501             return -1;
1502     }
1504     /*  Creating semaphores for TTS Task Port 2 */
1506     ICSS_EMAC_osalSemParamsInit(&semParams);
1507     semParams.mode = SemaphoreP_Mode_BINARY;
1508     semParams.name = "ttsPort2TxSemaphore";
1509     ttsP2TxSem =  ICSS_EMAC_osalCreateBlockingLock(0, &semParams);
1510     if(ttsP2TxSem == NULL)
1511     {
1512             return -1;
1513     }
1515     return 0;
1516 };
1518 /*  Function to de-initialize time triggered send.*/
1519 uint32_t deInitTTS(ICSS_EmacHandle icssEmacHandle)
1521     ICSSEMAC_IoctlCmd ioctlParams;
1522     ICSS_EmacTTSConfig ttsConfig;
1523     uint8_t portNumber;
1524     int8_t ret;
1526     if(icssEmacHandle == emachandle2)
1527     {
1528         portNumber = ICSS_EMAC_PORT_1;
1529     }
1530     else
1531     {
1532         portNumber = ICSS_EMAC_PORT_2;
1533     }
1535     //Setting tts status (Port 1).
1536     ttsConfig.icssEmacHandle = icssEmacHandle;
1537     ttsConfig.statusTTS = ICSS_EMAC_TTS_DISABLE;
1538     ttsConfig.cyclePeriod = 0;
1539     ttsConfig.configTime = 0;
1540     ttsConfig.cycleStartTime = 0;
1541     ttsConfig.cycTxSOFStatus = ICSS_EMAC_TTS_CYC_TXSOF_DISABLE;
1542     ttsConfig.portNumber = portNumber;
1544     ioctlParams.command = 0;
1545     ioctlParams.ioctlVal = (void *)(&ttsConfig);
1547     //Disabling time triggered send on PORT 1 (PRU0).
1548     ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_CTRL, portNumber, &ioctlParams);
1549     assert(ret == 0);
1551     tts_enabled = EC_FALSE;
1552     return max_jitter; //PC-- added to return max_jitter for a quick test
1553 };
1555 /*  Function to initialize time triggered send.*/
1556 EC_T_BYTE initTTS(ICSS_EmacHandle icssEmacHandle, uint32_t cyclePeriod)
1558     int8_t ret;
1559     uint8_t portNumber;
1560     uint32_t iepRegsBase;
1561     uint64_t iepCounterVal;
1562     ICSSEMAC_IoctlCmd ioctlParams;
1563     ICSS_EmacTTSConfig ttsConfig;
1565     /*  Create TTS related semaphores   */
1566     ret = ttsSemCreate();
1567     assert(ret == 0);
1569     if(icssEmacHandle == emachandle2)
1570     {
1571         portNumber = ICSS_EMAC_PORT_1;
1572     }
1573     else //if(icssEmacHandle == emachandle3)
1574     {
1575         portNumber = ICSS_EMAC_PORT_2;
1576     }
1578     cyclePeriod *= 1000;    //Convert from us to ns.
1579     ioctlParams.command = 0;
1580     iepRegsBase = (((ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussIepRegs;
1582     ioctlParams.ioctlVal = (void *)(&ttsConfig);
1584     ttsConfig.icssEmacHandle = icssEmacHandle;
1585     ttsConfig.cycTxSOFStatus = ICSS_EMAC_TTS_CYC_TXSOF_ENABLE;
1586     ttsConfig.portNumber = portNumber;
1587     ttsConfig.configTime = ICSS_EMAC_TTS_CONFIG_TIME;
1588     ttsConfig.cyclePeriod = cyclePeriod;
1589     ttsConfig.statusTTS = ICSS_EMAC_TTS_ENABLE;
1591     //Reading IEP Counter Value.
1592     iepCounterVal = (*((uint64_t*)(iepRegsBase + CSL_ICSSIEP_COUNT_REG0)));
1594     /*  Calculating cycle start value by adding 100us to counter value. */
1595     ttsConfig.cycleStartTime = (uint64_t)(iepCounterVal + 100000);
1597     //Enabling time triggered send.
1598     ret = ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_TTS_CTRL, portNumber, &ioctlParams);
1599     assert(ret == 0);
1600     tts_enabled = EC_TRUE;
1601     return ret;
1602 };
1603 #endif  //TTS
1605 /***************************************************************************************************
1606 *                                 Buffer
1607 */
1608 PT_BUF_QUEUE QueueBufCreate(void)
1610     PT_BUF_QUEUE BufRing;
1612     BufRing = (PT_BUF_QUEUE)malloc(sizeof(BufferQueue));
1614   if (BufRing == NULL) {
1615       System_printf("QueueBufCreate: Insufficient Memory for new Queue.\n");
1616       exit(ERROR_MEMORY);
1617   }
1619   BufRing->head = 0;
1620   BufRing->NumAllocBuf = 0;
1621   BufRing->NumWriteBuf = 0;
1622   BufRing->NumReadBuf = 0;
1624   return BufRing;
1625 };
1627 PT_CPSW_FRAMEBUFENTRY FrameBufEntryCreate(void) //PC-- experimental trying to match Acontis buffers
1629     PT_CPSW_FRAMEBUFENTRY pBufEntry;
1631     pBufEntry = (PT_CPSW_FRAMEBUFENTRY)malloc(sizeof(T_CPSW_FRAMEBUFENTRY)*MAX_NUM_BUF);
1633   if (pBufEntry == NULL) {
1634       System_printf("FrameBufEntryCreate: Insufficient Memory for new Frame BufEntry.\n");
1635       exit(ERROR_MEMORY);
1636   }
1638  return pBufEntry;
1639 };
1641 void QueueBufDestroy(PT_BUF_QUEUE BufRing)
1643   free(BufRing);
1644 };
1646 EC_T_INT QueueFreeBuf(PT_BUF_QUEUE BufQueue)
1648     if (BufQueue->NumAllocBuf <= 0) {
1649         //System_printf("QueueFreeBuf: Deleting on Empty Queue.\n");
1650         //exit(ERROR_QUEUE);
1651       }
1653     if (BufQueue->NumReadBuf <= 0) {
1654             //System_printf("QueueFreeBuf: Buffers haven't been processed cannot be free.\n");
1655             //exit(ERROR_QUEUE);
1656           }
1657     BufQueue->PktLength[BufQueue->head]=0;
1658     BufQueue->head++; //PC-- Advance head index
1659     BufQueue->head %= MAX_NUM_BUF; //PC-- wraps around
1660     BufQueue->NumAllocBuf--;
1661     BufQueue->NumReadBuf--;
1662     BufQueue->NumWriteBuf--;
1663     return BufQueue->NumWriteBuf;
1664 };
1666 EC_T_BYTE* QueueAllocBuf(PT_BUF_QUEUE BufQueue)
1668   int newBufIndex;
1669   EC_T_BYTE *pBufInQueue;
1671   if (BufQueue->NumAllocBuf >= MAX_NUM_BUF) {
1672       System_printf("QueueAllocBuf: Allocating on Full Queue.\n");
1673       exit(ERROR_QUEUE);
1674   }
1675   newBufIndex = (BufQueue->head + BufQueue->NumAllocBuf)% MAX_NUM_BUF;
1676   pBufInQueue = (EC_T_BYTE *)(BufQueue->buffer + (newBufIndex*BUF_SIZE));
1677   BufQueue->NumAllocBuf++;
1678   return pBufInQueue;
1679 };
1681 //PC-- experimental trying to match Acontis buffers TODO: this is unfinished
1682 static void ICSSSetupBuffers(PT_ICSS_EC_INTERNAL pAdapter)
1684    T_CPSW_FRAMEBUFENTRY *pBufEntry;
1685    int i;
1687    for (i = 0; i < (ICSS_RXDESCNT); ++i)
1688    {
1689       pBufEntry = RX_BUF_PTR(i);
1690       pBufEntry->bufentry.dwMagicKey = BUFFER_MAGIC_RX;
1691       pBufEntry->bufentry.eBufState = BS_FREE;
1692    }
1693 };
1695 /***************************************************************************************************
1696 *                                 Callback function
1697 */
1698 void ICSS_EMAC_CallbackTxComplete(void* ICSS_EmacSubSysHandle, void* queueNum)
1701     if((ICSS_EmacHandle)ICSS_EmacSubSysHandle == emachandle2)
1702     {
1703        //UART_printf("packet transmission complete for packet(PRU2ETH0) %d\n", packetTxComplete_port2);
1704         packetTxComplete_port2++;
1705     }
1706      else if((ICSS_EmacHandle)ICSS_EmacSubSysHandle == emachandle3)
1707     {
1708         //UART_printf("packet transmission complete for packet(PRU2ETH1): %d\n", packetTxComplete_port3);
1709         packetTxComplete_port3++;
1710     }
1712 };
1714 #ifdef TTS
1715 /*
1716  * ---TTS Cyclic Packet Insertion Interrupt Callback Port 1---
1717  */
1718 void ICSS_EMAC_TtsCycPort1Callback()
1720     ICSS_EMAC_osalPostLock(ttsP1TxSem);
1721 };
1723 /*
1724  * ---TTS Cyclic Packet Insertion Interrupt Callback Port 2---
1725  */
1726 void ICSS_EMAC_TtsCycPort2Callback()
1728     ICSS_EMAC_osalPostLock(ttsP2TxSem);
1729 };
1730 #endif
1732 void ICSS_EMAC_CallbackRxPacket2(uint8_t* queueNum, void* ICSS_EmacSubSysHandle)
1735         uint32_t        tmp;
1736         int32_t         morePkts;
1737         int32_t         port;
1738         uint32_t        queue;
1739         uint32_t        idx;
1740         queue = (*queueNum);
1741         EC_T_BYTE*      pRxDDRbuf;
1742         packetLength=0;
1743         ICSS_EmacRxArgument rxArgs;
1745     rxArgs.icssEmacHandle = emachandle2;
1746     rxArgs.queueNumber = queue;
1747     rxArgs.more = &morePkts;
1748     rxArgs.port = &port;
1750     if((ICSS_EmacHandle)ICSS_EmacSubSysHandle == emachandle2) /* PRU2 ETH 0 */
1751     {
1753         for (tmp = 1; tmp; )
1754         {
1755         pRxDDRbuf = QueueAllocBuf(RxBufQueue);
1756         rxArgs.destAddress =  (uint32_t)pRxDDRbuf;
1757         packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
1759         if(packetLength>0)
1760         {
1762             RxBufQueue->NumWriteBuf++;
1763             idx= (RxBufQueue->head + RxBufQueue->NumAllocBuf-1)% MAX_NUM_BUF;
1764             RxBufQueue->PktLength[idx]=packetLength;
1766         }
1767         if(rxArgs.more== 0)
1768             tmp = 0;    // exit if there are no more packets
1770         }
1771     }
1772 }; /* PRU2 ETH 0 */
1774 void ICSS_EMAC_CallbackRxPacket3(uint8_t* queueNum, void* ICSS_EmacSubSysHandle)
1776         uint32_t        tmp;
1777         int32_t         morePkts;
1778         int32_t         port;
1779         uint32_t        queue;
1780         uint32_t        idx;
1781         queue = (*queueNum);
1782         EC_T_BYTE*      pRxDDRbuf;
1783         packetLength=0;
1784         ICSS_EmacRxArgument rxArgs;
1786     rxArgs.icssEmacHandle = emachandle3;
1787     rxArgs.queueNumber = queue;
1788     rxArgs.more = &morePkts;
1789     rxArgs.port = &port;
1791     if((ICSS_EmacHandle)ICSS_EmacSubSysHandle == emachandle3) /* PRU2 ETH 1 */
1792     {
1794         for (tmp = 1; tmp; )
1795         {
1796         pRxDDRbuf = QueueAllocBuf(RxBufQueue);
1797         rxArgs.destAddress =  (uint32_t)pRxDDRbuf;
1798         packetLength = ICSS_EmacRxPktGet(&rxArgs, NULL);
1800         if(packetLength>0)
1801         {
1803             RxBufQueue->NumWriteBuf++;
1804             idx= (RxBufQueue->head + RxBufQueue->NumAllocBuf-1)% MAX_NUM_BUF;
1805             RxBufQueue->PktLength[idx]=packetLength;
1807         }
1808         if(rxArgs.more== 0)
1809             tmp = 0;    // exit if there are no more packets
1811         }
1812     }
1813 };/* PRU2 ETH 1 */
1815 /***************************************************************************************************
1816 *                                 PHY & Co
1817 */
1819 static EC_T_DWORD ICSSPhyUpdateLinkStatus(PT_ICSS_EC_INTERNAL pAdapter, ICSS_EmacHandle icssemacHandle)
1821    EC_T_DWORD dwLinkStatus = 0;
1822    EC_T_DWORD phySpeed=0;
1823    volatile uint8_t portStatus = 0;
1824    ICSS_EmacFwStaticMmap *pStaticMMap = (&((ICSS_EmacObject*)icssemacHandle->object)->fwStaticMMap); //PC-- added 03/14/17
1826    dwLinkStatus = ICSS_EmacPhyLinkStatusGet((((ICSS_EmacHwAttrs*)icssemacHandle->hwAttrs)->emacBaseAddrCfg)->prussMiiMdioRegs,
1827                                                                     (((ICSS_EmacObject*)icssemacHandle->object)->emacInitcfg)->phyAddr[0],
1828                                                                     100);
1830    if (dwLinkStatus)
1831    {
1832       dwLinkStatus |= ICSS_LINKFLAG_LINKOK;
1833    }
1835  //phySpeed = *((uint32_t*)((((ICSS_EmacHwAttrs*)icssemacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr + PHY_SPEED_OFFSET));
1836    phySpeed = *((uint32_t*)((((ICSS_EmacHwAttrs*)icssemacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr + pStaticMMap->phySpeedOffset));
1837  //portStatus = *((uint8_t*)((((ICSS_EmacHwAttrs*)icssemacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr + PORT_STATUS_OFFSET));
1838    portStatus = *((uint8_t*)((((ICSS_EmacHwAttrs*)icssemacHandle->hwAttrs)->emacBaseAddrCfg)->dataRam0BaseAddr + pStaticMMap->portStatusOffset));
1840    if (phySpeed==Hundread_Mbps && portStatus==ICSS_EMAC_PORT_IS_HD_MASK )
1841     {
1842        pAdapter->dwPhyFeatures |= ICSS_LINKFLAG_100baseT_Half;
1843        dwLinkStatus |= ICSS_LINKFLAG_100baseT_Half;
1844     }
1846    if (phySpeed==Hundread_Mbps && portStatus!=ICSS_EMAC_PORT_IS_HD_MASK )
1847      {
1848        pAdapter->dwPhyFeatures |= ICSS_LINKFLAG_100baseT_Full;
1849        dwLinkStatus |= ICSS_LINKFLAG_100baseT_Full;
1850      }
1852    if (phySpeed==Ten_Mbps && portStatus==ICSS_EMAC_PORT_IS_HD_MASK )
1853      {
1854        pAdapter->dwPhyFeatures |= ICSS_LINKFLAG_10baseT_Half;
1855        dwLinkStatus |= ICSS_LINKFLAG_10baseT_Half;
1856      }
1858    if (phySpeed==Ten_Mbps && portStatus!=ICSS_EMAC_PORT_IS_HD_MASK )
1859      {
1860            pAdapter->dwPhyFeatures |= ICSS_LINKFLAG_10baseT_Full;
1861            dwLinkStatus |= ICSS_LINKFLAG_10baseT_Full;
1862      }
1864    return dwLinkStatus;
1865 };
1867 /***************************************************************************************************
1868 *                                 List Management
1869 */
1871 static EC_T_BOOL ListAddOI(PT_ICSS_EC_INTERNAL poAdapter)
1873    EC_T_BOOL           bResult = EC_TRUE;
1874    PT_ICSS_EC_INTERNAL oCur    = EC_NULL;
1876    oCur = S_oOpenInstanceRoot;
1878    if( EC_NULL == oCur )
1879    {
1880       S_oOpenInstanceRoot = poAdapter;
1881       S_oOpenInstanceRoot->pPrev = S_oOpenInstanceRoot->pNext = EC_NULL;
1882    }
1883    else
1884    {
1885       while( EC_NULL != oCur->pNext )
1886       {
1887          oCur = oCur->pNext;
1888       }
1890       oCur->pNext = poAdapter;
1891       poAdapter->pPrev = oCur;
1892       poAdapter->pNext = EC_NULL;
1893    };
1895    return bResult;
1896 };
1898 static EC_T_BOOL ListRmOI(PT_ICSS_EC_INTERNAL poAdapter)
1900    EC_T_BOOL       bResult = EC_TRUE;
1902    if( S_oOpenInstanceRoot == poAdapter )
1903    {
1904       S_oOpenInstanceRoot = poAdapter->pNext;
1905    }
1907    if( EC_NULL != poAdapter->pPrev )
1908    {
1909       poAdapter->pPrev->pNext = poAdapter->pNext;
1910    }
1912    if( EC_NULL != poAdapter->pNext )
1913    {
1914       poAdapter->pNext->pPrev = poAdapter->pPrev;
1915    }
1917    poAdapter->pPrev = EC_NULL;
1918    poAdapter->pNext = EC_NULL;
1920    return bResult;
1921 };
1923 void ICSS_EMAC_SocCtrlGetPortMacAddr(uint32_t addrIdx, uint8_t *pMacAddr)
1925 if(addrIdx == 0)
1926     {
1927         pMacAddr[2U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_1
1928                        >> 16U) & 0xFFU;
1929         pMacAddr[1U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_1
1930                        >> 8U) & 0xFFU;
1931         pMacAddr[0U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_1)
1932                       & 0xFF;
1933         pMacAddr[5U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_0
1934                        >> 16U) & 0xFFU;
1935         pMacAddr[4U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_0
1936                        >> 8U) & 0xFFU;
1937         pMacAddr[3U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_0)
1938                       & 0xFFU;
1939     }
1940     else
1941     {
1942         pMacAddr[2U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_3
1943                        >> 16U) & 0xFFU;
1944         pMacAddr[1U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_3
1945                        >> 8U) & 0xFFU;
1946         pMacAddr[0U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_3)
1947                       & 0xFF;
1948         pMacAddr[5U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_2
1949                        >> 16U) & 0xFFU;
1950         pMacAddr[4U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_2
1951                        >> 8U) & 0xFFU;
1952         pMacAddr[3U] =  (((CSL_control_coreRegs *) CSL_MPU_CTRL_MODULE_CORE_CORE_REGISTERS_REGS)->MAC_ID_SW_2)
1953                       & 0xFFU;
1954     }
1955 };
1959 /***************************************************************************************************
1960 *                                 TEST APPLICATION
1961 */
1962 static EC_T_BYTE   S_abyFrameData[60] =
1964    0xff, 0xff, 0xff, 0xff, 0xff, 0xff,   /* Dest Mac */                            /*0-5*/
1965    0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xBE,   /* Src Mac */                             /*6-11*/
1966    0x88, 0xa4,                           /* Type ECAT */                           /*12-13*/
1967    0x0e, 0x10,                           /* E88A4 Length 0x0e, Type ECAT (0x1) */  /*14-15*/
1968    0x01,                                 /* APRD */                                /*16*/
1969    0x80,                                 /* Index */                               /*17*/
1970    0x00, 0x00,                           /* Slave Address */                       /*18-19*/
1971    0x30, 0x01,                           /* Offset Address */                      /*20-21*/
1972    0x04, 0x00,                           /* Length - Last sub command */           /*22-23*/
1973    0x00, 0x00,                           /* Interrupt */                           /*24-25*/
1974    0x00, 0x00,                           /* Data */                                /*26-27*/
1975    0x00, 0x00,                           /* Data 2 */                              /*28-29*/
1976    0x00, 0x00                            /* Working Counter */                     /*30-31*/
1977 };
1979 #define TXBURST_FRAMES 8 // Number of frames to send per cycle
1980 #define RXMSK 1
1981 #define TXMSK 2
1983 //PC-- Test Application function
1984 void emll_ICSS_Test()
1986     EC_T_LINK_PARMS_ICSS LinkParamICSS;
1987    EC_T_DWORD dwStatus;
1988    EC_T_LINK_FRAMEDESC oRecvFrame = {0};
1990    EC_T_DWORD i;
1991    EC_T_BYTE dstAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
1992    EC_T_BYTE srcAddress[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xBA, 0xBE };
1993    EC_T_DWORD dwInstance = 0;
1994    EC_T_DWORD intFlag = 0;
1995    EC_T_BOOL bMaster = EC_FALSE;
1996    EC_T_DWORD rxtxMask = 0;
1997    EC_T_DWORD numframes = 0;
1998    EC_T_DWORD txFrames = 0;
1999    EC_T_DWORD rxFrames = 0;
2000    EC_T_INT RemainingRxframes =0;
2002    System_printf("emll_ICSS_Test test program\n");
2006 //PC-- hard code params
2007      dwInstance = 2; //ICSS Eth0 /* dwInstance is 1-based but port index is 0-based */
2008      intFlag = 0; //Polling
2009      bMaster = 'm';
2010      rxtxMask = 3;
2011      rxtxMask &= 0x3;
2012      numframes = 5;
2015       System_printf("\n\nInstance %d, Flags [%s] [%s] [%s %s], TX-Frames %d, "
2016       "Dst-Addr: %02x:%02x:%02x:%02x:%02x:%02x, Src-Addr: %02x:%02x:%02x:%02x:%02x:%02x\n\n",
2017       dwInstance,
2018       intFlag ? "Interrupt" : "Polling",
2019       bMaster ? "Master" : "Slave",
2020       (rxtxMask & RXMSK) ? "RX" : "--",
2021       (rxtxMask & TXMSK) ? "TX" : "--",
2022       numframes,
2023       dstAddress[0], dstAddress[1], dstAddress[2],
2024       dstAddress[3], dstAddress[4], dstAddress[5],
2025       srcAddress[0], srcAddress[1], srcAddress[2],
2026       srcAddress[3], srcAddress[4], srcAddress[5]);
2028    /* initialization */
2029    memset(&LinkParamICSS, 0, sizeof(LinkParamICSS));
2031    LinkParamICSS.linkParms.dwInstance = dwInstance;
2032    LinkParamICSS.linkParms.dwSignature = EC_LINK_PARMS_SIGNATURE_ICSS;
2033    LinkParamICSS.linkParms.eLinkMode = intFlag;
2035    dwStatus = EcLinkOpen( &LinkParamICSS, emllPRUTestFrameRcv, emllPRUTestNotify, EC_NULL, &pvLLInstance );
2036    //LinkParamICSS.dwPort =  (&pvLLInstance->oInitParms.dwPort+1)%2; // 0 -> Eth0, 1 -> Eth1
2037    LinkParamICSS.dwPort = 1;
2038    if (dwStatus != EC_E_NOERROR)
2039    {
2040        System_printf("emllPRUTest: error 0x%x in EcLinkOpen!\n", dwStatus );
2041       return;
2042    }
2044    // PC-- Check Link status in ICSS2 eth0
2045    // Wait for link
2046       while (emllPRUTestGetStatus(pvLLInstance) != eLinkStatus_OK)
2047       {
2048          LinkOsSleep(2000);
2049          System_printf("emll_ICSS_Test: LINK IS DOWN\n");
2050       }
2051          System_printf("emll_ICSS_Test: LINK IS UP\n");
2053     for (i = 0; numframes == 0 || i < numframes; ++i)
2054      {
2055         if (rxtxMask & TXMSK)
2056         {
2057            if (!sendAllFrames(S_abyFrameData, sizeof(S_abyFrameData),dstAddress, srcAddress, &txFrames, TXBURST_FRAMES))
2059                System_printf("emllICSSTest: Sent frame %d\n",i);
2060         }
2061         if (rxtxMask & RXMSK)
2062                 {
2063                    // receive frame(s)
2064             RemainingRxframes=0xff;
2065                    for (;;)
2066                    {
2067                       if(RemainingRxframes==0) break; //PC-- Nothing to be processed
2068                       dwStatus = EcLinkRecvFrame(pvLLInstance, &oRecvFrame);
2070                       // Simulated frame processing
2071                       Task_sleep(50);
2072                       //PC-- if buffer gets processed by EC-Master then we can mark it as read and free it
2073                       RxBufQueue->NumReadBuf++;
2075                       if (dwStatus != EC_E_NOERROR)
2076                       {
2077                       System_printf( "EcLinkRecvFrame returned error 0x%x\n", dwStatus);
2078                       goto Exit;
2079                       }
2081                       if (oRecvFrame.pbyFrame == EC_NULL) break;
2083                       rxFrames++;
2085                       // Release frame
2086                       if(RemainingRxframes>=0)
2087                       {
2088                           RemainingRxframes = EcLinkFreeRecvFrame(pvLLInstance, &oRecvFrame);
2089                       }
2090                    }
2091                 }
2092      }
2094    Exit:
2096       dwStatus = EcLinkClose( pvLLInstance );
2097       if( dwStatus != EC_E_NOERROR )
2098       {
2099          PRINT( "EcLinkClose returned error 0x%x\n", dwStatus );
2100          return;
2101       }
2102 };
2104 /*-END OF SOURCE FILE--------------------------------------------------------*/