]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/pdk.git/blob - packages/ti/transport/ndk/nimu_icss/src/nimu_icssSwitchEmac.c
75c6f33ae693a00ab9dd948194ad53fc1d721322
[processor-sdk/pdk.git] / packages / ti / transport / ndk / nimu_icss / src / nimu_icssSwitchEmac.c
1 /**
2  *   @file nimu_icssSwitchEmac.c
3  *   @brief
4  *      Contains helper functions used to implement NDK NIMU transport driver interface for ICSS
5  */
7 /* Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com/ 
8  *
9  *  Redistribution and use in source and binary forms, with or without 
10  *  modification, are permitted provided that the following conditions 
11  *  are met:
12  *
13  *    Redistributions of source code must retain the above copyright 
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  *    Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the 
18  *    documentation and/or other materials provided with the   
19  *    distribution.
20  *
21  *    Neither the name of Texas Instruments Incorporated nor the names of
22  *    its contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
26  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
27  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
29  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
30  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
31  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
34  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
35  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  */
39 #include <stdint.h>
40 #include <ti/csl/hw_types.h>
41 #if defined (SOC_AM335x) || defined (SOC_AM437x)
42 #include <ti/csl/src/ip/mdio/V2/cslr_mdio.h>
43 #include <ti/csl/src/ip/mdio/V2/csl_mdio.h>
44 #include <ti/csl/src/ip/mdio/V2/csl_mdioAux.h>
45 #else
46 #include <ti/csl/csl_mdioAux.h>
47 #endif
49 #include "ti/transport/ndk/nimu_icss/src/nimu_icss_transport_log.h"
50 #include "ti/transport/ndk/nimu_icss/src/nimu_icssSwitchEmac.h"
51 #include "ti/transport/ndk/nimu_icss/nimu_icssIoctl.h"
52 #include "ti/drv/icss_emac/icss_emacStatistics.h"
53 #include "ti/drv/icss_emac/icss_emacStormControl.h"
54 #include "ti/transport/ndk/nimu_icss/nimu_icssEth.h"
56 /* ========================================================================== */
57 /*                            Global Variables                                */
58 /* ========================================================================== */
62 void NIMU_ICSS_packetInit(NIMU_IcssEmacPkt* pNimuPacket)
63 {
64     PBM_Handle hPkt;
65     hPkt = PBM_alloc(1522U);
66     if (hPkt != NULL)
67     {
68         PBM_setDataOffset( hPkt, 0 );
69     
70         pNimuPacket->AppPrivate = (uint32_t)hPkt;
71         pNimuPacket->pDataBuffer  = PBM_getDataBuffer(hPkt);
72         pNimuPacket->BufferLen    = PBM_getBufferLen(hPkt);
73         pNimuPacket->DataOffset =  PBM_getDataOffset(hPkt);
74     }
75 }
77 /**
78 * @brief The function free Rx packet buffer
79 * @internal
80 * @param pi pointer to EMAC object
81 *
82 * @retval none
83 */
84 void NIMU_ICSS_packetShutdown(NIMU_IcssPdInfo *pi); /* misra warning */
85 void NIMU_ICSS_packetShutdown(NIMU_IcssPdInfo *pi)
86 {
88     NIMU_IcssDevice* nimuDevice = (NIMU_IcssDevice*)(((ICSS_EmacObject*)((pi->nimuDrvHandle)->object))->pvtInfo);
89     PBM_free( (PBM_Handle)((nimuDevice->nimuPktRx)->AppPrivate));
90 }
92 /**
93 * @brief Update our local copy of the statistics
94 * @internal
95 * @param pd pointer to EMAC object
96 *
97 * @retval none
98 *
99 * @pre EMAC peripheral instance must be opened
100 */
101 static void NIMU_ICSS_updateStats(NIMU_IcssPdInfo *pd, uint8_t portNo); /* misra warning */
102 static void NIMU_ICSS_updateStats(NIMU_IcssPdInfo *pd, uint8_t portNo)
104     uint8_t     i = 0;
105     ICSS_EmacHandle icssEmacHandle = pd->nimuDrvHandle;
106     NIMU_IcssDevice *nimuDevice = (NIMU_IcssDevice*)(((ICSS_EmacObject*)icssEmacHandle->object)->pvtInfo);
107     NIMU_IcssStatistics* nimuStats = nimuDevice->nimuStat;
108         ICSS_EmacPruStatistics_t *pruStatsPtr;
109         ICSS_EmacHostStatistics_t * hostStatsPtr;
110         ICSSEMAC_IoctlCmd ioctlParams;
112         /*Separate logic to get Switch and Mac statistics*/
113         if(ICSS_EMAC_MODE_SWITCH == ((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg->portMask)
114         {
115                 /*IOCTL Command to read Statistics to ICSSEMAC handle*/
116                 ioctlParams.command = ICSS_EMAC_IOCTL_STAT_CTRL_GET;
117                 ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_1, (void*)&ioctlParams);
118                 ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_2, (void*)&ioctlParams);
120                 pruStatsPtr = (ICSS_EmacPruStatistics_t*)(((ICSS_EmacObject*)icssEmacHandle->object)->pruStat);
121                 hostStatsPtr = (ICSS_EmacHostStatistics_t*)(((ICSS_EmacObject*)icssEmacHandle->object)->hostStat);
123                 /*Getting Host statistics*/
124                 (nimuStats)->txUcast += ((hostStatsPtr)->txUcast + (hostStatsPtr + 1)->txUcast);
125                 (nimuStats)->txBcast += ((hostStatsPtr)->txBcast + (hostStatsPtr + 1)->txBcast);
126                 (nimuStats)->txMcast += ((hostStatsPtr)->txMcast + (hostStatsPtr + 1)->txMcast);
127                 (nimuStats)->txGoodFrames += ((hostStatsPtr)->txUcast + (hostStatsPtr)->txBcast + (hostStatsPtr)->txMcast);
128                 (nimuStats)->txNetOctets += ((hostStatsPtr)->txOctets + (hostStatsPtr + 1)->txOctets);
129                 (nimuStats)->rxUcast+= ((hostStatsPtr)->rxUcast + (hostStatsPtr + 1)->rxUcast);
130                 (nimuStats)->rxBcast += ((hostStatsPtr)->rxBcast + (hostStatsPtr + 1)->rxBcast);
131                 (nimuStats)->rxMcast += ((hostStatsPtr)->rxMcast + (hostStatsPtr + 1)->rxMcast);
132                 (nimuStats)->rxGoodFrames += ((hostStatsPtr)->rxUcast + (hostStatsPtr)->rxBcast + (hostStatsPtr)->rxMcast);
133                 (nimuStats)->rxNetOctets += ((hostStatsPtr)->rxOctets + (hostStatsPtr + 1)->rxOctets);
134         (nimuStats)->rxUnknownProtocol += ((hostStatsPtr)->rxUnknownProtocol + (hostStatsPtr + 1)->rxUnknownProtocol);
135         (nimuStats)->droppedPackets = 0U;
138         for( i = 0U; i < NIMU_ICSS_NUM_MAC_PORTS; i++) {
140             (nimuStats + i + 1U)->txUcast += (pruStatsPtr + i)->txUcast;
141             (nimuStats + i + 1U)->txBcast += (pruStatsPtr + i)->txBcast;
142             (nimuStats + i + 1U)->txMcast += (pruStatsPtr + i)->txMcast;
143             (nimuStats + i + 1U)->txGoodFrames += ((pruStatsPtr + i)->txUcast + (pruStatsPtr + i)->txBcast \
144                                              + (pruStatsPtr + i)->txMcast);
145             (nimuStats + i + 1U)->txNetOctets += (pruStatsPtr + i)->txOctets;
147             (nimuStats + i + 1U)->rxUcast += (pruStatsPtr + i)->rxUcast;
148             (nimuStats + i + 1U)->rxBcast += (pruStatsPtr + i)->rxBcast;
149             (nimuStats + i + 1U)->rxMcast += (pruStatsPtr + i)->rxMcast;
151             (nimuStats + i + 1U)->rxGoodFrames += ((pruStatsPtr + i)->rxUcast + (pruStatsPtr + i)->rxBcast \
152                                               + (pruStatsPtr + i)->rxMcast);
153             (nimuStats + i + 1U)->rxNetOctets += (pruStatsPtr + i)->rxOctets;
154             (nimuStats + i + 1U)->rxErrorFrames += ((pruStatsPtr + i)->rxCRCFrames + (pruStatsPtr + i)->rxOverSizedFrames + (pruStatsPtr + i)->rxUnderSizedFrames
155                                                 + (pruStatsPtr + i)->rxMisAlignmentFrames);
156             (nimuStats + i + 1U)->rxUnknownProtocol += (hostStatsPtr + i)->rxUnknownProtocol;
157             (nimuStats + i + 1U)->droppedPackets += ((pruStatsPtr + i)->stormPrevCounter + (pruStatsPtr + i)->droppedPackets);
159             (nimuStats + i + 1U)->lateColl     += (pruStatsPtr + i)->lateColl;
160             (nimuStats + i + 1U)->excessColl     += (pruStatsPtr + i)->excessColl;
161             (nimuStats + i + 1U)->singleColl     += (pruStatsPtr + i)->singleColl;
162             (nimuStats + i + 1U)->multiColl     += (pruStatsPtr + i)->multiColl;
163             (nimuStats + i + 1U)->defTx         += (pruStatsPtr + i)->defTx;
164             (nimuStats + i + 1U)->macRxError     += ((pruStatsPtr + i)->macRxError + (pruStatsPtr + i)->SFDError);
166             }
168         /*IOCTL Command to Clear Statistics to ICSSEMAC handle.The nimu structure holds the stat */
169                 /* Increment the nimu structure values in next read */
170                 ioctlParams.command = ICSS_EMAC_IOCTL_STAT_CTRL_CLEAR;
171                 ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_1, (void*)&ioctlParams);
172                 ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_2, (void*)&ioctlParams);
173         }
174     else
175     {
176         /*IOCTL Command to read Statistics to ICSSEMAC handle*/
177         ioctlParams.command = ICSS_EMAC_IOCTL_STAT_CTRL_GET;
178         ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_STATS_CTRL, portNo, (void*)&ioctlParams);
180         pruStatsPtr = (ICSS_EmacPruStatistics_t*)(((ICSS_EmacObject*)icssEmacHandle->object)->pruStat);
181         hostStatsPtr = (ICSS_EmacHostStatistics_t*)(((ICSS_EmacObject*)icssEmacHandle->object)->hostStat);
183         /*Getting Host statistics*/
184         (nimuStats)->txUcast += (hostStatsPtr)->txUcast;
185         (nimuStats)->txBcast += (hostStatsPtr)->txBcast;
186         (nimuStats)->txMcast += (hostStatsPtr)->txMcast;
187         (nimuStats)->txGoodFrames += ((hostStatsPtr)->txUcast + (hostStatsPtr)->txBcast + (hostStatsPtr)->txMcast);
188         (nimuStats)->txNetOctets += (hostStatsPtr)->txOctets ;
189         (nimuStats)->rxUcast+= (hostStatsPtr)->rxUcast ;
190         (nimuStats)->rxBcast += (hostStatsPtr)->rxBcast ;
191         (nimuStats)->rxMcast += (hostStatsPtr)->rxMcast ;
192         (nimuStats)->rxGoodFrames += ((hostStatsPtr)->rxUcast + (hostStatsPtr)->rxBcast + (hostStatsPtr)->rxMcast); /* NA */
193         (nimuStats)->rxNetOctets += (hostStatsPtr)->rxOctets ;
194         (nimuStats)->rxUnknownProtocol += (hostStatsPtr)->rxUnknownProtocol;
195         (nimuStats)->droppedPackets = 0;
197         /*Getting Port statistics*/
198         (nimuStats + 1)->txUcast += (pruStatsPtr)->txUcast;
199         (nimuStats + 1)->txBcast += (pruStatsPtr)->txBcast;
200         (nimuStats + 1)->txMcast += (pruStatsPtr)->txMcast;
201         (nimuStats + 1)->txGoodFrames += ((pruStatsPtr)->txUcast + (pruStatsPtr)->txBcast \
202                                          + (pruStatsPtr)->txMcast);
203         (nimuStats + 1)->txNetOctets += (pruStatsPtr)->txOctets;
205         (nimuStats + 1)->rxUcast += (pruStatsPtr)->rxUcast;
206         (nimuStats + 1)->rxBcast += (pruStatsPtr)->rxBcast;
207         (nimuStats + 1)->rxMcast += (pruStatsPtr)->rxMcast;
209         (nimuStats + 1)->rxGoodFrames += ((pruStatsPtr)->rxUcast + (pruStatsPtr)->rxBcast \
210                                           + (pruStatsPtr)->rxMcast);
211         (nimuStats + 1)->rxNetOctets += (pruStatsPtr)->rxOctets;
212         (nimuStats + 1)->rxErrorFrames += ((pruStatsPtr)->rxCRCFrames + (pruStatsPtr)->rxOverSizedFrames + (pruStatsPtr)->rxUnderSizedFrames
213                                             + (pruStatsPtr)->rxMisAlignmentFrames);
214         (nimuStats + 1)->rxUnknownProtocol += (hostStatsPtr)->rxUnknownProtocol;
215         (nimuStats + 1)->droppedPackets += ((pruStatsPtr)->stormPrevCounter + (pruStatsPtr)->droppedPackets);
217         (nimuStats + 1)->lateColl     += (pruStatsPtr)->lateColl;
218         (nimuStats + 1)->excessColl     += (pruStatsPtr)->excessColl;
219         (nimuStats + 1)->singleColl     += (pruStatsPtr)->singleColl;
220         (nimuStats + 1)->multiColl     += (pruStatsPtr)->multiColl;
221         (nimuStats + 1)->defTx         += (pruStatsPtr)->defTx;
222         (nimuStats + 1)->macRxError     += ((pruStatsPtr)->macRxError + (pruStatsPtr)->SFDError);
225                 /*IOCTL Command to Clear Statistics to ICSSEMAC handle.The nimu structure holds the stat */
226                 /* Increment the nimu structure values in next read */
227                 ioctlParams.command = ICSS_EMAC_IOCTL_STAT_CTRL_CLEAR;
228                 ICSS_EmacIoctl(icssEmacHandle, ICSS_EMAC_IOCTL_STATS_CTRL, portNo, (void*)&ioctlParams);
229         }
233 /**********************************************************************
234  ***************** Switch Configuration Functions *********************
235  **********************************************************************/
238 /**
239 * @internal
240 * @brief Configures Address lookup engine (ALE) of EMAC.
242 * @param hPort       pointer to port object
244 * @retval none
246 */
247 static void NIMU_ICSS_setAleCfg(ICSS_EmacHandle handle); /* misra warning */
248 static void NIMU_ICSS_setAleCfg(ICSS_EmacHandle handle)
250     ICSSEMAC_IoctlCmd ioctlParams;
251     ioctlParams.command = ICSS_EMAC_LEARN_CTRL_INIT_TABLE;
252     if(ICSS_EMAC_MODE_SWITCH == (((ICSS_EmacObject*)handle->object)->emacInitcfg)->portMask)
253     {
254         if((((ICSS_EmacObject*)handle->object)->emacInitcfg)->learningEn)
255         {
256             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_LEARNING_CTRL, 0, (void*)&ioctlParams);
257         }
258     }
262 /**
263 * @internal
264 * @brief Configures Address lookup engine (ALE) of EMAC.
266 * @param hPort       pointer to port object
268 * @retval none
270 */
271 static void NIMU_ICSS_setRateControlCfg(ICSS_EmacHandle handle); /* misra warning */
272 static void NIMU_ICSS_setRateControlCfg(ICSS_EmacHandle handle)
274     ICSSEMAC_IoctlCmd ioctlParams;
275     ioctlParams.command = ICSS_EMAC_STORM_PREV_CTRL_INIT;
278     switch ((((ICSS_EmacObject*)handle->object)->emacInitcfg)->portMask)
279     {
280         case ICSS_EMAC_MODE_SWITCH:
281         {
282             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STORM_PREV_CTRL, ICSS_EMAC_PORT_1, (void*)&ioctlParams);
283             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STORM_PREV_CTRL, ICSS_EMAC_PORT_2, (void*)&ioctlParams);
284             break;
285         }
286         case ICSS_EMAC_MODE_MAC1:
287         {
288             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STORM_PREV_CTRL, ICSS_EMAC_PORT_1, (void*)&ioctlParams);
289             break;
290         }
291         case ICSS_EMAC_MODE_MAC2:
292         {
293             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STORM_PREV_CTRL, ICSS_EMAC_PORT_2, (void*)&ioctlParams);
294             break;
295         }
296         default:
297         {
298             break;
299         }
300     }
304 /**
305 * @internal
306 * @brief Configures Address lookup engine (ALE) of EMAC.
308 * @param hPort       pointer to port object
310 * @retval none
312 */
313 static void NIMU_ICSS_setStatisticsCfg(ICSS_EmacHandle handle); /* misra warning */
314 static void NIMU_ICSS_setStatisticsCfg(ICSS_EmacHandle handle)
316     ICSSEMAC_IoctlCmd ioctlParams;
317     ioctlParams.command = ICSS_EMAC_IOCTL_STAT_CTRL_CLEAR;
320     switch ((((ICSS_EmacObject*)handle->object)->emacInitcfg)->portMask)
321     {
322         case ICSS_EMAC_MODE_SWITCH:
323         {
324             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_1, (void*)&ioctlParams);
325             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_2, (void*)&ioctlParams);
326             break;
327         }
328         case ICSS_EMAC_MODE_MAC1:
329         {
330             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_1, (void*)&ioctlParams);
331             break;
332         }
333         case ICSS_EMAC_MODE_MAC2:
334         {
335             ICSS_EmacIoctl(handle, ICSS_EMAC_IOCTL_STATS_CTRL, ICSS_EMAC_PORT_2, (void*)&ioctlParams);
336             break;
337         }
338         default:
339         {
340             break;
341         }
342     }
347 /**
348 * @internal
349 * @brief This function opens and sets up a MAC port for communication.
351 * @param hPort               Handle to the Port object to setup
353 * @retval none
355 */
356 static void NIMU_ICSS_macOpen(uint32_t hPort,NIMU_IcssPdInfo * pi); /* misra warning */
357 static void NIMU_ICSS_macOpen(uint32_t hPort,NIMU_IcssPdInfo * pi)
360     uint32_t instId = hPort ;
361     ICSS_EmacHandle icssEmacHandle = pi->nimuDrvHandle;
362     uint32_t phyNum = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->phyAddr[instId];
363     uint32_t phyinst = (hPort + pi->PhysIdx);
364     uint32_t PhySel;
367     PhySel=phyNum;
368     PhySel = PhySel | (0x40U);
370     uint32_t baseAddr = (((const ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussMiiMdioRegs;
372     baseAddr = baseAddr + CSL_MDIO_USER_PHY_SEL_REG(0U);
374     baseAddr = baseAddr + (phyinst*8U);
376      HWREG(baseAddr) = PhySel;
380 static void NIMU_ICSS_macClose(uint32_t hPort,NIMU_IcssPdInfo * pi); /* misra warning */
381 static void NIMU_ICSS_macClose(uint32_t hPort,NIMU_IcssPdInfo * pi)
384     uint32_t instId = hPort ;
385     ICSS_EmacHandle icssEmacHandle = pi->nimuDrvHandle;
386     uint32_t phyNum = (((ICSS_EmacObject*)icssEmacHandle->object)->emacInitcfg)->phyAddr[instId];
387     uint32_t phyinst = (hPort + pi->PhysIdx);
388     uint32_t PhySel;
390     PhySel=phyNum;
391     PhySel = PhySel & ~((uint32_t)0x40U);
393     uint32_t baseAddr = (((const ICSS_EmacHwAttrs*)icssEmacHandle->hwAttrs)->emacBaseAddrCfg)->prussMiiMdioRegs;
395     baseAddr = baseAddr + CSL_MDIO_USER_PHY_SEL_REG(0U);
396     baseAddr = baseAddr + (phyinst*8U);
398      HWREG(baseAddr) = PhySel;
402 void NIMU_ICSS_openPeripheral(NIMU_IcssPdInfo *pi)
404     uint32_t              i;
405     uint32_t numPorts=0U;
407     if(ICSS_EMAC_MODE_SWITCH == (uint32_t)((((ICSS_EmacObject*)(pi->nimuDrvHandle)->object)->emacInitcfg)->portMask))
408     {
409         numPorts = 2U;
410     }
411     else
412     {
413         numPorts = 1U;
414     }
415     if(ICSS_EMAC_MODE_MAC2 != (((ICSS_EmacObject*)(pi->nimuDrvHandle)->object)->emacInitcfg)->portMask)
416     {
417         CSL_MDIO_init((((ICSS_EmacHwAttrs*)(pi->nimuDrvHandle)->hwAttrs)->emacBaseAddrCfg)->prussMiiMdioRegs,
418                                  NIMU_ICSS_DEFAULT_MDIOCLOCKFREQ,NIMU_ICSS_DEFAULT_MDIOBUSFREQ);
419     }
421     /* Open all ports */
422     for(i=0;i<numPorts; i++)
423     {
424         NIMU_ICSS_macOpen(i,pi);
425     }/* end of for loop over PORTS */
427     NIMU_ICSS_setAleCfg(pi->nimuDrvHandle);
429     NIMU_ICSS_setRateControlCfg(pi->nimuDrvHandle);
431     NIMU_ICSS_setStatisticsCfg(pi->nimuDrvHandle);
435 uint32_t NIMU_ICSS_closePeripheral(NIMU_IcssPdInfo *pi)
437     uint32_t i;
438     uint32_t numPorts;
440     if(ICSS_EMAC_MODE_SWITCH == (((ICSS_EmacObject*)(pi->nimuDrvHandle)->object)->emacInitcfg)->portMask)
441     {
442         numPorts =2U;
443     }
444     else
445     {
446         numPorts = 1U;
447     }
448     /* Close all ports */
449     for(i=0U;i<numPorts; i++)
450     {
451         NIMU_ICSS_macClose(i,pi);
452     }/* end of for loop over PORTS */
454     NIMU_ICSS_packetShutdown(pi);
456     /* Exit with interrupts still disabled in the wrapper */
457     return (NIMU_ICSS_SUCCESS);
459 /**
460 * @brief        Called to get the current device statistics. The statistics structure
461 *               contains a collection of event counts for various packet sent and
462 *               receive properties. Reading the statistics also clears the current
463 *               statistic counters, so the values read represent a delta from the last
464 *               call.
465 * @details  The statistics information is copied into the structure pointed to
466 *                       by the pStatistics argument.
467 *                       The function returns zero on success, or an error code on failure.
468 *                       Possible error code include:
469 *                       NIMU_ICSS_INVALID_PARAM   - A calling parameter is invalid
470 * @internal
471 * @param  hEMAC       handle to the opened EMAC device
472 * @param  pStatistics Pointer to the device statistics
473 * @param  portNo   port number
475 * @retval       Success (0)
476 *                       NIMU_ICSS_INVALID_PARAM   - A calling parameter is invalid
477 * @pre      EMAC peripheral instance must be opened before calling this API
479 */
480 uint32_t NIMU_ICSS_getStatistics(NIMU_IcssPdInfo *pi, NIMU_IcssStatistics *pStatistics,uint8_t portNo)
482     uint32_t retVal;
483     NIMU_IcssDevice *nimuDevice = (NIMU_IcssDevice*)(((ICSS_EmacObject*)(pi->nimuDrvHandle)->object)->pvtInfo);
484     NIMU_IcssStatistics* nimuStats = nimuDevice->nimuStat;
486     if(portNo > NIMU_ICSS_NUM_MAC_PORTS)
487     {
488             retVal =  NIMU_ICSS_INVALID_PORT;
489     }
490     else
491     {
492         /* Update the stats */
493         NIMU_ICSS_updateStats(pi, portNo);
494         /* Copy the updated stats to the application */
495         *pStatistics = *(nimuStats + portNo);
496         retVal = NIMU_ICSS_SUCCESS;
497     }
498     return (retVal);
500 /**
501 * @brief        Called to clear the current device statistics for a particular port
502 * @internal
503 * @param  pi       handle to the opened EMAC device
504 * @param  portNo   port to clear statistics
506 * @retval       Success (0)
507 *                       NIMU_ICSS_INVALID_PARAM   - A calling parameter is invalid
508 * @pre      EMAC peripheral instance must be opened before calling this API
510 */
511 uint32_t NIMU_ICSS_clearStatistics(NIMU_IcssPdInfo *pi,uint8_t portNo)
513     uint32_t retVal;
514     NIMU_IcssDevice *nimuDevice = (NIMU_IcssDevice*)(((ICSS_EmacObject*)(pi->nimuDrvHandle)->object)->pvtInfo);
515     NIMU_IcssStatistics* nimuStats = nimuDevice->nimuStat;
516     if(portNo > NIMU_ICSS_NUM_MAC_PORTS)
517     {
518             retVal =  NIMU_ICSS_INVALID_PORT;
519     }
520     else
521     {
522         NIMU_ICSS_updateStats(pi, portNo);
523         memset((nimuStats + portNo),0,sizeof(NIMU_IcssStatistics));
524         retVal = NIMU_ICSS_SUCCESS;
525     }
526     return (retVal);
530 uint32_t NIMU_ICSS_setConfig(NIMU_IcssPdInfo *pi, void* pBuf, uint32_t size)
532     uint32_t  ret_val = NIMU_ICSS_SUCCESS;
533     uint32_t port;
534     NIMU_IcssConsCmd * swConsCommand = (NIMU_IcssConsCmd *)pBuf;
535     ICSS_EmacHandle emachandle = pi->nimuDrvHandle;
536     uint8_t mode =0;
537     uint32_t mdioBaseAdd;
538     uint32_t phyAddr;
539     uint16_t regStatus = 0U;
540     mdioBaseAdd= (((ICSS_EmacHwAttrs*)emachandle->hwAttrs)->emacBaseAddrCfg)->prussMiiMdioRegs;
541     uint8_t macMode = (((ICSS_EmacObject*)emachandle->object)->emacInitcfg)->portMask;
543     switch(swConsCommand->opcode)
544     {
545         case ICSS_IOCTL_SET_PORT_CONFIG:
546         {
547             NIMU_IcssPortCmd *lpPortCmd = &swConsCommand->PortCmd;
548             uint8_t port = lpPortCmd->port;
549             if( (lpPortCmd->port < 2) && (lpPortCmd->EnDis < 2))
550             {
551                 switch(lpPortCmd->value)
552                 {
553                     case 0:
554                     {
555                         mode=PHY_CONFIG_AUTONEG;
556                         break;
557                     }
558                     case 10:
559                     {
560                         if(lpPortCmd->EnDis ==1)
561                         {
562                             mode=PHY_CONFIG_10FD;
563                         }
564                         else
565                         {
566                             mode=PHY_CONFIG_10HD;
567                         }
568                         break;
569                     }
570                     case 100:
571                     {
572                         if(lpPortCmd->EnDis ==1)
573                         {
574                             mode=PHY_CONFIG_100FD;
575                         }
576                         else
577                         {
578                             mode=PHY_CONFIG_100HD;
579                         }
580                          break;
581                     }
582                     default:
583                     {
584                         mode=PHY_CONFIG_AUTONEG;
585                         break;
586                     }
587                 }/* end of switch construct  */
589                 if(macMode == ICSS_EMAC_MODE_SWITCH)
590                 {
591                     if(port > 0U)
592                     {
593                         phyAddr =(((ICSS_EmacObject*)emachandle->object)->emacInitcfg)->phyAddr[port-1U];
594                     }
595                     else
596                     {
597                         ret_val = NIMU_ICSS_INVALID_PORT;
598                      }
599                 }
600                 else
601                 {
602                     phyAddr = (((ICSS_EmacObject*)emachandle->object)->emacInitcfg)->phyAddr[0U];
603                 }
604                 if (ret_val == NIMU_ICSS_SUCCESS)
605                 {
606                     regStatus = 0;
607                     CSL_MDIO_phyRegRead(mdioBaseAdd, phyAddr, NIMU_ICSS_PHY_BMCR_REG, &regStatus);
608                     switch(mode)
609                     {
610                          case PHY_CONFIG_AUTONEG:
611                               regStatus = regStatus | NIMU_ICSS_MII_AUTO_NEGOTIATE_EN;
612                              break;
613                          case PHY_CONFIG_100FD:
614                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_AUTO_NEGOTIATE_EN));
615                              regStatus = regStatus | NIMU_ICSS_MII_SPEEDSEL_100;
616                              regStatus = regStatus | NIMU_ICSS_MII_DUPLEXMODE_FULL;
618                              
619                              break;
620                          case PHY_CONFIG_10FD:
621                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_AUTO_NEGOTIATE_EN));
622                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_SPEEDSEL_100));
623                              regStatus = regStatus | NIMU_ICSS_MII_DUPLEXMODE_FULL;
624                              break;
625                          case PHY_CONFIG_100HD:
626                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_AUTO_NEGOTIATE_EN));
627                              regStatus = regStatus | NIMU_ICSS_MII_SPEEDSEL_100;
628                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_DUPLEXMODE_FULL));
629                              break;
630                          case PHY_CONFIG_10HD:
631                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_AUTO_NEGOTIATE_EN));
632                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_SPEEDSEL_100));
633                              regStatus = regStatus & (uint16_t)(~(NIMU_ICSS_MII_DUPLEXMODE_FULL));
634                              break;
635                          default:
636                              regStatus = regStatus | NIMU_ICSS_MII_AUTO_NEGOTIATE_EN;
637                              break;
638                     }
639                 CSL_MDIO_phyRegWrite(mdioBaseAdd, phyAddr, NIMU_ICSS_PHY_BMCR_REG, regStatus);
640                     }
641             }
642             else
643             {
644                 NIMU_ICSS_transport_log("SET_PORT_CONFIG:Invalid Arguments\n");
645                 ret_val = NIMU_ICSS_INVALID_PORT;
646             }
648             break;
649         }
650         case ICSS_IOCTL_GET_PORT_CONFIG:
651         {
652             NIMU_IcssPortCmd *lpPortCmd = &swConsCommand->PortCmd;
653             uint8_t i;
654             if(lpPortCmd->port == 0)        /*HOST Port*/
655             {
656                 port  = lpPortCmd->port;
657                 lpPortCmd->ml    = port;
658                 lpPortCmd->port  = ((uint8_t)1U);
659                 lpPortCmd->value = ((uint32_t)0U);
660                 lpPortCmd->EnDis = ((uint8_t)1U);
661                 lpPortCmd->phyMode = 0;
662                 for(i=0U;i<6U;i++)
663                 {
664                     lpPortCmd->add[i]= ((((ICSS_EmacObject*)(pi->nimuDrvHandle)->object)->emacInitcfg)->macId)[i];
665                 }
666             }
667             else if(lpPortCmd->port < ((uint8_t)3U))
668             {
669                 port  = lpPortCmd->port;
670                 if(macMode == ICSS_EMAC_MODE_SWITCH)
671                 {
672                     phyAddr = (((ICSS_EmacObject*)emachandle->object)->emacInitcfg)->phyAddr[port-1U];
673                 }
674                 else
675                 {
676                     phyAddr = (((ICSS_EmacObject*)emachandle->object)->emacInitcfg)->phyAddr[0U];
677                 }
679                 CSL_MDIO_phyRegRead(mdioBaseAdd, phyAddr, NIMU_ICSS_PHY_BMCR_REG, &regStatus);
681                 if(regStatus & NIMU_ICSS_MII_AUTO_NEGOTIATE_EN)
682                 {
683                     lpPortCmd->value =0;
684                 }
685                 switch(lpPortCmd->value)
686                 {
687                     case PHY_CONFIG_10FD:
688                     {
689                         lpPortCmd->EnDis =((uint8_t)1);
690                         lpPortCmd->value =10;
691                         break;
692                     }
693                     case PHY_CONFIG_10HD:
694                      {
695                         lpPortCmd->EnDis =((uint8_t)0U);
696                         lpPortCmd->value =((uint32_t)10U);
697                          break;
698                      }
699                     case PHY_CONFIG_100FD:
700                      {
701                         lpPortCmd->EnDis =((uint8_t)1U);
702                         lpPortCmd->value =((uint32_t)100U);
703                           break;
704                      }
705                      case PHY_CONFIG_100HD:
706                      {
707                         lpPortCmd->EnDis =((uint8_t)0U);
708                         lpPortCmd->value =((uint32_t)100U);
709                           break;
710                      }
711                      default:
712                      {
713                         break;
714                      }
715                 }
716                 port  = lpPortCmd->port;
717                 lpPortCmd->ml    = port - 1U;
718                 lpPortCmd->port  = CSL_MDIO_phyLinkStatus(mdioBaseAdd,phyAddr);
719             }
720             else
721             {
722                 NIMU_ICSS_transport_log("GET_PORT_CONFIG:Invalid Arguments\n");
723                  ret_val = NIMU_ICSS_INVALID_PORT;
724             }
726             break;
727         }
728         default:
729         {
730             break;
731         }
732     }/* end of switch construct */
734     swConsCommand->ret_type = ret_val;
736     return ret_val;
739 uint32_t NIMU_ICSS_sendPacket(Handle hEMAC, NIMU_IcssEmacPkt *pPkt)
741     uint32_t retVal = NIMU_ICSS_SUCCESS;
742     uint32_t          fragcnt,pktlen;
743     NIMU_IcssEmacPkt        *pPktLast;
744     uint32_t txPort;
745     ICSS_EmacHandle handle = (ICSS_EmacHandle)hEMAC;
746     int32_t ret;
747    ICSS_EmacTxArgument txArgs;
749     /* Count the number of frags in this packet */
750     fragcnt =1U;
751     pktlen  = pPkt->PktLength;
753     pPktLast = pPkt;
754     while ((((pPktLast->Flags & NIMU_ICSS_EMAC_PKT_FLAGS_EOP) != NIMU_ICSS_EMAC_PKT_FLAGS_EOP)) && (retVal == NIMU_ICSS_SUCCESS))
755     {
756         if (pPktLast->pNext == NULL)
757         {
758             retVal = NIMU_ICSS_INVALID_PARAM;
759         }
760         else
761         {
762             pktlen -= pPktLast->ValidLen;
763             pPktLast = pPktLast->pNext;
764             fragcnt++;
765             /* At this point we can't have another SOP */
766             if (pPktLast->Flags & NIMU_ICSS_EMAC_PKT_FLAGS_SOP)
767             {
768                 retVal = NIMU_ICSS_INVALID_PARAM;
769             }
770         }
771     }
772     if (retVal == NIMU_ICSS_SUCCESS)
773     {
774         /* Make sure PktLength and ValidLen agree */
775         if (pktlen != pPktLast->ValidLen)
776         {
777             retVal = NIMU_ICSS_ERR_BADPACKET;
778         }
779         else
780         {
781             /* The frag count must be correct */
782             if (fragcnt != pPkt->PktFrags)
783             {
784                 retVal = NIMU_ICSS_ERR_BADPACKET;
785             }
786             else
787             {
788                 /* Now pad for 60 byte min size. We only pad the last fragment */
789                 if (pPkt->PktLength < 60U)
790                 {
791                     pktlen = 60U - pPkt->PktLength;
792                     pPkt->PktLength = 60U;
793                     pPktLast->ValidLen += pktlen;
794                 }
795             
796             
797                 if(ICSS_EMAC_MODE_SWITCH == (((ICSS_EmacObject*)handle->object)->emacInitcfg)->portMask)
798                 { /*Switch Mode*/
799                     txPort = ICSS_EMAC_PORT_0;
800                 } 
801                 else if(ICSS_EMAC_MODE_MAC1 == (((ICSS_EmacObject*)handle->object)->emacInitcfg)->portMask)
802                 {
803                     txPort = ICSS_EMAC_PORT_1;
804                 } 
805                 else if(ICSS_EMAC_MODE_MAC2 == (((ICSS_EmacObject*)handle->object)->emacInitcfg)->portMask) 
806                 {
807                     txPort = ICSS_EMAC_PORT_2;
808                 }
809                 else
810                 {
811                     txPort = ICSS_EMAC_PORT_0;
812                 }
813                 txArgs.icssEmacHandle = handle;
814                 txArgs.lengthOfPacket = pPkt->PktLength;
815                 txArgs.portNumber = txPort;
816                 txArgs.queuePriority = ICSS_EMAC_QUEUE4;
817                 txArgs.srcAddress = (const uint8_t *)(pPkt->pDataBuffer + pPkt->DataOffset);
818             
819                 ret = ((((ICSS_EmacObject*)handle->object)->callBackHandle)->txCallBack)->callBack(&txArgs, ((((ICSS_EmacObject *)handle->object)->callBackHandle)->txCallBack)->userArg);
820                 if(ret != 0)
821                 {
822                     retVal = NIMU_ICSS_ERR_TX_OUT_OF_BD;
823                 }
824             }
825         }
826     }
827     return (retVal);
830 /**
831 * @internal
832 * @brief     This function should be called every time there is an EMAC device Rx
833 *             interrupt to process the packet
834 * @details  Note that the application has the responsibility for mapping the
835 *             physical device index to the correct EMAC_serviceCheck() function. If
836 *             more than one EMAC device is on the same interrupt, the function must be
837 *             called for each device.
839 * @param  hEMAC       handle to the opened EMAC device
841 * @retval     NIMU_ICSS_SUCCESS (0)
842 *                NIMU_ICSS_INTERNAL_FAILURE   - Packet provided by firmware has invalid length
843 * @pre     NIMU_ICSS_openPeripheral function must be called before calling this API.
845 */
846 uint32_t NIMU_ICSS_rxServiceCheck(ICSS_EmacHandle hEMAC,int32_t prioQueue)
848     uint32_t retVal = NIMU_ICSS_SUCCESS;
849     NIMU_IcssEmacPkt    *pPkt;
850     int32_t        packetLength;
851     ICSS_EmacRxArgument rxArgs;
852     uint32_t dataBufTemp;
854     NIMU_IcssDevice* lclDevice = (NIMU_IcssDevice*)(((ICSS_EmacObject*)hEMAC->object)->pvtInfo);
856     rxArgs.icssEmacHandle = hEMAC;
857     
858     rxArgs.queueNumber = prioQueue;
859     rxArgs.more = 1;
860     rxArgs.port = 0;
862     while ((retVal == NIMU_ICSS_SUCCESS) && (rxArgs.more == 1U))
863     {
864         pPkt = lclDevice->nimuPktRx;
865         if (pPkt != NULL)
866         {
867             dataBufTemp = ((uint32_t)pPkt->pDataBuffer);
868             rxArgs.destAddress =  dataBufTemp + pPkt->DataOffset;
869             packetLength =  ((((ICSS_EmacObject*)hEMAC->object)->callBackHandle)->rxCallBack)->callBack(&rxArgs, ((((ICSS_EmacObject *)hEMAC->object)->callBackHandle)->rxCallBack)->userArg);
871             if (packetLength > 0)
872             {
873                 /* Fill in the necessary packet header fields */
874                 pPkt->ValidLen = pPkt->PktLength = (uint32_t)(packetLength) & (0xFFFFU);
875                 pPkt->PktChannel = (uint32_t)rxArgs.port;
876                 pPkt->PktFrags = (1U);
877                 (lclDevice->pfcbRxPacket)(hEMAC,pPkt);
878             }
879             else
880             {
881                 retVal = NIMU_ICSS_INTERNAL_FAILURE;
882             }
883         }
884         else
885         {
886             retVal = NIMU_ICSS_INTERNAL_FAILURE;
887         }
889     }
891     return(retVal);