1 /* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of Freescale Semiconductor nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 *
16 * ALTERNATIVELY, this software may be distributed under the terms of the
17 * GNU General Public License ("GPL") as published by the Free Software
18 * Foundation, either version 2 of that License or (at your option) any
19 * later version.
20 *
21 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 /******************************************************************************
34 @File dtsec.c
35
36 @Description FM dTSEC ...
37 *//***************************************************************************/
38
39 #include "std_ext.h"
40 #include "error_ext.h"
41 #include "string_ext.h"
42 #include "xx_ext.h"
43 #include "endian_ext.h"
44 #include "crc_mac_addr_ext.h"
45 #include "debug_ext.h"
46
47 #include "fm_common.h"
48 #include "dtsec.h"
49
50
51 /*****************************************************************************/
52 /* Internal routines */
53 /*****************************************************************************/
54
CheckInitParameters(t_Dtsec * p_Dtsec)55 static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
56 {
57 if(ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
58 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
59 if(p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
60 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
61 if(p_Dtsec->addr == 0)
62 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
63 if(((p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000) ||
64 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
65 (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)) &&
66 p_Dtsec->p_DtsecDriverParam->halfDuplex)
67 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
68 if(p_Dtsec->p_DtsecDriverParam->halfDuplex && (p_Dtsec->p_DtsecDriverParam)->loopback)
69 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
70 #ifdef FM_NO_RX_PREAM_ERRATA_DTSECx1
71 if(p_Dtsec->p_DtsecDriverParam->preambleRxEn)
72 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
73 #endif /* FM_NO_RX_PREAM_ERRATA_DTSECx1 */
74 if(((p_Dtsec->p_DtsecDriverParam)->preambleTxEn || (p_Dtsec->p_DtsecDriverParam)->preambleRxEn) &&( (p_Dtsec->p_DtsecDriverParam)->preambleLength != 0x7))
75 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
76 if((p_Dtsec->p_DtsecDriverParam)->fifoTxWatermarkH<((p_Dtsec->p_DtsecDriverParam)->fifoTxThr+8))
77 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("fifoTxWatermarkH has to be at least 8 larger than fifoTxThr"));
78 if((p_Dtsec->p_DtsecDriverParam)->halfDuplex &&
79 (p_Dtsec->p_DtsecDriverParam->txTimeStampEn || p_Dtsec->p_DtsecDriverParam->rxTimeStampEn))
80 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
81 if((p_Dtsec->p_DtsecDriverParam)->actOnRxPauseFrame && (p_Dtsec->p_DtsecDriverParam)->controlFrameAccept )
82 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
83 if((p_Dtsec->p_DtsecDriverParam)->packetAlignmentPadding > MAX_PACKET_ALIGNMENT)
84 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
85 if(((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg1 > MAX_INTER_PACKET_GAP) ||
86 ((p_Dtsec->p_DtsecDriverParam)->nonBackToBackIpg2 > MAX_INTER_PACKET_GAP) ||
87 ((p_Dtsec->p_DtsecDriverParam)->backToBackIpg > MAX_INTER_PACKET_GAP))
88 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
89 if((p_Dtsec->p_DtsecDriverParam)->alternateBackoffVal > MAX_INTER_PALTERNATE_BEB)
90 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
91 if((p_Dtsec->p_DtsecDriverParam)->maxRetransmission > MAX_RETRANSMISSION)
92 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
93 if((p_Dtsec->p_DtsecDriverParam)->collisionWindow > MAX_COLLISION_WINDOW)
94 RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
95
96 /* If Auto negotiation process is disabled, need to */
97 /* Set up the PHY using the MII Management Interface */
98 if (p_Dtsec->p_DtsecDriverParam->tbiPhyAddr > MAX_PHYS)
99 RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
100 if(!p_Dtsec->f_Exception)
101 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
102 if(!p_Dtsec->f_Event)
103 RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
104 return E_OK;
105 }
106
GetMiiDiv(int32_t refClk)107 static uint8_t GetMiiDiv(int32_t refClk)
108 {
109 uint32_t div,tmpClk;
110 int minRange;
111
112 div = 1;
113 minRange = (int)(refClk/40 - 1);
114
115 tmpClk = (uint32_t)ABS(refClk/60 - 1);
116 if (tmpClk < minRange)
117 {
118 div = 2;
119 minRange = (int)tmpClk;
120 }
121 tmpClk = (uint32_t)ABS(refClk/60 - 1);
122 if (tmpClk < minRange)
123 {
124 div = 3;
125 minRange = (int)tmpClk;
126 }
127 tmpClk = (uint32_t)ABS(refClk/80 - 1);
128 if (tmpClk < minRange)
129 {
130 div = 4;
131 minRange = (int)tmpClk;
132 }
133 tmpClk = (uint32_t)ABS(refClk/100 - 1);
134 if (tmpClk < minRange)
135 {
136 div = 5;
137 minRange = (int)tmpClk;
138 }
139 tmpClk = (uint32_t)ABS(refClk/140 - 1);
140 if (tmpClk < minRange)
141 {
142 div = 6;
143 minRange = (int)tmpClk;
144 }
145 tmpClk = (uint32_t)ABS(refClk/280 - 1);
146 if (tmpClk < minRange)
147 {
148 div = 7;
149 minRange = (int)tmpClk;
150 }
151
152 return (uint8_t)div;
153 }
154
155 /* ........................................................................... */
156
SetDefaultParam(t_DtsecDriverParam * p_DtsecDriverParam)157 static void SetDefaultParam(t_DtsecDriverParam *p_DtsecDriverParam)
158 {
159 p_DtsecDriverParam->errorDisabled = DEFAULT_errorDisabled;
160
161 p_DtsecDriverParam->promiscuousEnable = DEFAULT_promiscuousEnable;
162
163 p_DtsecDriverParam->pauseExtended = DEFAULT_pauseExtended;
164 p_DtsecDriverParam->pauseTime = DEFAULT_pauseTime;
165
166 p_DtsecDriverParam->halfDuplex = DEFAULT_halfDuplex;
167 p_DtsecDriverParam->halfDulexFlowControlEn = DEFAULT_halfDulexFlowControlEn;
168 p_DtsecDriverParam->txTimeStampEn = DEFAULT_txTimeStampEn;
169 p_DtsecDriverParam->rxTimeStampEn = DEFAULT_rxTimeStampEn;
170
171 p_DtsecDriverParam->packetAlignmentPadding = DEFAULT_packetAlignment;
172 p_DtsecDriverParam->controlFrameAccept = DEFAULT_controlFrameAccept;
173 p_DtsecDriverParam->groupHashExtend = DEFAULT_groupHashExtend;
174 p_DtsecDriverParam->broadcReject = DEFAULT_broadcReject;
175 p_DtsecDriverParam->rxShortFrame = DEFAULT_rxShortFrame;
176 p_DtsecDriverParam->exactMatch = DEFAULT_exactMatch;
177 p_DtsecDriverParam->debugMode = DEFAULT_debugMode;
178
179 p_DtsecDriverParam->loopback = DEFAULT_loopback;
180 p_DtsecDriverParam->tbiPhyAddr = DEFAULT_tbiPhyAddr;
181 p_DtsecDriverParam->actOnRxPauseFrame = DEFAULT_actOnRxPauseFrame;
182 p_DtsecDriverParam->actOnTxPauseFrame = DEFAULT_actOnTxPauseFrame;
183
184 p_DtsecDriverParam->preambleLength = DEFAULT_PreAmLength;
185 p_DtsecDriverParam->preambleRxEn = DEFAULT_PreAmRxEn;
186 p_DtsecDriverParam->preambleTxEn = DEFAULT_PreAmTxEn;
187 p_DtsecDriverParam->lengthCheckEnable = DEFAULT_lengthCheckEnable;
188 p_DtsecDriverParam->padAndCrcEnable = DEFAULT_padAndCrcEnable;
189 p_DtsecDriverParam->crcEnable = DEFAULT_crcEnable;
190
191 p_DtsecDriverParam->nonBackToBackIpg1 = DEFAULT_nonBackToBackIpg1;
192 p_DtsecDriverParam->nonBackToBackIpg2 = DEFAULT_nonBackToBackIpg2;
193 p_DtsecDriverParam->minIfgEnforcement = DEFAULT_minIfgEnforcement;
194 p_DtsecDriverParam->backToBackIpg = DEFAULT_backToBackIpg;
195
196 p_DtsecDriverParam->alternateBackoffVal = DEFAULT_altBackoffVal;
197 p_DtsecDriverParam->alternateBackoffEnable = DEFAULT_altBackoffEnable;
198 p_DtsecDriverParam->backPressureNoBackoff = DEFAULT_backPressureNoBackoff;
199 p_DtsecDriverParam->noBackoff = DEFAULT_noBackoff;
200 p_DtsecDriverParam->excessDefer = DEFAULT_excessDefer;
201 p_DtsecDriverParam->maxRetransmission = DEFAULT_maxRetransmission;
202 p_DtsecDriverParam->collisionWindow = DEFAULT_collisionWindow;
203
204 p_DtsecDriverParam->maxFrameLength = DEFAULT_maxFrameLength;
205
206 p_DtsecDriverParam->fifoTxThr = DEFAULT_fifoTxThr;
207 p_DtsecDriverParam->fifoTxWatermarkH = DEFAULT_fifoTxWatermarkH;
208
209 p_DtsecDriverParam->fifoRxWatermarkL = DEFAULT_fifoRxWatermarkL;
210 }
211
DtsecException(t_Handle h_Dtsec)212 static void DtsecException(t_Handle h_Dtsec)
213 {
214 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
215 uint32_t event;
216 t_DtsecMemMap *p_DtsecMemMap;
217
218 ASSERT_COND(p_Dtsec);
219 p_DtsecMemMap = p_Dtsec->p_MemMap;
220 ASSERT_COND(p_DtsecMemMap);
221
222 event = GET_UINT32(p_DtsecMemMap->ievent);
223 /* handle only MDIO events */
224 event &= (IMASK_MMRDEN | IMASK_MMWREN);
225 if(event)
226 {
227 event &= GET_UINT32(p_DtsecMemMap->imask);
228
229 WRITE_UINT32(p_DtsecMemMap->ievent, event);
230
231 if(event & IMASK_MMRDEN)
232 p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
233 if(event & IMASK_MMWREN)
234 p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
235 }
236 }
237
UpdateStatistics(t_Dtsec * p_Dtsec)238 static void UpdateStatistics(t_Dtsec *p_Dtsec)
239 {
240 t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap;
241 uint32_t car1 = GET_UINT32(p_DtsecMemMap->car1);
242 uint32_t car2 = GET_UINT32(p_DtsecMemMap->car2);
243
244 if(car1)
245 {
246 WRITE_UINT32(p_DtsecMemMap->car1, car1);
247 if(car1 & CAR1_TR64)
248 p_Dtsec->internalStatistics.tr64 += VAL22BIT;
249 if(car1 & CAR1_TR127)
250 p_Dtsec->internalStatistics.tr127 += VAL22BIT;
251 if(car1 & CAR1_TR255)
252 p_Dtsec->internalStatistics.tr255 += VAL22BIT;
253 if(car1 & CAR1_TR511)
254 p_Dtsec->internalStatistics.tr511 += VAL22BIT;
255 if(car1 & CAR1_TRK1)
256 p_Dtsec->internalStatistics.tr1k += VAL22BIT;
257 if(car1 & CAR1_TRMAX)
258 p_Dtsec->internalStatistics.trmax += VAL22BIT;
259 if(car1 & CAR1_TRMGV)
260 p_Dtsec->internalStatistics.trmgv += VAL22BIT;
261 if(car1 & CAR1_RBYT)
262 p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
263 if(car1 & CAR1_RPKT)
264 p_Dtsec->internalStatistics.rpkt += VAL22BIT;
265 if(car1 & CAR1_RMCA)
266 p_Dtsec->internalStatistics.rmca += VAL22BIT;
267 if(car1 & CAR1_RBCA)
268 p_Dtsec->internalStatistics.rbca += VAL22BIT;
269 if(car1 & CAR1_RXPF)
270 p_Dtsec->internalStatistics.rxpf += VAL16BIT;
271 if(car1 & CAR1_RALN)
272 p_Dtsec->internalStatistics.raln += VAL16BIT;
273 if(car1 & CAR1_RFLR)
274 p_Dtsec->internalStatistics.rflr += VAL16BIT;
275 if(car1 & CAR1_RCDE)
276 p_Dtsec->internalStatistics.rcde += VAL16BIT;
277 if(car1 & CAR1_RCSE)
278 p_Dtsec->internalStatistics.rcse += VAL16BIT;
279 if(car1 & CAR1_RUND)
280 p_Dtsec->internalStatistics.rund += VAL16BIT;
281 if(car1 & CAR1_ROVR)
282 p_Dtsec->internalStatistics.rovr += VAL16BIT;
283 if(car1 & CAR1_RFRG)
284 p_Dtsec->internalStatistics.rfrg += VAL16BIT;
285 if(car1 & CAR1_RJBR)
286 p_Dtsec->internalStatistics.rjbr += VAL16BIT;
287 if(car1 & CAR1_RDRP)
288 p_Dtsec->internalStatistics.rdrp += VAL16BIT;
289 }
290 if(car2)
291 {
292 WRITE_UINT32(p_DtsecMemMap->car2, car2);
293 if(car2 & CAR2_TFCS)
294 p_Dtsec->internalStatistics.tfcs += VAL12BIT;
295 if(car2 & CAR2_TBYT)
296 p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
297 if(car2 & CAR2_TPKT)
298 p_Dtsec->internalStatistics.tpkt += VAL22BIT;
299 if(car2 & CAR2_TMCA)
300 p_Dtsec->internalStatistics.tmca += VAL22BIT;
301 if(car2 & CAR2_TBCA)
302 p_Dtsec->internalStatistics.tbca += VAL22BIT;
303 if(car2 & CAR2_TXPF)
304 p_Dtsec->internalStatistics.txpf += VAL16BIT;
305 if(car2 & CAR2_TDRP)
306 p_Dtsec->internalStatistics.tdrp += VAL16BIT;
307 }
308 }
309
310 /* .............................................................................. */
311
DtsecGetMaxFrameLength(t_Handle h_Dtsec)312 static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
313 {
314 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
315
316 SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
317
318 return (uint16_t)GET_UINT32(p_Dtsec->p_MemMap->maxfrm);
319 }
320
DtsecErrException(t_Handle h_Dtsec)321 static void DtsecErrException(t_Handle h_Dtsec)
322 {
323 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
324 uint32_t event;
325 t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap;
326
327 event = GET_UINT32(p_DtsecMemMap->ievent);
328 /* do not handle MDIO events */
329 event &= ~(IMASK_MMRDEN | IMASK_MMWREN);
330
331 event &= GET_UINT32(p_DtsecMemMap->imask);
332
333 WRITE_UINT32(p_DtsecMemMap->ievent, event);
334
335 if(event & IMASK_BREN)
336 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
337 if(event & IMASK_RXCEN)
338 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
339 if(event & IMASK_MSROEN)
340 UpdateStatistics(p_Dtsec);
341 if(event & IMASK_GTSCEN)
342 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
343 if(event & IMASK_BTEN)
344 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
345 if(event & IMASK_TXCEN)
346 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
347 if(event & IMASK_TXEEN)
348 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
349 if(event & IMASK_LCEN)
350 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
351 if(event & IMASK_CRLEN)
352 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
353 if(event & IMASK_XFUNEN)
354 {
355 #ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
356 uint32_t tpkt1, tmpReg1, tpkt2, tmpReg2, i;
357 /* a. Write 0x00E0_0C00 to DTSEC_ID */
358 /* This is a read only regidter */
359
360 /* b. Read and save the value of TPKT */
361 tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
362
363 /* c. Read the register at dTSEC address offset 0x32C */
364 tmpReg1 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
365
366 /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
367 if((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
368 {
369 /* If they are not equal, save the value of this register and wait for at least
370 * MAXFRM*16 ns */
371 XX_UDelay((uint32_t)(NCSW_MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
372 }
373
374 /* e. Read and save TPKT again and read the register at dTSEC address offset
375 0x32C again*/
376 tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
377 tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
378
379 /* f. Compare the value of TPKT saved in step b to value read in step e. Also
380 compare bits [9:15] of the register at offset 0x32C saved in step d to the value
381 of bits [9:15] saved in step e. If the two registers values are unchanged, then
382 the transmit portion of the dTSEC controller is locked up and the user should
383 proceed to the recover sequence. */
384 if((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
385 {
386 /* recover sequence */
387
388 /* a.Write a 1 to RCTRL[GRS]*/
389
390 WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
391
392 /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
393 for(i = 0 ; i < 100 ; i++ )
394 {
395 if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN)
396 break;
397 XX_UDelay(1);
398 }
399 if(GET_UINT32(p_DtsecMemMap->ievent) & IMASK_GRSCEN)
400 WRITE_UINT32(p_DtsecMemMap->ievent, IMASK_GRSCEN);
401 else
402 DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
403
404
405 /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
406 FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
407
408 /* d.Wait 4 Tx clocks (32 ns) */
409 XX_UDelay(1);
410
411 /* e.Write a 0 to bit n of FM_RSTC. */
412 /* cleared by FMAN */
413 }
414 else
415 {
416 /* If either value has changed, the dTSEC controller is not locked up and the
417 controller should be allowed to proceed normally by writing the reset value
418 of 0x0824_0101 to DTSEC_ID. */
419 /* Register is read only */
420 }
421 #endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
422
423 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
424 }
425 if(event & IMASK_MAGEN)
426 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
427 if(event & IMASK_GRSCEN)
428 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
429 if(event & IMASK_TDPEEN)
430 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
431 if(event & IMASK_RDPEEN)
432 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
433
434 /* - masked interrupts */
435 ASSERT_COND(!(event & IMASK_ABRTEN));
436 ASSERT_COND(!(event & IMASK_IFERREN));
437 }
438
Dtsec1588Exception(t_Handle h_Dtsec)439 static void Dtsec1588Exception(t_Handle h_Dtsec)
440 {
441 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
442 uint32_t event;
443 t_DtsecMemMap *p_DtsecMemMap = p_Dtsec->p_MemMap;
444
445 if (p_Dtsec->ptpTsuEnabled)
446 {
447 event = GET_UINT32(p_DtsecMemMap->tmr_pevent);
448 event &= GET_UINT32(p_DtsecMemMap->tmr_pemask);
449 if(event)
450 {
451 WRITE_UINT32(p_DtsecMemMap->tmr_pevent, event);
452 ASSERT_COND(event & PEMASK_TSRE);
453 p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
454 }
455 }
456 }
457
458 /* ........................................................................... */
459
FreeInitResources(t_Dtsec * p_Dtsec)460 static void FreeInitResources(t_Dtsec *p_Dtsec)
461 {
462 /*TODO - need to ask why with mdioIrq != 0*/
463 if ((p_Dtsec->mdioIrq != 0) && (p_Dtsec->mdioIrq != NO_IRQ))
464 {
465 XX_DisableIntr(p_Dtsec->mdioIrq);
466 XX_FreeIntr(p_Dtsec->mdioIrq);
467 }
468 else if (p_Dtsec->mdioIrq == 0)
469 FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
470 FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
471 FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
472
473 /* release the driver's group hash table */
474 FreeHashTable(p_Dtsec->p_MulticastAddrHash);
475 p_Dtsec->p_MulticastAddrHash = NULL;
476
477 /* release the driver's individual hash table */
478 FreeHashTable(p_Dtsec->p_UnicastAddrHash);
479 p_Dtsec->p_UnicastAddrHash = NULL;
480 }
481
482 /* ........................................................................... */
483
HardwareClearAddrInPaddr(t_Dtsec * p_Dtsec,uint8_t paddrNum)484 static void HardwareClearAddrInPaddr(t_Dtsec *p_Dtsec, uint8_t paddrNum)
485 {
486 WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match1, 0x0);
487 WRITE_UINT32(((t_DtsecMemMap*)p_Dtsec->p_MemMap)->macaddr[paddrNum].exact_match2, 0x0);
488 }
489
490 /* ........................................................................... */
491
HardwareAddAddrInPaddr(t_Dtsec * p_Dtsec,uint64_t * p_Addr,uint8_t paddrNum)492 static void HardwareAddAddrInPaddr(t_Dtsec *p_Dtsec, uint64_t *p_Addr, uint8_t paddrNum)
493 {
494 uint32_t tmpReg32 = 0;
495 uint64_t addr = *p_Addr;
496 t_DtsecMemMap *p_DtsecMemMap = (t_DtsecMemMap*)p_Dtsec->p_MemMap;
497
498 tmpReg32 = (uint32_t)(addr);
499 SwapUint32P(&tmpReg32);
500 WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match1, tmpReg32);
501
502 tmpReg32 = (uint32_t)(addr>>32);
503 SwapUint32P(&tmpReg32);
504 WRITE_UINT32(p_DtsecMemMap->macaddr[paddrNum].exact_match2, tmpReg32);
505 }
506
507 /* ........................................................................... */
508
GracefulStop(t_Dtsec * p_Dtsec,e_CommMode mode)509 static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
510 {
511 t_DtsecMemMap *p_MemMap;
512
513 ASSERT_COND(p_Dtsec);
514
515 p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
516 ASSERT_COND(p_MemMap);
517
518 /* Assert the graceful transmit stop bit */
519 if (mode & e_COMM_MODE_RX)
520 WRITE_UINT32(p_MemMap->rctrl,
521 GET_UINT32(p_MemMap->rctrl) | RCTRL_GRS);
522
523 #ifdef FM_GRS_ERRATA_DTSEC_A002
524 XX_UDelay(100);
525 #endif /* FM_GRS_ERRATA_DTSEC_A002 */
526
527 #ifdef FM_GTS_ERRATA_DTSEC_A004
528 DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
529 #else /* not FM_GTS_ERRATA_DTSEC_A004 */
530 if (mode & e_COMM_MODE_TX)
531 WRITE_UINT32(p_MemMap->tctrl,
532 GET_UINT32(p_MemMap->tctrl) | TCTRL_GTS);
533 #endif /* not FM_GTS_ERRATA_DTSEC_A004 */
534
535 return E_OK;
536 }
537
538 /* .............................................................................. */
539
GracefulRestart(t_Dtsec * p_Dtsec,e_CommMode mode)540 static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
541 {
542 t_DtsecMemMap *p_MemMap;
543
544 ASSERT_COND(p_Dtsec);
545
546 p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
547 ASSERT_COND(p_MemMap);
548
549 /* clear the graceful receive stop bit */
550 if(mode & e_COMM_MODE_TX)
551 WRITE_UINT32(p_MemMap->tctrl,
552 GET_UINT32(p_MemMap->tctrl) & ~TCTRL_GTS);
553
554 if(mode & e_COMM_MODE_RX)
555 WRITE_UINT32(p_MemMap->rctrl,
556 GET_UINT32(p_MemMap->rctrl) & ~RCTRL_GRS);
557
558 return E_OK;
559 }
560
561
562 /*****************************************************************************/
563 /* dTSEC Configs modification functions */
564 /*****************************************************************************/
565
566
567 /* .............................................................................. */
568
DtsecConfigLoopback(t_Handle h_Dtsec,bool newVal)569 static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
570 {
571
572 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
573
574 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
575 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
576
577 p_Dtsec->p_DtsecDriverParam->loopback = newVal;
578
579 return E_OK;
580 }
581
582 /* .............................................................................. */
583
DtsecConfigMaxFrameLength(t_Handle h_Dtsec,uint16_t newVal)584 static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
585 {
586 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
587
588 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
589 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
590
591 p_Dtsec->p_DtsecDriverParam->maxFrameLength = newVal;
592
593 return E_OK;
594 }
595
596 /* .............................................................................. */
597
DtsecConfigPadAndCrc(t_Handle h_Dtsec,bool newVal)598 static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
599 {
600 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
601
602 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
603 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
604
605 p_Dtsec->p_DtsecDriverParam->padAndCrcEnable = newVal;
606
607 return E_OK;
608 }
609
610 /* .............................................................................. */
611
DtsecConfigHalfDuplex(t_Handle h_Dtsec,bool newVal)612 static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
613 {
614 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
615
616 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
617 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
618
619 p_Dtsec->p_DtsecDriverParam->halfDuplex = newVal;
620
621 return E_OK;
622 }
623
624 /* .............................................................................. */
625
DtsecConfigLengthCheck(t_Handle h_Dtsec,bool newVal)626 static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
627 {
628 #ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
629 UNUSED(h_Dtsec);
630 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
631
632 #else
633 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
634
635 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
636 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
637
638 p_Dtsec->p_DtsecDriverParam->lengthCheckEnable = newVal;
639
640 return E_OK;
641 #endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
642 }
643
DtsecConfigException(t_Handle h_Dtsec,e_FmMacExceptions exception,bool enable)644 static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
645 {
646 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
647 uint32_t bitMask = 0;
648
649 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
650 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
651
652 if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
653 {
654 GET_EXCEPTION_FLAG(bitMask, exception);
655 if(bitMask)
656 {
657 if (enable)
658 p_Dtsec->exceptions |= bitMask;
659 else
660 p_Dtsec->exceptions &= ~bitMask;
661 }
662 else
663 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
664 }
665 else
666 {
667 if(!p_Dtsec->ptpTsuEnabled)
668 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
669 switch(exception){
670 case(e_FM_MAC_EX_1G_1588_TS_RX_ERR):
671 if(enable)
672 p_Dtsec->enTsuErrExeption = TRUE;
673 else
674 p_Dtsec->enTsuErrExeption = FALSE;
675 break;
676 default:
677 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
678 }
679 }
680 return E_OK;
681 }
682 /*****************************************************************************/
683 /* dTSEC Run Time API functions */
684 /*****************************************************************************/
685
686 /* .............................................................................. */
687
DtsecEnable(t_Handle h_Dtsec,e_CommMode mode)688 static t_Error DtsecEnable(t_Handle h_Dtsec, e_CommMode mode)
689 {
690 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
691 t_DtsecMemMap *p_MemMap ;
692 uint32_t tmpReg32 = 0;
693
694 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
695 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE);
696
697 p_MemMap= (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
698
699 tmpReg32 = GET_UINT32(p_MemMap->maccfg1);
700 if (mode & e_COMM_MODE_RX)
701 tmpReg32 |= MACCFG1_RX_EN;
702 if (mode & e_COMM_MODE_TX)
703 tmpReg32 |= MACCFG1_TX_EN;
704 WRITE_UINT32(p_MemMap->maccfg1, tmpReg32);
705
706 GracefulRestart(p_Dtsec, mode);
707
708 return E_OK;
709 }
710
711 /* .............................................................................. */
712
DtsecDisable(t_Handle h_Dtsec,e_CommMode mode)713 static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
714 {
715 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
716 t_DtsecMemMap *p_MemMap ;
717 uint32_t tmpReg32 = 0;
718
719 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
720 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_HANDLE);
721
722 p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
723
724 GracefulStop(p_Dtsec, mode);
725
726 tmpReg32 = GET_UINT32(p_MemMap->maccfg1);
727 if (mode & e_COMM_MODE_RX)
728 tmpReg32 &= ~MACCFG1_RX_EN;
729 if (mode & e_COMM_MODE_TX)
730 tmpReg32 &= ~MACCFG1_TX_EN;
731 WRITE_UINT32(p_MemMap->maccfg1, tmpReg32);
732
733 return E_OK;
734 }
735
736 /* .............................................................................. */
737
DtsecTxMacPause(t_Handle h_Dtsec,uint16_t pauseTime)738 static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
739 {
740 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
741 uint32_t ptv = 0;
742 t_DtsecMemMap *p_MemMap;
743
744 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
745 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
746 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE);
747
748 p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
749
750 if (pauseTime)
751 {
752 #ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
753 {
754 if (pauseTime <= 320)
755 RETURN_ERROR(MINOR, E_INVALID_VALUE,
756 ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
757 " value should be greater than 320."));
758 }
759 #endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
760
761 #ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
762 {
763 t_FmRevisionInfo revInfo;
764 FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo);
765 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
766 pauseTime += 2;
767 }
768 #endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
769
770 ptv = GET_UINT32(p_MemMap->ptv);
771 ptv |= pauseTime;
772 WRITE_UINT32(p_MemMap->ptv, ptv);
773
774 /* trigger the transmission of a flow-control pause frame */
775 WRITE_UINT32(p_MemMap->maccfg1,
776 GET_UINT32(p_MemMap->maccfg1) | MACCFG1_TX_FLOW);
777 }
778 else
779 {
780 WRITE_UINT32(p_MemMap->maccfg1,
781 GET_UINT32(p_MemMap->maccfg1) & ~MACCFG1_TX_FLOW);
782 }
783
784 return E_OK;
785 }
786
787 /* .............................................................................. */
788
DtsecRxIgnoreMacPause(t_Handle h_Dtsec,bool en)789 static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
790 {
791 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
792 t_DtsecMemMap *p_MemMap;
793 uint32_t tmpReg32;
794
795 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
796 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
797 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE);
798
799 p_MemMap = (t_DtsecMemMap*)(p_Dtsec->p_MemMap);
800
801 tmpReg32 = GET_UINT32(p_MemMap->maccfg1);
802 if (en)
803 tmpReg32 &= ~MACCFG1_RX_FLOW;
804 else
805 tmpReg32 |= MACCFG1_RX_FLOW;
806 WRITE_UINT32(p_MemMap->maccfg1, tmpReg32);
807
808 return E_OK;
809 }
810
811
812 /* .............................................................................. */
813
DtsecEnable1588TimeStamp(t_Handle h_Dtsec)814 static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
815 {
816 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
817
818 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
819 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
820 #ifdef FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3
821 if((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
822 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("1588TimeStamp in 10/100 SGMII"));
823 #endif /* FM_10_100_SGMII_NO_TS_ERRATA_DTSEC3 */
824 p_Dtsec->ptpTsuEnabled = TRUE;
825 WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) | RCTRL_RTSE);
826 WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) | TCTRL_TTSE);
827
828 return E_OK;
829 }
830
DtsecDisable1588TimeStamp(t_Handle h_Dtsec)831 static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
832 {
833 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
834
835 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
836 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
837
838 p_Dtsec->ptpTsuEnabled = FALSE;
839 WRITE_UINT32(p_Dtsec->p_MemMap->rctrl, GET_UINT32(p_Dtsec->p_MemMap->rctrl) & ~RCTRL_RTSE);
840 WRITE_UINT32(p_Dtsec->p_MemMap->tctrl, GET_UINT32(p_Dtsec->p_MemMap->tctrl) & ~TCTRL_TTSE);
841
842 return E_OK;
843 }
844
845 /* .............................................................................. */
846
DtsecGetStatistics(t_Handle h_Dtsec,t_FmMacStatistics * p_Statistics)847 static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
848 {
849 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
850 t_DtsecMemMap *p_DtsecMemMap;
851
852 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
853 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
854 SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
855
856 if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
857 RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
858
859 p_DtsecMemMap = p_Dtsec->p_MemMap;
860 memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
861
862 if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
863 {
864 p_Statistics->eStatPkts64 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr64))
865 + p_Dtsec->internalStatistics.tr64; /**< r-10G tr-DT 64 byte frame counter */
866 p_Statistics->eStatPkts65to127 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr127))
867 + p_Dtsec->internalStatistics.tr127; /**< r-10G 65 to 127 byte frame counter */
868 p_Statistics->eStatPkts128to255 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr255))
869 + p_Dtsec->internalStatistics.tr255; /**< r-10G 128 to 255 byte frame counter */
870 p_Statistics->eStatPkts256to511 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr511))
871 + p_Dtsec->internalStatistics.tr511; /**< r-10G 256 to 511 byte frame counter */
872 p_Statistics->eStatPkts512to1023 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tr1k))
873 + p_Dtsec->internalStatistics.tr1k; /**< r-10G 512 to 1023 byte frame counter */
874 p_Statistics->eStatPkts1024to1518 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmax))
875 + p_Dtsec->internalStatistics.trmax; /**< r-10G 1024 to 1518 byte frame counter */
876 p_Statistics->eStatPkts1519to1522 = (MASK22BIT & GET_UINT32(p_DtsecMemMap->trmgv))
877 + p_Dtsec->internalStatistics.trmgv; /**< r-10G 1519 to 1522 byte good frame count */
878 /* MIB II */
879 p_Statistics->ifInOctets = GET_UINT32(p_DtsecMemMap->rbyt)
880 + p_Dtsec->internalStatistics.rbyt; /**< Total number of byte received. */
881 p_Statistics->ifInPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rpkt))
882 + p_Dtsec->internalStatistics.rpkt; /**< Total number of packets received.*/
883 p_Statistics->ifInMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rmca))
884 + p_Dtsec->internalStatistics.rmca; /**< Total number of multicast frame received*/
885 p_Statistics->ifInBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->rbca))
886 + p_Dtsec->internalStatistics.rbca; /**< Total number of broadcast frame received */
887 p_Statistics->ifOutOctets = GET_UINT32(p_DtsecMemMap->tbyt)
888 + p_Dtsec->internalStatistics.tbyt; /**< Total number of byte sent. */
889 p_Statistics->ifOutPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tpkt))
890 + p_Dtsec->internalStatistics.tpkt; /**< Total number of packets sent .*/
891 p_Statistics->ifOutMcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tmca))
892 + p_Dtsec->internalStatistics.tmca; /**< Total number of multicast frame sent */
893 p_Statistics->ifOutBcastPkts = (MASK22BIT & GET_UINT32(p_DtsecMemMap->tbca))
894 + p_Dtsec->internalStatistics.tbca; /**< Total number of multicast frame sent */
895 }
896 /* */
897 p_Statistics->eStatFragments = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rfrg))
898 + p_Dtsec->internalStatistics.rfrg; /**< Total number of packets that were less than 64 octets long with a wrong CRC.*/
899 p_Statistics->eStatJabbers = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rjbr))
900 + p_Dtsec->internalStatistics.rjbr; /**< Total number of packets longer than valid maximum length octets */
901
902 p_Statistics->eStatsDropEvents = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rdrp))
903 + p_Dtsec->internalStatistics.rdrp; /**< number of dropped packets due to internal errors of the MAC Client. */
904 p_Statistics->eStatCRCAlignErrors = (MASK16BIT & GET_UINT32(p_DtsecMemMap->raln))
905 + p_Dtsec->internalStatistics.raln; /**< Incremented when frames of correct length but with CRC error are received.*/
906
907 p_Statistics->eStatUndersizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rund))
908 + p_Dtsec->internalStatistics.rund; /**< Total number of packets that were less than 64 octets long with a good CRC.*/
909 p_Statistics->eStatOversizePkts = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rovr))
910 + p_Dtsec->internalStatistics.rovr; /**< T,B.D*/
911 /* Pause */
912 p_Statistics->reStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->rxpf))
913 + p_Dtsec->internalStatistics.rxpf; /**< Pause MAC Control received */
914 p_Statistics->teStatPause = (MASK16BIT & GET_UINT32(p_DtsecMemMap->txpf))
915 + p_Dtsec->internalStatistics.txpf; /**< Pause MAC Control sent */
916
917 p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents; /**< Frames received, but discarded due to problems within the MAC RX. */
918
919 p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents
920 + p_Statistics->eStatCRCAlignErrors
921 + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rflr))
922 + p_Dtsec->internalStatistics.rflr
923 + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcde))
924 + p_Dtsec->internalStatistics.rcde
925 + (MASK16BIT & GET_UINT32(p_DtsecMemMap->rcse))
926 + p_Dtsec->internalStatistics.rcse;
927
928 p_Statistics->ifOutDiscards = (MASK16BIT & GET_UINT32(p_DtsecMemMap->tdrp))
929 + p_Dtsec->internalStatistics.tdrp; /**< Frames received, but discarded due to problems within the MAC TX N/A!.*/
930 p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards /**< Number of frames transmitted with error: */
931 + (MASK12BIT & GET_UINT32(p_DtsecMemMap->tfcs))
932 + p_Dtsec->internalStatistics.tfcs;
933
934 return E_OK;
935 }
936
937 /* .............................................................................. */
938
DtsecModifyMacAddress(t_Handle h_Dtsec,t_EnetAddr * p_EnetAddr)939 static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
940 {
941 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
942 t_DtsecMemMap *p_DtsecMemMap;
943 uint32_t tmpReg32 = 0;
944 uint64_t addr;
945
946 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
947 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
948
949 p_DtsecMemMap = p_Dtsec->p_MemMap;
950 /* Initialize MAC Station Address registers (1 & 2) */
951 /* Station address have to be swapped (big endian to little endian */
952 addr = ((*(uint64_t *)p_EnetAddr) >> 16);
953 p_Dtsec->addr = addr;
954
955 tmpReg32 = (uint32_t)(addr);
956 SwapUint32P(&tmpReg32);
957 WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32);
958
959 tmpReg32 = (uint32_t)(addr>>32);
960 SwapUint32P(&tmpReg32);
961 WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32);
962
963 return E_OK;
964 }
965
966 /* .............................................................................. */
967
DtsecResetCounters(t_Handle h_Dtsec)968 static t_Error DtsecResetCounters (t_Handle h_Dtsec)
969 {
970 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
971
972 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
973
974 /* clear HW counters */
975 WRITE_UINT32(p_Dtsec->p_MemMap->ecntrl, GET_UINT32(p_Dtsec->p_MemMap->ecntrl) | ECNTRL_CLRCNT);
976
977 /* clear SW counters holding carries */
978 memset((char *)&p_Dtsec->internalStatistics, (char)0x0, sizeof(t_InternalStatistics));
979
980 return E_OK;
981 }
982
983 /* .............................................................................. */
984
DtsecAddExactMatchMacAddress(t_Handle h_Dtsec,t_EnetAddr * p_EthAddr)985 static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
986 {
987 t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
988 uint64_t ethAddr;
989 uint8_t paddrNum;
990
991 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
992
993 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
994
995 if (ethAddr & GROUP_ADDRESS)
996 /* Multicast address has no effect in PADDR */
997 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
998
999 /* Make sure no PADDR contains this address */
1000 for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
1001 if (p_Dtsec->indAddrRegUsed[paddrNum])
1002 if (p_Dtsec->paddr[paddrNum] == ethAddr)
1003 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
1004
1005 /* Find first unused PADDR */
1006 for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
1007 if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
1008 {
1009 /* mark this PADDR as used */
1010 p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
1011 /* store address */
1012 p_Dtsec->paddr[paddrNum] = ethAddr;
1013
1014 /* put in hardware */
1015 HardwareAddAddrInPaddr(p_Dtsec, ðAddr, paddrNum);
1016 p_Dtsec->numOfIndAddrInRegs++;
1017
1018 return E_OK;
1019 }
1020
1021 /* No free PADDR */
1022 RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
1023 }
1024
1025 /* .............................................................................. */
1026
DtsecDelExactMatchMacAddress(t_Handle h_Dtsec,t_EnetAddr * p_EthAddr)1027 static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
1028 {
1029 t_Dtsec *p_Dtsec = (t_Dtsec *) h_Dtsec;
1030 uint64_t ethAddr;
1031 uint8_t paddrNum;
1032
1033 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1034
1035 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
1036
1037 /* Find used PADDR containing this address */
1038 for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
1039 {
1040 if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
1041 (p_Dtsec->paddr[paddrNum] == ethAddr))
1042 {
1043 /* mark this PADDR as not used */
1044 p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
1045 /* clear in hardware */
1046 HardwareClearAddrInPaddr(p_Dtsec, paddrNum);
1047 p_Dtsec->numOfIndAddrInRegs--;
1048
1049 return E_OK;
1050 }
1051 }
1052
1053 RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
1054 }
1055
1056 /* .............................................................................. */
1057
DtsecAddHashMacAddress(t_Handle h_Dtsec,t_EnetAddr * p_EthAddr)1058 static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
1059 {
1060 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1061 t_DtsecMemMap *p_DtsecMemMap;
1062 uint32_t crc;
1063 uint8_t crcMirror, reg;
1064 uint32_t bitMask;
1065 t_EthHashEntry *p_HashEntry;
1066 uint64_t ethAddr;
1067
1068 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1069 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
1070
1071 p_DtsecMemMap = p_Dtsec->p_MemMap;
1072
1073 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
1074
1075 /* CRC calculation */
1076 GET_MAC_ADDR_CRC(ethAddr, crc);
1077
1078 /* calculate the "crc mirror" */
1079 crcMirror = MIRROR((uint8_t)crc);
1080
1081 /* 3 MSB bits define the register */
1082 reg = (uint8_t)(crcMirror >> 5);
1083 /* 5 LSB bits define the bit within the register */
1084 bitMask = 0x80000000 >> (crcMirror & 0x1f);
1085
1086 /* Create element to be added to the driver hash table */
1087 p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
1088 p_HashEntry->addr = ethAddr;
1089 INIT_LIST(&p_HashEntry->node);
1090
1091 if (ethAddr & GROUP_ADDRESS)
1092 {
1093 /* Group Address */
1094 LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror]));
1095 /* Set the appropriate bit in GADDR0-7 */
1096 WRITE_UINT32(p_DtsecMemMap->gaddr[reg],
1097 GET_UINT32(p_DtsecMemMap->gaddr[reg]) | bitMask);
1098 }
1099 else
1100 {
1101 LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror]));
1102 /* Set the appropriate bit in IADDR0-7 */
1103 WRITE_UINT32(p_DtsecMemMap->igaddr[reg],
1104 GET_UINT32(p_DtsecMemMap->igaddr[reg]) | bitMask);
1105 }
1106
1107 return E_OK;
1108 }
1109
1110 /* .............................................................................. */
1111
DtsecDelHashMacAddress(t_Handle h_Dtsec,t_EnetAddr * p_EthAddr)1112 static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
1113 {
1114 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1115 t_DtsecMemMap *p_DtsecMemMap;
1116 t_List *p_Pos;
1117 uint32_t crc;
1118 uint8_t crcMirror, reg;
1119 uint32_t bitMask;
1120 t_EthHashEntry *p_HashEntry = NULL;
1121 uint64_t ethAddr;
1122
1123 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1124 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
1125
1126 p_DtsecMemMap = p_Dtsec->p_MemMap;
1127
1128 ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
1129
1130 /* CRC calculation */
1131 GET_MAC_ADDR_CRC(ethAddr, crc);
1132
1133 /* calculate the "crc mirror" */
1134 crcMirror = MIRROR((uint8_t)crc);
1135
1136 /* 3 MSB bits define the register */
1137 reg =(uint8_t)( crcMirror >> 5);
1138 /* 5 LSB bits define the bit within the register */
1139 bitMask = 0x80000000 >> (crcMirror & 0x1f);
1140
1141 if (ethAddr & GROUP_ADDRESS)
1142 {
1143 /* Group Address */
1144 LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror]))
1145 {
1146 p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
1147 if(p_HashEntry->addr == ethAddr)
1148 {
1149 LIST_DelAndInit(&p_HashEntry->node);
1150 XX_Free(p_HashEntry);
1151 break;
1152 }
1153 }
1154 if(LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[crcMirror]))
1155 WRITE_UINT32(p_DtsecMemMap->gaddr[reg],
1156 GET_UINT32(p_DtsecMemMap->gaddr[reg]) & ~bitMask);
1157 }
1158 else
1159 {
1160 /* Individual Address */
1161 LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror]))
1162 {
1163 p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
1164 if(p_HashEntry->addr == ethAddr)
1165 {
1166 LIST_DelAndInit(&p_HashEntry->node);
1167 XX_Free(p_HashEntry);
1168 break;
1169 }
1170 }
1171 if(LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[crcMirror]))
1172 WRITE_UINT32(p_DtsecMemMap->igaddr[reg],
1173 GET_UINT32(p_DtsecMemMap->igaddr[reg]) & ~bitMask);
1174 }
1175
1176 /* address does not exist */
1177 ASSERT_COND(p_HashEntry != NULL);
1178
1179 return E_OK;
1180 }
1181
1182
1183 /* .............................................................................. */
1184
DtsecSetPromiscuous(t_Handle h_Dtsec,bool newVal)1185 static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
1186 {
1187 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1188 t_DtsecMemMap *p_DtsecMemMap;
1189 uint32_t tmpReg32;
1190
1191 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1192 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
1193 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
1194
1195 p_DtsecMemMap = p_Dtsec->p_MemMap;
1196
1197 tmpReg32 = GET_UINT32(p_DtsecMemMap->rctrl);
1198
1199 if (newVal)
1200 tmpReg32 |= RCTRL_PROM;
1201 else
1202 tmpReg32 &= ~RCTRL_PROM;
1203
1204 WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32);
1205
1206 return E_OK;
1207 }
1208
1209 /* .............................................................................. */
1210
DtsecSetStatistics(t_Handle h_Dtsec,e_FmMacStatisticsLevel statisticsLevel)1211 static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
1212 {
1213 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1214 t_DtsecMemMap *p_DtsecMemMap;
1215
1216 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1217 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
1218
1219 p_DtsecMemMap = p_Dtsec->p_MemMap;
1220
1221 p_Dtsec->statisticsLevel = statisticsLevel;
1222
1223 switch (p_Dtsec->statisticsLevel)
1224 {
1225 case(e_FM_MAC_NONE_STATISTICS):
1226 WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff);
1227 WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff);
1228 WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) & ~ECNTRL_STEN);
1229 WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) & ~IMASK_MSROEN);
1230 p_Dtsec->exceptions &= ~IMASK_MSROEN;
1231 break;
1232 case(e_FM_MAC_PARTIAL_STATISTICS):
1233 WRITE_UINT32(p_DtsecMemMap->cam1, CAM1_ERRORS_ONLY);
1234 WRITE_UINT32(p_DtsecMemMap->cam2, CAM2_ERRORS_ONLY);
1235 WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN);
1236 WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN);
1237 p_Dtsec->exceptions |= IMASK_MSROEN;
1238 break;
1239 case(e_FM_MAC_FULL_STATISTICS):
1240 WRITE_UINT32(p_DtsecMemMap->cam1,0);
1241 WRITE_UINT32(p_DtsecMemMap->cam2,0);
1242 WRITE_UINT32(p_DtsecMemMap->ecntrl, GET_UINT32(p_DtsecMemMap->ecntrl) | ECNTRL_STEN);
1243 WRITE_UINT32(p_DtsecMemMap->imask, GET_UINT32(p_DtsecMemMap->imask) | IMASK_MSROEN);
1244 p_Dtsec->exceptions |= IMASK_MSROEN;
1245 break;
1246 default:
1247 RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
1248 }
1249
1250 return E_OK;
1251 }
1252
1253 /* .............................................................................. */
1254
DtsecAdjustLink(t_Handle h_Dtsec,e_EnetSpeed speed,bool fullDuplex)1255 static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
1256 {
1257 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1258 t_DtsecMemMap *p_DtsecMemMap;
1259 uint32_t tmpReg32;
1260
1261 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1262 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
1263 p_DtsecMemMap = p_Dtsec->p_MemMap;
1264 SANITY_CHECK_RETURN_ERROR(p_DtsecMemMap, E_INVALID_HANDLE);
1265
1266 if ((!fullDuplex) && (speed >= e_ENET_SPEED_1000))
1267 RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
1268
1269 p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
1270 p_Dtsec->halfDuplex = !fullDuplex;
1271
1272 tmpReg32 = GET_UINT32(p_DtsecMemMap->maccfg2);
1273 if(p_Dtsec->halfDuplex)
1274 tmpReg32 &= ~MACCFG2_FULL_DUPLEX;
1275 else
1276 tmpReg32 |= MACCFG2_FULL_DUPLEX;
1277
1278 tmpReg32 &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
1279 if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
1280 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)||
1281 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
1282 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
1283 tmpReg32 |= MACCFG2_NIBBLE_MODE;
1284 else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
1285 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)||
1286 (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000))
1287 tmpReg32 |= MACCFG2_BYTE_MODE;
1288 WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32);
1289
1290 tmpReg32 = GET_UINT32(p_DtsecMemMap->ecntrl);
1291 if (!(tmpReg32 & ECNTRL_CFG_RO))
1292 {
1293 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
1294 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
1295 tmpReg32 |= ECNTRL_R100M;
1296 else
1297 tmpReg32 &= ~ECNTRL_R100M;
1298 WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32);
1299 }
1300
1301 return E_OK;
1302 }
1303
1304 /* .............................................................................. */
1305
DtsecGetId(t_Handle h_Dtsec,uint32_t * macId)1306 static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
1307 {
1308 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1309
1310 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1311 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
1312
1313 *macId = p_Dtsec->macId;
1314
1315 return E_OK;
1316 }
1317
1318 /* .............................................................................. */
1319
DtsecGetVersion(t_Handle h_Dtsec,uint32_t * macVersion)1320 static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
1321 {
1322 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1323 t_DtsecMemMap *p_DtsecMemMap;
1324
1325 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1326 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
1327 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
1328
1329 p_DtsecMemMap = p_Dtsec->p_MemMap;
1330 *macVersion = GET_UINT32(p_DtsecMemMap->tsec_id1);
1331
1332 return E_OK;
1333 }
1334
1335 /* .............................................................................. */
1336
DtsecSetException(t_Handle h_Dtsec,e_FmMacExceptions exception,bool enable)1337 static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
1338 {
1339 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1340 uint32_t tmpReg, bitMask = 0;
1341 t_DtsecMemMap *p_DtsecMemMap;
1342
1343 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1344 SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_HANDLE);
1345 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_NULL_POINTER);
1346
1347 p_DtsecMemMap = p_Dtsec->p_MemMap;
1348
1349 if(exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
1350 {
1351 GET_EXCEPTION_FLAG(bitMask, exception);
1352 if(bitMask)
1353 {
1354 if (enable)
1355 p_Dtsec->exceptions |= bitMask;
1356 else
1357 p_Dtsec->exceptions &= ~bitMask;
1358 }
1359 else
1360 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
1361
1362 tmpReg = GET_UINT32(p_DtsecMemMap->imask);
1363 if(enable)
1364 tmpReg |= bitMask;
1365 else
1366 tmpReg &= ~bitMask;
1367 WRITE_UINT32(p_DtsecMemMap->imask, tmpReg);
1368
1369 /* warn if MIB OVFL is disabled and statistic gathering is enabled */
1370 if((exception == e_FM_MAC_EX_1G_RX_MIB_CNT_OVFL) &&
1371 !enable &&
1372 (p_Dtsec->statisticsLevel != e_FM_MAC_NONE_STATISTICS))
1373 DBG(WARNING, ("Disabled MIB counters overflow exceptions. Counters value may be inaccurate due to unregistered overflow"));
1374
1375 }
1376 else
1377 {
1378 if(!p_Dtsec->ptpTsuEnabled)
1379 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
1380 tmpReg = GET_UINT32(p_DtsecMemMap->tmr_pemask);
1381 switch(exception){
1382 case(e_FM_MAC_EX_1G_1588_TS_RX_ERR):
1383 if(enable)
1384 {
1385 p_Dtsec->enTsuErrExeption = TRUE;
1386 WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg | PEMASK_TSRE);
1387 }
1388 else
1389 {
1390 p_Dtsec->enTsuErrExeption = FALSE;
1391 WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg & ~PEMASK_TSRE);
1392 }
1393 break;
1394 default:
1395 RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
1396 }
1397 }
1398
1399 return E_OK;
1400 }
1401
1402 /* ........................................................................... */
1403
1404 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
DtsecDumpRegs(t_Handle h_Dtsec)1405 static t_Error DtsecDumpRegs(t_Handle h_Dtsec)
1406 {
1407 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1408 int i = 0;
1409
1410 DECLARE_DUMP;
1411
1412 if (p_Dtsec->p_MemMap)
1413 {
1414
1415 DUMP_TITLE(p_Dtsec->p_MemMap, ("MAC %d: ", p_Dtsec->macId));
1416 DUMP_VAR(p_Dtsec->p_MemMap, tsec_id1);
1417 DUMP_VAR(p_Dtsec->p_MemMap, tsec_id2);
1418 DUMP_VAR(p_Dtsec->p_MemMap, ievent);
1419 DUMP_VAR(p_Dtsec->p_MemMap, imask);
1420 DUMP_VAR(p_Dtsec->p_MemMap, edis);
1421 DUMP_VAR(p_Dtsec->p_MemMap, ecntrl);
1422 DUMP_VAR(p_Dtsec->p_MemMap, ptv);
1423 DUMP_VAR(p_Dtsec->p_MemMap, tmr_ctrl);
1424 DUMP_VAR(p_Dtsec->p_MemMap, tmr_pevent);
1425 DUMP_VAR(p_Dtsec->p_MemMap, tmr_pemask);
1426 DUMP_VAR(p_Dtsec->p_MemMap, tctrl);
1427 DUMP_VAR(p_Dtsec->p_MemMap, rctrl);
1428 DUMP_VAR(p_Dtsec->p_MemMap, maccfg1);
1429 DUMP_VAR(p_Dtsec->p_MemMap, maccfg2);
1430 DUMP_VAR(p_Dtsec->p_MemMap, ipgifg);
1431 DUMP_VAR(p_Dtsec->p_MemMap, hafdup);
1432 DUMP_VAR(p_Dtsec->p_MemMap, maxfrm);
1433
1434 DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr1);
1435 DUMP_VAR(p_Dtsec->p_MemMap, macstnaddr2);
1436
1437 DUMP_SUBSTRUCT_ARRAY(i, 8)
1438 {
1439 DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match1);
1440 DUMP_VAR(p_Dtsec->p_MemMap, macaddr[i].exact_match2);
1441 }
1442 }
1443
1444 return E_OK;
1445 }
1446 #endif /* (defined(DEBUG_ERRORS) && ... */
1447
1448
1449 /*****************************************************************************/
1450 /* FM Init & Free API */
1451 /*****************************************************************************/
1452
1453 /* .............................................................................. */
1454
DtsecInit(t_Handle h_Dtsec)1455 static t_Error DtsecInit(t_Handle h_Dtsec)
1456 {
1457 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1458 t_DtsecDriverParam *p_DtsecDriverParam;
1459 t_DtsecMemMap *p_DtsecMemMap;
1460 int i;
1461 uint32_t tmpReg32;
1462 uint64_t addr;
1463 t_Error err;
1464
1465 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1466 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1467 SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_MemMap, E_INVALID_STATE);
1468
1469 CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
1470
1471 p_DtsecDriverParam = p_Dtsec->p_DtsecDriverParam;
1472 p_Dtsec->halfDuplex = p_DtsecDriverParam->halfDuplex;
1473 p_Dtsec->debugMode = p_DtsecDriverParam->debugMode;
1474 p_DtsecMemMap = p_Dtsec->p_MemMap;
1475
1476 /*************dtsec_id2******************/
1477 tmpReg32 = GET_UINT32(p_DtsecMemMap->tsec_id2);
1478
1479 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
1480 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
1481 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
1482 (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) ||
1483 (p_Dtsec->enetMode == e_ENET_MODE_RMII_100))
1484 if(tmpReg32 & ID2_INT_REDUCED_OFF)
1485 {
1486 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for reduced interface in current DTSEC version"));
1487 }
1488
1489 if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
1490 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) ||
1491 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)||
1492 (p_Dtsec->enetMode == e_ENET_MODE_MII_10) ||
1493 (p_Dtsec->enetMode == e_ENET_MODE_MII_100))
1494 if(tmpReg32 & ID2_INT_NORMAL_OFF)
1495 {
1496 RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("no support for normal interface in current DTSEC version"));
1497 }
1498 /*************dtsec_id2******************/
1499
1500 /***************EDIS************************/
1501 WRITE_UINT32(p_DtsecMemMap->edis, p_DtsecDriverParam->errorDisabled);
1502 /***************EDIS************************/
1503
1504 /***************ECNTRL************************/
1505 tmpReg32 = 0;
1506 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
1507 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
1508 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
1509 (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000))
1510 tmpReg32 |= ECNTRL_GMIIM;
1511 if ((p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
1512 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) ||
1513 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000))
1514 tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM);
1515 if (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000)
1516 tmpReg32 |= (ECNTRL_SGMIIM | ECNTRL_TBIM | ECNTRL_QSGMIIM);
1517 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
1518 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10)||
1519 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100))
1520 tmpReg32 |= ECNTRL_RPM;
1521 if ((p_Dtsec->enetMode == e_ENET_MODE_RGMII_100) ||
1522 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100) ||
1523 (p_Dtsec->enetMode == e_ENET_MODE_RMII_100))
1524 tmpReg32 |= ECNTRL_R100M;
1525 if ((p_Dtsec->enetMode == e_ENET_MODE_RMII_10) || (p_Dtsec->enetMode == e_ENET_MODE_RMII_100))
1526 tmpReg32 |= ECNTRL_RMM;
1527 WRITE_UINT32(p_DtsecMemMap->ecntrl, tmpReg32);
1528 /***************ECNTRL************************/
1529
1530 /***************PTV************************/
1531 tmpReg32 = 0;
1532 #ifdef FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1
1533 {
1534 t_FmRevisionInfo revInfo;
1535 FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &revInfo);
1536 if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
1537 p_DtsecDriverParam->pauseTime += 2;
1538 }
1539 #endif /* FM_SHORT_PAUSE_TIME_ERRATA_DTSEC1 */
1540 if (p_DtsecDriverParam->pauseTime)
1541 tmpReg32 |= (uint32_t)p_DtsecDriverParam->pauseTime;
1542
1543 if (p_DtsecDriverParam->pauseExtended)
1544 tmpReg32 |= ((uint32_t)p_DtsecDriverParam->pauseExtended) << PTV_PTE_OFST;
1545 WRITE_UINT32(p_DtsecMemMap->ptv, tmpReg32);
1546 /***************PTV************************/
1547
1548 /***************TCTRL************************/
1549 tmpReg32 = 0;
1550 if(p_DtsecDriverParam->halfDuplex)
1551 {
1552 if(p_DtsecDriverParam->halfDulexFlowControlEn)
1553 tmpReg32 |= TCTRL_THDF;
1554 }
1555 else
1556 {
1557 if(p_DtsecDriverParam->txTimeStampEn)
1558 tmpReg32 |= TCTRL_TTSE;
1559 }
1560 WRITE_UINT32(p_DtsecMemMap->tctrl, tmpReg32);
1561 /***************TCTRL************************/
1562
1563 /***************RCTRL************************/
1564 tmpReg32 = 0;
1565 if (p_DtsecDriverParam->packetAlignmentPadding)
1566 tmpReg32 |= ((uint32_t)(0x0000001f & p_DtsecDriverParam->packetAlignmentPadding)) << 16;
1567 if (p_DtsecDriverParam->controlFrameAccept)
1568 tmpReg32 |= RCTRL_CFA;
1569 if (p_DtsecDriverParam->groupHashExtend)
1570 tmpReg32 |= RCTRL_GHTX;
1571 if(p_DtsecDriverParam->rxTimeStampEn)
1572 tmpReg32 |= RCTRL_RTSE;
1573 if (p_DtsecDriverParam->broadcReject)
1574 tmpReg32 |= RCTRL_BC_REJ;
1575 if (p_DtsecDriverParam->rxShortFrame)
1576 tmpReg32 |= RCTRL_RSF;
1577 if (p_DtsecDriverParam->promiscuousEnable)
1578 tmpReg32 |= RCTRL_PROM;
1579 if (p_DtsecDriverParam->exactMatch)
1580 tmpReg32 |= RCTRL_EMEN;
1581
1582 WRITE_UINT32(p_DtsecMemMap->rctrl, tmpReg32);
1583 /***************RCTRL************************/
1584
1585 /* Assign a Phy Address to the TBI (TBIPA). */
1586 /* Done also in case that TBI is not selected to avoid */
1587 /* conflict with the external PHY�s Physical address */
1588 WRITE_UINT32(p_DtsecMemMap->tbipa, p_DtsecDriverParam->tbiPhyAddr);
1589
1590 /* Reset the management interface */
1591 WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, MIIMCFG_RESET_MGMT);
1592 WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg, ~MIIMCFG_RESET_MGMT);
1593 /* Setup the MII Mgmt clock speed */
1594 WRITE_UINT32(p_Dtsec->p_MiiMemMap->miimcfg,
1595 (uint32_t)GetMiiDiv((int32_t)(((p_Dtsec->fmMacControllerDriver.clkFreq*10)/2)/8)));
1596
1597 if(p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)
1598 {
1599 uint16_t tmpReg16;
1600
1601 /* Configure the TBI PHY Control Register */
1602 tmpReg16 = PHY_TBICON_SPEED2 | PHY_TBICON_SRESET;
1603
1604 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16);
1605
1606 tmpReg16 = PHY_TBICON_SPEED2;
1607
1608 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 17, tmpReg16);
1609
1610 if(!p_DtsecDriverParam->halfDuplex)
1611 tmpReg16 |= PHY_CR_FULLDUPLEX | 0x8000 | PHY_CR_ANE;
1612
1613 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16);
1614
1615 tmpReg16 = 0x01a0;
1616 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 4, tmpReg16);
1617
1618 tmpReg16 = 0x1340;
1619 DTSEC_MII_WritePhyReg(p_Dtsec, p_DtsecDriverParam->tbiPhyAddr, 0, tmpReg16);
1620 }
1621
1622 /***************TMR_CTL************************/
1623 WRITE_UINT32(p_DtsecMemMap->tmr_ctrl, 0);
1624
1625 if(p_Dtsec->ptpTsuEnabled)
1626 {
1627 tmpReg32 = 0;
1628 if (p_Dtsec->enTsuErrExeption)
1629 tmpReg32 |= PEMASK_TSRE;
1630 WRITE_UINT32(p_DtsecMemMap->tmr_pemask, tmpReg32);
1631 WRITE_UINT32(p_DtsecMemMap->tmr_pevent, tmpReg32);
1632 }
1633
1634 /***************DEBUG************************/
1635 tmpReg32 = 0;
1636 if(p_DtsecDriverParam->debugMode)
1637 WRITE_UINT32(p_DtsecMemMap->tsec_id1, TSEC_ID1_DEBUG);
1638 /***************DEBUG************************/
1639
1640 /***************MACCFG1***********************/
1641 WRITE_UINT32(p_DtsecMemMap->maccfg1, MACCFG1_SOFT_RESET);
1642 WRITE_UINT32(p_DtsecMemMap->maccfg1, 0);
1643 tmpReg32 = 0;
1644 if(p_DtsecDriverParam->loopback)
1645 tmpReg32 |= MACCFG1_LOOPBACK;
1646 if(p_DtsecDriverParam->actOnRxPauseFrame)
1647 tmpReg32 |= MACCFG1_RX_FLOW;
1648 if(p_DtsecDriverParam->actOnTxPauseFrame)
1649 tmpReg32 |= MACCFG1_TX_FLOW;
1650 WRITE_UINT32(p_DtsecMemMap->maccfg1, tmpReg32);
1651 /***************MACCFG1***********************/
1652
1653 /***************MACCFG2***********************/
1654 tmpReg32 = 0;
1655 if( (p_Dtsec->enetMode == e_ENET_MODE_RMII_10) ||
1656 (p_Dtsec->enetMode == e_ENET_MODE_RMII_100) ||
1657 (p_Dtsec->enetMode == e_ENET_MODE_MII_10) ||
1658 (p_Dtsec->enetMode == e_ENET_MODE_MII_100) ||
1659 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_10) ||
1660 (p_Dtsec->enetMode == e_ENET_MODE_RGMII_100)||
1661 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_10) ||
1662 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_100))
1663 tmpReg32 |= MACCFG2_NIBBLE_MODE;
1664 else if((p_Dtsec->enetMode == e_ENET_MODE_RGMII_1000) ||
1665 (p_Dtsec->enetMode == e_ENET_MODE_SGMII_1000)||
1666 (p_Dtsec->enetMode == e_ENET_MODE_GMII_1000)||
1667 (p_Dtsec->enetMode == e_ENET_MODE_QSGMII_1000))
1668 tmpReg32 |= MACCFG2_BYTE_MODE;
1669
1670 tmpReg32 |= (((uint32_t)p_DtsecDriverParam->preambleLength) & 0x0000000f)<< PREAMBLE_LENGTH_SHIFT;
1671
1672 if(p_DtsecDriverParam->preambleRxEn)
1673 tmpReg32 |= MACCFG2_PRE_AM_Rx_EN;
1674 if(p_DtsecDriverParam->preambleTxEn)
1675 tmpReg32 |= MACCFG2_PRE_AM_Tx_EN;
1676 if(p_DtsecDriverParam->lengthCheckEnable)
1677 tmpReg32 |= MACCFG2_LENGTH_CHECK;
1678 if(p_DtsecDriverParam->padAndCrcEnable)
1679 tmpReg32 |= MACCFG2_PAD_CRC_EN;
1680 if(p_DtsecDriverParam->crcEnable)
1681 tmpReg32 |= MACCFG2_CRC_EN;
1682 if(!p_DtsecDriverParam->halfDuplex)
1683 tmpReg32 |= MACCFG2_FULL_DUPLEX;
1684 WRITE_UINT32(p_DtsecMemMap->maccfg2, tmpReg32);
1685 /***************MACCFG2***********************/
1686
1687 /***************IPGIFG************************/
1688 tmpReg32 = 0;
1689 ASSERT_COND(p_DtsecDriverParam->nonBackToBackIpg1 <= p_DtsecDriverParam->nonBackToBackIpg2);
1690 tmpReg32 = (uint32_t)((((uint32_t)p_DtsecDriverParam->nonBackToBackIpg1 <<
1691 IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_1) |
1692 (((uint32_t)p_DtsecDriverParam->nonBackToBackIpg2 <<
1693 IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT) & IPGIFG_NON_BACK_TO_BACK_IPG_2) |
1694 (((uint32_t)p_DtsecDriverParam->minIfgEnforcement <<
1695 IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT) & IPGIFG_MIN_IFG_ENFORCEMENT) |
1696 ((uint32_t)p_DtsecDriverParam->backToBackIpg & IPGIFG_BACK_TO_BACK_IPG));
1697 WRITE_UINT32(p_DtsecMemMap->ipgifg, tmpReg32);
1698 /***************IPGIFG************************/
1699
1700 /***************HAFDUP************************/
1701 tmpReg32 = 0;
1702 if(p_DtsecDriverParam->alternateBackoffEnable)
1703 {
1704 tmpReg32 = (uint32_t) (HAFDUP_ALT_BEB | (((uint32_t)p_DtsecDriverParam->alternateBackoffVal & 0x0000000f) <<
1705 HAFDUP_ALTERNATE_BEB_TRUNCATION_SHIFT));
1706 }
1707
1708 if(p_DtsecDriverParam->backPressureNoBackoff)
1709 tmpReg32 |= HAFDUP_BP_NO_BACKOFF;
1710 if(p_DtsecDriverParam->noBackoff)
1711 tmpReg32 |= HAFDUP_NO_BACKOFF;
1712 if(p_DtsecDriverParam->excessDefer)
1713 tmpReg32 |= HAFDUP_EXCESS_DEFER;
1714 tmpReg32 |= (((uint32_t)p_DtsecDriverParam->maxRetransmission <<
1715 HAFDUP_RETRANSMISSION_MAX_SHIFT )& HAFDUP_RETRANSMISSION_MAX);
1716 tmpReg32|= ((uint32_t)p_DtsecDriverParam->collisionWindow & HAFDUP_COLLISION_WINDOW);
1717
1718 WRITE_UINT32(p_DtsecMemMap->hafdup, tmpReg32);
1719 /***************HAFDUP************************/
1720
1721 /***************MAXFRM************************/
1722 /* Initialize MAXFRM */
1723 WRITE_UINT32(p_DtsecMemMap->maxfrm,
1724 p_DtsecDriverParam->maxFrameLength);
1725 err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm,
1726 e_FM_MAC_1G,
1727 p_Dtsec->fmMacControllerDriver.macId,
1728 p_DtsecDriverParam->maxFrameLength);
1729 if (err)
1730 RETURN_ERROR(MAJOR, err, NO_MSG);
1731 /***************MAXFRM************************/
1732
1733 /***************CAM1************************/
1734 WRITE_UINT32(p_DtsecMemMap->cam1,0xffffffff);
1735 WRITE_UINT32(p_DtsecMemMap->cam2,0xffffffff);
1736
1737 /***************IMASK************************/
1738 WRITE_UINT32(p_DtsecMemMap->imask, p_Dtsec->exceptions);
1739 /***************IMASK************************/
1740
1741 /***************IEVENT************************/
1742 WRITE_UINT32(p_DtsecMemMap->ievent, EVENTS_MASK);
1743
1744 /***************MACSTNADDR1/2*****************/
1745 /* Initialize MAC Station Address registers (1 & 2) */
1746 /* Station address have to be swapped (big endian to little endian */
1747 addr = p_Dtsec->addr;
1748
1749 tmpReg32 = (uint32_t)(addr);
1750 SwapUint32P(&tmpReg32);
1751 WRITE_UINT32(p_DtsecMemMap->macstnaddr1, tmpReg32);
1752
1753 tmpReg32 = (uint32_t)(addr>>32);
1754 SwapUint32P(&tmpReg32);
1755 WRITE_UINT32(p_DtsecMemMap->macstnaddr2, tmpReg32);
1756 /***************MACSTNADDR1/2*****************/
1757
1758 /***************DEBUG*****************/
1759 WRITE_UINT32(p_DtsecMemMap->tx_threshold, (uint32_t)(p_DtsecDriverParam->fifoTxThr & 0x7f));
1760 WRITE_UINT32(p_DtsecMemMap->tx_watermark_high, (uint32_t)(p_DtsecDriverParam->fifoTxWatermarkH & 0x7f));
1761 WRITE_UINT32(p_DtsecMemMap->rx_watermark_low, (uint32_t)(p_DtsecDriverParam->fifoRxWatermarkL & 0x7f));
1762 /***************DEBUG*****************/
1763
1764 /*****************HASH************************/
1765 for(i=0 ; i<NUM_OF_HASH_REGS ; i++)
1766 {
1767 /* Initialize IADDRx */
1768 WRITE_UINT32(p_DtsecMemMap->igaddr[i], 0);
1769 /* Initialize GADDRx */
1770 WRITE_UINT32(p_DtsecMemMap->gaddr[i], 0);
1771 }
1772
1773 p_Dtsec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
1774 if(!p_Dtsec->p_MulticastAddrHash)
1775 {
1776 FreeInitResources(p_Dtsec);
1777 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
1778 }
1779
1780 p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
1781 if(!p_Dtsec->p_UnicastAddrHash)
1782 {
1783 FreeInitResources(p_Dtsec);
1784 RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
1785 }
1786
1787 /* register err intr handler for dtsec to FPM (err)*/
1788 FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR, DtsecErrException , p_Dtsec);
1789 /* register 1588 intr handler for TMR to FPM (normal)*/
1790 FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC_TMR, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL, Dtsec1588Exception , p_Dtsec);
1791 /* register normal intr handler for dtsec to main interrupt controller. */
1792 if (p_Dtsec->mdioIrq != NO_IRQ)
1793 {
1794 XX_SetIntr(p_Dtsec->mdioIrq, DtsecException, p_Dtsec);
1795 XX_EnableIntr(p_Dtsec->mdioIrq);
1796 }
1797
1798 XX_Free(p_DtsecDriverParam);
1799 p_Dtsec->p_DtsecDriverParam = NULL;
1800
1801 err = DtsecSetStatistics(p_Dtsec, e_FM_MAC_FULL_STATISTICS);
1802 if(err)
1803 {
1804 FreeInitResources(p_Dtsec);
1805 RETURN_ERROR(MAJOR, err, NO_MSG);
1806 }
1807
1808 return E_OK;
1809 }
1810
1811 /* ........................................................................... */
1812
DtsecFree(t_Handle h_Dtsec)1813 static t_Error DtsecFree(t_Handle h_Dtsec)
1814 {
1815 t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
1816
1817 SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1818
1819 FreeInitResources(p_Dtsec);
1820
1821 if (p_Dtsec->p_DtsecDriverParam)
1822 {
1823 XX_Free(p_Dtsec->p_DtsecDriverParam);
1824 p_Dtsec->p_DtsecDriverParam = NULL;
1825 }
1826 XX_Free (h_Dtsec);
1827
1828 return E_OK;
1829 }
1830
1831 /* .............................................................................. */
1832
InitFmMacControllerDriver(t_FmMacControllerDriver * p_FmMacControllerDriver)1833 static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
1834 {
1835 p_FmMacControllerDriver->f_FM_MAC_Init = DtsecInit;
1836 p_FmMacControllerDriver->f_FM_MAC_Free = DtsecFree;
1837
1838 p_FmMacControllerDriver->f_FM_MAC_SetStatistics = DtsecSetStatistics;
1839 p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback = DtsecConfigLoopback;
1840 p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength = DtsecConfigMaxFrameLength;
1841
1842 p_FmMacControllerDriver->f_FM_MAC_ConfigWan = NULL; /* Not supported on dTSEC */
1843
1844 p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc = DtsecConfigPadAndCrc;
1845 p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex = DtsecConfigHalfDuplex;
1846 p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck = DtsecConfigLengthCheck;
1847 p_FmMacControllerDriver->f_FM_MAC_ConfigException = DtsecConfigException;
1848
1849 p_FmMacControllerDriver->f_FM_MAC_Enable = DtsecEnable;
1850 p_FmMacControllerDriver->f_FM_MAC_Disable = DtsecDisable;
1851
1852 p_FmMacControllerDriver->f_FM_MAC_SetException = DtsecSetException;
1853
1854 p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous = DtsecSetPromiscuous;
1855 p_FmMacControllerDriver->f_FM_MAC_AdjustLink = DtsecAdjustLink;
1856
1857 p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp = DtsecEnable1588TimeStamp;
1858 p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp = DtsecDisable1588TimeStamp;
1859
1860 p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames = DtsecTxMacPause;
1861 p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames = DtsecRxIgnoreMacPause;
1862
1863 p_FmMacControllerDriver->f_FM_MAC_ResetCounters = DtsecResetCounters;
1864 p_FmMacControllerDriver->f_FM_MAC_GetStatistics = DtsecGetStatistics;
1865
1866 p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr = DtsecModifyMacAddress;
1867 p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr = DtsecAddHashMacAddress;
1868 p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr = DtsecDelHashMacAddress;
1869 p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr = DtsecAddExactMatchMacAddress;
1870 p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr = DtsecDelExactMatchMacAddress;
1871 p_FmMacControllerDriver->f_FM_MAC_GetId = DtsecGetId;
1872 p_FmMacControllerDriver->f_FM_MAC_GetVersion = DtsecGetVersion;
1873 p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength = DtsecGetMaxFrameLength;
1874
1875 p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg = DTSEC_MII_WritePhyReg;
1876 p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg = DTSEC_MII_ReadPhyReg;
1877
1878 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
1879 p_FmMacControllerDriver->f_FM_MAC_DumpRegs = DtsecDumpRegs;
1880 #endif /* (defined(DEBUG_ERRORS) && ... */
1881 }
1882
1883
1884 /*****************************************************************************/
1885 /* dTSEC Config Main Entry */
1886 /*****************************************************************************/
1887
1888 /* .............................................................................. */
1889
DTSEC_Config(t_FmMacParams * p_FmMacParam)1890 t_Handle DTSEC_Config(t_FmMacParams *p_FmMacParam)
1891 {
1892 t_Dtsec *p_Dtsec;
1893 t_DtsecDriverParam *p_DtsecDriverParam;
1894 uintptr_t baseAddr;
1895 uint8_t i;
1896
1897 SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
1898
1899 baseAddr = p_FmMacParam->baseAddr;
1900 /* allocate memory for the UCC GETH data structure. */
1901 p_Dtsec = (t_Dtsec *) XX_Malloc(sizeof(t_Dtsec));
1902 if (!p_Dtsec)
1903 {
1904 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
1905 return NULL;
1906 }
1907 /* Zero out * p_Dtsec */
1908 memset(p_Dtsec, 0, sizeof(t_Dtsec));
1909 InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
1910
1911 /* allocate memory for the dTSEC driver parameters data structure. */
1912 p_DtsecDriverParam = (t_DtsecDriverParam *) XX_Malloc(sizeof(t_DtsecDriverParam));
1913 if (!p_DtsecDriverParam)
1914 {
1915 XX_Free(p_Dtsec);
1916 REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
1917 return NULL;
1918 }
1919 /* Zero out */
1920 memset(p_DtsecDriverParam, 0, sizeof(t_DtsecDriverParam));
1921
1922 /* Plant parameter structure pointer */
1923 p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
1924
1925 SetDefaultParam(p_DtsecDriverParam);
1926
1927 for (i=0; i < sizeof(p_FmMacParam->addr); i++)
1928 p_Dtsec->addr |= ((uint64_t)p_FmMacParam->addr[i] << ((5-i) * 8));
1929
1930 p_Dtsec->p_MemMap = (t_DtsecMemMap *)UINT_TO_PTR(baseAddr);
1931 p_Dtsec->p_MiiMemMap = (t_MiiAccessMemMap *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
1932 p_Dtsec->enetMode = p_FmMacParam->enetMode;
1933 p_Dtsec->macId = p_FmMacParam->macId;
1934 p_Dtsec->exceptions = DEFAULT_exceptions;
1935 p_Dtsec->mdioIrq = p_FmMacParam->mdioIrq;
1936 p_Dtsec->f_Exception = p_FmMacParam->f_Exception;
1937 p_Dtsec->f_Event = p_FmMacParam->f_Event;
1938 p_Dtsec->h_App = p_FmMacParam->h_App;
1939
1940 return p_Dtsec;
1941 }
1942