xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c (revision acc1a9ef)
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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, &ethAddr, 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 
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 
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 
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 
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 
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 
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 
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 
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 
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))
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 
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 
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 
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 
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