75c6f33ae693a00ab9dd948194ad53fc1d721322
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 );
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)
103 {
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 }
230 }
233 /**********************************************************************
234 ***************** Switch Configuration Functions *********************
235 **********************************************************************/
238 /**
239 * @internal
240 * @brief Configures Address lookup engine (ALE) of EMAC.
241 *
242 * @param hPort pointer to port object
243 *
244 * @retval none
245 *
246 */
247 static void NIMU_ICSS_setAleCfg(ICSS_EmacHandle handle); /* misra warning */
248 static void NIMU_ICSS_setAleCfg(ICSS_EmacHandle handle)
249 {
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 }
259 }
262 /**
263 * @internal
264 * @brief Configures Address lookup engine (ALE) of EMAC.
265 *
266 * @param hPort pointer to port object
267 *
268 * @retval none
269 *
270 */
271 static void NIMU_ICSS_setRateControlCfg(ICSS_EmacHandle handle); /* misra warning */
272 static void NIMU_ICSS_setRateControlCfg(ICSS_EmacHandle handle)
273 {
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 }
302 }
304 /**
305 * @internal
306 * @brief Configures Address lookup engine (ALE) of EMAC.
307 *
308 * @param hPort pointer to port object
309 *
310 * @retval none
311 *
312 */
313 static void NIMU_ICSS_setStatisticsCfg(ICSS_EmacHandle handle); /* misra warning */
314 static void NIMU_ICSS_setStatisticsCfg(ICSS_EmacHandle handle)
315 {
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 }
343 }
347 /**
348 * @internal
349 * @brief This function opens and sets up a MAC port for communication.
350 *
351 * @param hPort Handle to the Port object to setup
352 *
353 * @retval none
354 *
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)
358 {
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;
377 }
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)
382 {
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;
400 }
402 void NIMU_ICSS_openPeripheral(NIMU_IcssPdInfo *pi)
403 {
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);
433 }
435 uint32_t NIMU_ICSS_closePeripheral(NIMU_IcssPdInfo *pi)
436 {
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);
458 }
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
474 *
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
478 *
479 */
480 uint32_t NIMU_ICSS_getStatistics(NIMU_IcssPdInfo *pi, NIMU_IcssStatistics *pStatistics,uint8_t portNo)
481 {
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);
499 }
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
505 *
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
509 *
510 */
511 uint32_t NIMU_ICSS_clearStatistics(NIMU_IcssPdInfo *pi,uint8_t portNo)
512 {
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);
527 }
530 uint32_t NIMU_ICSS_setConfig(NIMU_IcssPdInfo *pi, void* pBuf, uint32_t size)
531 {
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, ®Status);
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;
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, ®Status);
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;
737 }
739 uint32_t NIMU_ICSS_sendPacket(Handle hEMAC, NIMU_IcssEmacPkt *pPkt)
740 {
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 }
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);
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);
828 }
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.
838 *
839 * @param hEMAC handle to the opened EMAC device
840 *
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.
844 *
845 */
846 uint32_t NIMU_ICSS_rxServiceCheck(ICSS_EmacHandle hEMAC,int32_t prioQueue)
847 {
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;
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);
892 }