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
55static 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
107static 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
157static 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
212static 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
238static 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
312static 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
321static 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
439static 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
460static 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
484static 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
492static 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
509static 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
540static 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
569static 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
584static 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
598static 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
612static 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
626static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
627{
628#ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
629UNUSED(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
644static 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
688static 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
713static 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
738static 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
789static 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
814static 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
831static 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
847static 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
939static 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
968static 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
985static 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
1027static 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
1058static 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
1112static 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
1185static 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
1211static 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
1255static 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
1306static 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
1320static 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
1337static 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))
1405static 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
1455static 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
1813static 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
1833static 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
1890t_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