]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c
Import tzdata 2020a
[FreeBSD/FreeBSD.git] / sys / contrib / ncsw / Peripherals / FM / MAC / dtsec.c
1 /*
2  * Copyright 2008-2013 Freescale Semiconductor Inc.
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   FMan dTSEC driver
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 "debug_ext.h"
45 #include "crc_mac_addr_ext.h"
46
47 #include "fm_common.h"
48 #include "dtsec.h"
49 #include "fsl_fman_dtsec.h"
50 #include "fsl_fman_dtsec_mii_acc.h"
51
52 /*****************************************************************************/
53 /*                      Internal routines                                    */
54 /*****************************************************************************/
55
56 static t_Error CheckInitParameters(t_Dtsec *p_Dtsec)
57 {
58     if (ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_10000)
59         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 1G MAC driver only supports 1G or lower speeds"));
60     if (p_Dtsec->macId >= FM_MAX_NUM_OF_1G_MACS)
61         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId can not be greater than the number of 1G MACs"));
62     if (p_Dtsec->addr == 0)
63         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC Must have a valid MAC Address"));
64     if ((ENET_SPEED_FROM_MODE(p_Dtsec->enetMode) >= e_ENET_SPEED_1000) &&
65         p_Dtsec->p_DtsecDriverParam->halfdup_on)
66         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet MAC 1G can't work in half duplex"));
67     if (p_Dtsec->p_DtsecDriverParam->halfdup_on && (p_Dtsec->p_DtsecDriverParam)->loopback)
68         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("LoopBack is not supported in halfDuplex mode"));
69 #ifdef FM_RX_PREAM_4_ERRATA_DTSEC_A001
70     if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev <= 6) /* fixed for rev3 */
71         if (p_Dtsec->p_DtsecDriverParam->rx_preamble)
72             RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("preambleRxEn"));
73 #endif /* FM_RX_PREAM_4_ERRATA_DTSEC_A001 */
74     if (((p_Dtsec->p_DtsecDriverParam)->tx_preamble || (p_Dtsec->p_DtsecDriverParam)->rx_preamble) &&( (p_Dtsec->p_DtsecDriverParam)->preamble_len != 0x7))
75         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Preamble length should be 0x7 bytes"));
76     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_on &&
77        (p_Dtsec->p_DtsecDriverParam->tx_time_stamp_en || p_Dtsec->p_DtsecDriverParam->rx_time_stamp_en))
78         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("dTSEC in half duplex mode has to be with 1588 timeStamping diable"));
79     if ((p_Dtsec->p_DtsecDriverParam)->rx_flow && (p_Dtsec->p_DtsecDriverParam)->rx_ctrl_acc )
80         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Receive control frame are not passed to the system memory so it can not be accept "));
81     if ((p_Dtsec->p_DtsecDriverParam)->rx_prepend  > MAX_PACKET_ALIGNMENT)
82         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("packetAlignmentPadding can't be greater than %d ",MAX_PACKET_ALIGNMENT ));
83     if (((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg1  > MAX_INTER_PACKET_GAP) ||
84         ((p_Dtsec->p_DtsecDriverParam)->non_back_to_back_ipg2 > MAX_INTER_PACKET_GAP) ||
85         ((p_Dtsec->p_DtsecDriverParam)->back_to_back_ipg > MAX_INTER_PACKET_GAP))
86         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Inter packet gap can't be greater than %d ",MAX_INTER_PACKET_GAP ));
87     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_alt_backoff_val > MAX_INTER_PALTERNATE_BEB)
88         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("alternateBackoffVal can't be greater than %d ",MAX_INTER_PALTERNATE_BEB ));
89     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_retransmit > MAX_RETRANSMISSION)
90         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("maxRetransmission can't be greater than %d ",MAX_RETRANSMISSION ));
91     if ((p_Dtsec->p_DtsecDriverParam)->halfdup_coll_window > MAX_COLLISION_WINDOW)
92         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("collisionWindow can't be greater than %d ",MAX_COLLISION_WINDOW ));
93
94     /*  If Auto negotiation process is disabled, need to */
95     /*  Set up the PHY using the MII Management Interface */
96     if (p_Dtsec->p_DtsecDriverParam->tbipa > MAX_PHYS)
97         RETURN_ERROR(MAJOR, E_NOT_IN_RANGE, ("PHY address (should be 0-%d)", MAX_PHYS));
98     if (!p_Dtsec->f_Exception)
99         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Exception"));
100     if (!p_Dtsec->f_Event)
101         RETURN_ERROR(MAJOR, E_INVALID_HANDLE, ("uninitialized f_Event"));
102
103 #ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
104     if (p_Dtsec->p_DtsecDriverParam->rx_len_check)
105        RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
106 #endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
107
108     return E_OK;
109 }
110
111 /* ......................................................................... */
112
113 static uint32_t GetMacAddrHashCode(uint64_t ethAddr)
114 {
115     uint32_t crc;
116
117     /* CRC calculation */
118     GET_MAC_ADDR_CRC(ethAddr, crc);
119
120     crc = GetMirror32(crc);
121
122     return crc;
123 }
124
125 /* ......................................................................... */
126
127 static void UpdateStatistics(t_Dtsec *p_Dtsec)
128 {
129     uint32_t car1, car2;
130
131     fman_dtsec_get_clear_carry_regs(p_Dtsec->p_MemMap, &car1, &car2);
132
133     if (car1)
134     {
135         if (car1 & CAR1_TR64)
136             p_Dtsec->internalStatistics.tr64 += VAL22BIT;
137         if (car1 & CAR1_TR127)
138             p_Dtsec->internalStatistics.tr127 += VAL22BIT;
139         if (car1 & CAR1_TR255)
140             p_Dtsec->internalStatistics.tr255 += VAL22BIT;
141         if (car1 & CAR1_TR511)
142             p_Dtsec->internalStatistics.tr511 += VAL22BIT;
143         if (car1 & CAR1_TRK1)
144             p_Dtsec->internalStatistics.tr1k += VAL22BIT;
145         if (car1 & CAR1_TRMAX)
146             p_Dtsec->internalStatistics.trmax += VAL22BIT;
147         if (car1 & CAR1_TRMGV)
148             p_Dtsec->internalStatistics.trmgv += VAL22BIT;
149         if (car1 & CAR1_RBYT)
150             p_Dtsec->internalStatistics.rbyt += (uint64_t)VAL32BIT;
151         if (car1 & CAR1_RPKT)
152             p_Dtsec->internalStatistics.rpkt += VAL22BIT;
153         if (car1 & CAR1_RMCA)
154             p_Dtsec->internalStatistics.rmca += VAL22BIT;
155         if (car1 & CAR1_RBCA)
156             p_Dtsec->internalStatistics.rbca += VAL22BIT;
157         if (car1 & CAR1_RXPF)
158             p_Dtsec->internalStatistics.rxpf += VAL16BIT;
159         if (car1 & CAR1_RALN)
160             p_Dtsec->internalStatistics.raln += VAL16BIT;
161         if (car1 & CAR1_RFLR)
162             p_Dtsec->internalStatistics.rflr += VAL16BIT;
163         if (car1 & CAR1_RCDE)
164             p_Dtsec->internalStatistics.rcde += VAL16BIT;
165         if (car1 & CAR1_RCSE)
166             p_Dtsec->internalStatistics.rcse += VAL16BIT;
167         if (car1 & CAR1_RUND)
168             p_Dtsec->internalStatistics.rund += VAL16BIT;
169         if (car1 & CAR1_ROVR)
170             p_Dtsec->internalStatistics.rovr += VAL16BIT;
171         if (car1 & CAR1_RFRG)
172             p_Dtsec->internalStatistics.rfrg += VAL16BIT;
173         if (car1 & CAR1_RJBR)
174             p_Dtsec->internalStatistics.rjbr += VAL16BIT;
175         if (car1 & CAR1_RDRP)
176             p_Dtsec->internalStatistics.rdrp += VAL16BIT;
177     }
178     if (car2)
179     {
180         if (car2  & CAR2_TFCS)
181             p_Dtsec->internalStatistics.tfcs += VAL12BIT;
182         if (car2  & CAR2_TBYT)
183             p_Dtsec->internalStatistics.tbyt += (uint64_t)VAL32BIT;
184         if (car2  & CAR2_TPKT)
185             p_Dtsec->internalStatistics.tpkt += VAL22BIT;
186         if (car2  & CAR2_TMCA)
187             p_Dtsec->internalStatistics.tmca += VAL22BIT;
188         if (car2  & CAR2_TBCA)
189             p_Dtsec->internalStatistics.tbca += VAL22BIT;
190         if (car2  & CAR2_TXPF)
191             p_Dtsec->internalStatistics.txpf += VAL16BIT;
192         if (car2  & CAR2_TDRP)
193             p_Dtsec->internalStatistics.tdrp += VAL16BIT;
194     }
195 }
196
197 /* .............................................................................. */
198
199 static uint16_t DtsecGetMaxFrameLength(t_Handle h_Dtsec)
200 {
201     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
202
203     SANITY_CHECK_RETURN_VALUE(p_Dtsec, E_INVALID_HANDLE, 0);
204     SANITY_CHECK_RETURN_VALUE(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE, 0);
205
206     return fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
207 }
208
209 /* .............................................................................. */
210
211 static void DtsecIsr(t_Handle h_Dtsec)
212 {
213     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
214     uint32_t            event;
215     struct dtsec_regs   *p_DtsecMemMap = p_Dtsec->p_MemMap;
216
217     /* do not handle MDIO events */
218     event = fman_dtsec_get_event(p_DtsecMemMap, (uint32_t)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN)));
219
220     event &= fman_dtsec_get_interrupt_mask(p_DtsecMemMap);
221
222     fman_dtsec_ack_event(p_DtsecMemMap, event);
223
224     if (event & DTSEC_IMASK_BREN)
225         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_RX);
226     if (event & DTSEC_IMASK_RXCEN)
227         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_CTL);
228     if (event & DTSEC_IMASK_MSROEN)
229         UpdateStatistics(p_Dtsec);
230     if (event & DTSEC_IMASK_GTSCEN)
231         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
232     if (event & DTSEC_IMASK_BTEN)
233         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_BAB_TX);
234     if (event & DTSEC_IMASK_TXCEN)
235         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_CTL);
236     if (event & DTSEC_IMASK_TXEEN)
237         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_ERR);
238     if (event & DTSEC_IMASK_LCEN)
239         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_LATE_COL);
240     if (event & DTSEC_IMASK_CRLEN)
241         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_COL_RET_LMT);
242     if (event & DTSEC_IMASK_XFUNEN)
243     {
244 #ifdef FM_TX_LOCKUP_ERRATA_DTSEC6
245         if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
246         {
247             uint32_t  tpkt1, tmpReg1, tpkt2, tmpReg2, i;
248             /* a. Write 0x00E0_0C00 to DTSEC_ID */
249             /* This is a read only regidter */
250
251             /* b. Read and save the value of TPKT */
252             tpkt1 = GET_UINT32(p_DtsecMemMap->tpkt);
253
254             /* c. Read the register at dTSEC address offset 0x32C */
255             tmpReg1 =  GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
256
257             /* d. Compare bits [9:15] to bits [25:31] of the register at address offset 0x32C. */
258             if ((tmpReg1 & 0x007F0000) != (tmpReg1 & 0x0000007F))
259             {
260                 /* If they are not equal, save the value of this register and wait for at least
261                  * MAXFRM*16 ns */
262                 XX_UDelay((uint32_t)(MIN(DtsecGetMaxFrameLength(p_Dtsec)*16/1000, 1)));
263             }
264
265             /* e. Read and save TPKT again and read the register at dTSEC address offset
266                 0x32C again*/
267             tpkt2 = GET_UINT32(p_DtsecMemMap->tpkt);
268             tmpReg2 = GET_UINT32(*(uint32_t*)((uint8_t*)p_DtsecMemMap + 0x32c));
269
270             /* f. Compare the value of TPKT saved in step b to value read in step e. Also
271                 compare bits [9:15] of the register at offset 0x32C saved in step d to the value
272                 of bits [9:15] saved in step e. If the two registers values are unchanged, then
273                 the transmit portion of the dTSEC controller is locked up and the user should
274                 proceed to the recover sequence. */
275             if ((tpkt1 == tpkt2) && ((tmpReg1 & 0x007F0000) == (tmpReg2 & 0x007F0000)))
276             {
277                 /* recover sequence */
278
279                 /* a.Write a 1 to RCTRL[GRS]*/
280
281                 WRITE_UINT32(p_DtsecMemMap->rctrl, GET_UINT32(p_DtsecMemMap->rctrl) | RCTRL_GRS);
282
283                 /* b.Wait until IEVENT[GRSC]=1, or at least 100 us has elapsed. */
284                 for (i = 0 ; i < 100 ; i++ )
285                 {
286                     if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
287                         break;
288                     XX_UDelay(1);
289                 }
290                 if (GET_UINT32(p_DtsecMemMap->ievent) & DTSEC_IMASK_GRSCEN)
291                     WRITE_UINT32(p_DtsecMemMap->ievent, DTSEC_IMASK_GRSCEN);
292                 else
293                     DBG(INFO,("Rx lockup due to dTSEC Tx lockup"));
294
295                 /* c.Write a 1 to bit n of FM_RSTC (offset 0x0CC of FPM)*/
296                 FmResetMac(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G, p_Dtsec->fmMacControllerDriver.macId);
297
298                 /* d.Wait 4 Tx clocks (32 ns) */
299                 XX_UDelay(1);
300
301                 /* e.Write a 0 to bit n of FM_RSTC. */
302                 /* cleared by FMAN */
303             }
304         }
305 #endif /* FM_TX_LOCKUP_ERRATA_DTSEC6 */
306
307         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_FIFO_UNDRN);
308     }
309     if (event & DTSEC_IMASK_MAGEN)
310         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_MAG_PCKT);
311     if (event & DTSEC_IMASK_GRSCEN)
312         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
313     if (event & DTSEC_IMASK_TDPEEN)
314         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_TX_DATA_ERR);
315     if (event & DTSEC_IMASK_RDPEEN)
316         p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_RX_DATA_ERR);
317
318     /*  - masked interrupts */
319     ASSERT_COND(!(event & DTSEC_IMASK_ABRTEN));
320     ASSERT_COND(!(event & DTSEC_IMASK_IFERREN));
321 }
322
323 static void DtsecMdioIsr(t_Handle h_Dtsec)
324 {
325     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
326     uint32_t            event;
327     struct dtsec_regs   *p_DtsecMemMap = p_Dtsec->p_MemMap;
328
329     event = GET_UINT32(p_DtsecMemMap->ievent);
330     /* handle only MDIO events */
331     event &= (DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN);
332     if (event)
333     {
334         event &= GET_UINT32(p_DtsecMemMap->imask);
335
336         WRITE_UINT32(p_DtsecMemMap->ievent, event);
337
338         if (event & DTSEC_IMASK_MMRDEN)
339             p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_RD_COMPLET);
340         if (event & DTSEC_IMASK_MMWREN)
341             p_Dtsec->f_Event(p_Dtsec->h_App, e_FM_MAC_EX_1G_MII_MNG_WR_COMPLET);
342     }
343 }
344
345 static void Dtsec1588Isr(t_Handle h_Dtsec)
346 {
347     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
348     uint32_t            event;
349     struct dtsec_regs   *p_DtsecMemMap = p_Dtsec->p_MemMap;
350
351     if (p_Dtsec->ptpTsuEnabled)
352     {
353         event = fman_dtsec_check_and_clear_tmr_event(p_DtsecMemMap);
354
355         if (event)
356         {
357             ASSERT_COND(event & TMR_PEVENT_TSRE);
358             p_Dtsec->f_Exception(p_Dtsec->h_App, e_FM_MAC_EX_1G_1588_TS_RX_ERR);
359         }
360     }
361 }
362
363 /* ........................................................................... */
364
365 static void FreeInitResources(t_Dtsec *p_Dtsec)
366 {
367     if (p_Dtsec->mdioIrq != NO_IRQ)
368     {
369         XX_DisableIntr(p_Dtsec->mdioIrq);
370         XX_FreeIntr(p_Dtsec->mdioIrq);
371     }
372     FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_ERR);
373     FmUnregisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MOD_1G_MAC, p_Dtsec->macId, e_FM_INTR_TYPE_NORMAL);
374
375     /* release the driver's group hash table */
376     FreeHashTable(p_Dtsec->p_MulticastAddrHash);
377     p_Dtsec->p_MulticastAddrHash =   NULL;
378
379     /* release the driver's individual hash table */
380     FreeHashTable(p_Dtsec->p_UnicastAddrHash);
381     p_Dtsec->p_UnicastAddrHash =     NULL;
382 }
383
384 /* ........................................................................... */
385
386 static t_Error GracefulStop(t_Dtsec *p_Dtsec, e_CommMode mode)
387 {
388     struct dtsec_regs *p_MemMap;
389
390     ASSERT_COND(p_Dtsec);
391
392     p_MemMap = p_Dtsec->p_MemMap;
393     ASSERT_COND(p_MemMap);
394
395     /* Assert the graceful transmit stop bit */
396     if (mode & e_COMM_MODE_RX)
397     {
398         fman_dtsec_stop_rx(p_MemMap);
399
400 #ifdef FM_GRS_ERRATA_DTSEC_A002
401         if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
402             XX_UDelay(100);
403 #else  /* FM_GRS_ERRATA_DTSEC_A002 */
404 #ifdef FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839
405         XX_UDelay(10);
406 #endif /* FM_GTS_AFTER_DROPPED_FRAME_ERRATA_DTSEC_A004839 */
407 #endif /* FM_GRS_ERRATA_DTSEC_A002 */
408     }
409
410     if (mode & e_COMM_MODE_TX)
411 #if defined(FM_GTS_ERRATA_DTSEC_A004) || defined(FM_GTS_AFTER_MAC_ABORTED_FRAME_ERRATA_DTSEC_A0012)
412     if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
413         DBG(INFO, ("GTS not supported due to DTSEC_A004 errata."));
414 #else  /* not defined(FM_GTS_ERRATA_DTSEC_A004) ||... */
415 #ifdef FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014
416         DBG(INFO, ("GTS not supported due to DTSEC_A0014 errata."));
417 #else  /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
418         fman_dtsec_stop_tx(p_MemMap);
419 #endif /* FM_GTS_UNDERRUN_ERRATA_DTSEC_A0014 */
420 #endif /* defined(FM_GTS_ERRATA_DTSEC_A004) ||...  */
421
422     return E_OK;
423 }
424
425 /* .............................................................................. */
426
427 static t_Error GracefulRestart(t_Dtsec *p_Dtsec, e_CommMode mode)
428 {
429     struct dtsec_regs *p_MemMap;
430
431     ASSERT_COND(p_Dtsec);
432     p_MemMap = p_Dtsec->p_MemMap;
433     ASSERT_COND(p_MemMap);
434
435     /* clear the graceful receive stop bit */
436     if (mode & e_COMM_MODE_TX)
437         fman_dtsec_start_tx(p_MemMap);
438
439     if (mode & e_COMM_MODE_RX)
440         fman_dtsec_start_rx(p_MemMap);
441
442     return E_OK;
443 }
444
445
446 /*****************************************************************************/
447 /*                      dTSEC Configs modification functions                 */
448 /*****************************************************************************/
449
450 /* .............................................................................. */
451
452 static t_Error DtsecConfigLoopback(t_Handle h_Dtsec, bool newVal)
453 {
454
455     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
456
457     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
458     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
459
460     p_Dtsec->p_DtsecDriverParam->loopback = newVal;
461
462     return E_OK;
463 }
464
465 /* .............................................................................. */
466
467 static t_Error DtsecConfigMaxFrameLength(t_Handle h_Dtsec, uint16_t newVal)
468 {
469     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
470
471     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
472     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
473
474     p_Dtsec->p_DtsecDriverParam->maximum_frame = newVal;
475
476     return E_OK;
477 }
478
479 /* .............................................................................. */
480
481 static t_Error DtsecConfigPadAndCrc(t_Handle h_Dtsec, bool newVal)
482 {
483     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
484
485     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
486     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
487
488     p_Dtsec->p_DtsecDriverParam->tx_pad_crc = newVal;
489
490     return E_OK;
491 }
492
493 /* .............................................................................. */
494
495 static t_Error DtsecConfigHalfDuplex(t_Handle h_Dtsec, bool newVal)
496 {
497     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
498
499     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
500     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
501
502     p_Dtsec->p_DtsecDriverParam->halfdup_on = newVal;
503
504     return E_OK;
505 }
506
507 /* .............................................................................. */
508
509 static t_Error DtsecConfigTbiPhyAddr(t_Handle h_Dtsec, uint8_t newVal)
510 {
511     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
512
513     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
514     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
515
516     p_Dtsec->p_DtsecDriverParam->tbi_phy_addr = newVal;
517
518     return E_OK;
519 }
520
521 /* .............................................................................. */
522
523 static t_Error DtsecConfigLengthCheck(t_Handle h_Dtsec, bool newVal)
524 {
525     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
526
527     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
528     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
529
530     p_Dtsec->p_DtsecDriverParam->rx_len_check = newVal;
531
532     return E_OK;
533 }
534
535 /* .............................................................................. */
536
537 static t_Error DtsecConfigException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
538 {
539     t_Dtsec *p_Dtsec = (t_Dtsec *)h_Dtsec;
540     uint32_t    bitMask = 0;
541
542     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
543     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
544
545     if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
546     {
547         GET_EXCEPTION_FLAG(bitMask, exception);
548         if (bitMask)
549         {
550             if (enable)
551                 p_Dtsec->exceptions |= bitMask;
552             else
553                 p_Dtsec->exceptions &= ~bitMask;
554         }
555         else
556             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
557     }
558     else
559     {
560         if (!p_Dtsec->ptpTsuEnabled)
561             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
562
563         if (enable)
564             p_Dtsec->enTsuErrExeption = TRUE;
565         else
566             p_Dtsec->enTsuErrExeption = FALSE;
567     }
568
569     return E_OK;
570 }
571
572
573 /*****************************************************************************/
574 /*                      dTSEC Run Time API functions                         */
575 /*****************************************************************************/
576
577 /* .............................................................................. */
578
579 static t_Error DtsecEnable(t_Handle h_Dtsec,  e_CommMode mode)
580 {
581     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
582
583     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
584     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
585
586     fman_dtsec_enable(p_Dtsec->p_MemMap,
587                  (bool)!!(mode & e_COMM_MODE_RX),
588                  (bool)!!(mode & e_COMM_MODE_TX));
589
590     GracefulRestart(p_Dtsec, mode);
591
592     return E_OK;
593 }
594
595 /* .............................................................................. */
596
597 static t_Error DtsecDisable (t_Handle h_Dtsec, e_CommMode mode)
598 {
599     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
600
601     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
602     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
603
604     GracefulStop(p_Dtsec, mode);
605
606     fman_dtsec_disable(p_Dtsec->p_MemMap,
607                   (bool)!!(mode & e_COMM_MODE_RX),
608                   (bool)!!(mode & e_COMM_MODE_TX));
609
610     return E_OK;
611 }
612
613 /* .............................................................................. */
614
615 static t_Error DtsecSetTxPauseFrames(t_Handle h_Dtsec,
616                                      uint8_t  priority,
617                                      uint16_t pauseTime,
618                                      uint16_t threshTime)
619 {
620     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
621
622     UNUSED(priority);UNUSED(threshTime);
623
624     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
625     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
626
627 #ifdef FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003
628     if (p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev == 2)
629         if (0 < pauseTime && pauseTime <= 320)
630             RETURN_ERROR(MINOR, E_INVALID_VALUE,
631                      ("This pause-time value of %d is illegal due to errata dTSEC-A003!"
632                       " value should be greater than 320."));
633 #endif /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 */
634
635     fman_dtsec_set_tx_pause_frames(p_Dtsec->p_MemMap, pauseTime);
636     return E_OK;
637 }
638
639 /* .............................................................................. */
640 /* backward compatibility. will be removed in the future. */
641 static t_Error DtsecTxMacPause(t_Handle h_Dtsec, uint16_t pauseTime)
642 {
643     return DtsecSetTxPauseFrames(h_Dtsec, 0, pauseTime, 0);
644 }
645
646 /* .............................................................................. */
647
648 static t_Error DtsecRxIgnoreMacPause(t_Handle h_Dtsec, bool en)
649 {
650     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
651     bool            accept_pause = !en;
652
653     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
654     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
655
656     fman_dtsec_handle_rx_pause(p_Dtsec->p_MemMap, accept_pause);
657
658     return E_OK;
659 }
660
661 /* .............................................................................. */
662
663 static t_Error DtsecEnable1588TimeStamp(t_Handle h_Dtsec)
664 {
665     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
666
667     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
668     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
669
670     p_Dtsec->ptpTsuEnabled = TRUE;
671     fman_dtsec_set_ts(p_Dtsec->p_MemMap, TRUE);
672
673     return E_OK;
674 }
675
676 /* .............................................................................. */
677
678 static t_Error DtsecDisable1588TimeStamp(t_Handle h_Dtsec)
679 {
680     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
681
682     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
683     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
684
685     p_Dtsec->ptpTsuEnabled = FALSE;
686     fman_dtsec_set_ts(p_Dtsec->p_MemMap, FALSE);
687
688     return E_OK;
689 }
690
691 /* .............................................................................. */
692
693 static t_Error DtsecGetStatistics(t_Handle h_Dtsec, t_FmMacStatistics *p_Statistics)
694 {
695     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
696     struct dtsec_regs   *p_DtsecMemMap;
697
698     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
699     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
700     SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
701
702     p_DtsecMemMap = p_Dtsec->p_MemMap;
703
704     if (p_Dtsec->statisticsLevel == e_FM_MAC_NONE_STATISTICS)
705         RETURN_ERROR(MINOR, E_INVALID_STATE, ("Statistics disabled"));
706
707     memset(p_Statistics, 0xff, sizeof(t_FmMacStatistics));
708
709     if (p_Dtsec->statisticsLevel == e_FM_MAC_FULL_STATISTICS)
710     {
711         p_Statistics->eStatPkts64 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR64)
712                 + p_Dtsec->internalStatistics.tr64;
713         p_Statistics->eStatPkts65to127 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR127)
714                 + p_Dtsec->internalStatistics.tr127;
715         p_Statistics->eStatPkts128to255 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR255)
716                 + p_Dtsec->internalStatistics.tr255;
717         p_Statistics->eStatPkts256to511 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR511)
718                 + p_Dtsec->internalStatistics.tr511;
719         p_Statistics->eStatPkts512to1023 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TR1K)
720                 + p_Dtsec->internalStatistics.tr1k;
721         p_Statistics->eStatPkts1024to1518 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMAX)
722                 + p_Dtsec->internalStatistics.trmax;
723         p_Statistics->eStatPkts1519to1522 = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TRMGV)
724                 + p_Dtsec->internalStatistics.trmgv;
725
726         /* MIB II */
727         p_Statistics->ifInOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBYT)
728                 + p_Dtsec->internalStatistics.rbyt;
729         p_Statistics->ifInPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RPKT)
730                 + p_Dtsec->internalStatistics.rpkt;
731         p_Statistics->ifInUcastPkts = 0;
732         p_Statistics->ifInMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RMCA)
733                 + p_Dtsec->internalStatistics.rmca;
734         p_Statistics->ifInBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RBCA)
735                 + p_Dtsec->internalStatistics.rbca;
736         p_Statistics->ifOutOctets = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBYT)
737                 + p_Dtsec->internalStatistics.tbyt;
738         p_Statistics->ifOutPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TPKT)
739                 + p_Dtsec->internalStatistics.tpkt;
740         p_Statistics->ifOutUcastPkts = 0;
741         p_Statistics->ifOutMcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TMCA)
742                 + p_Dtsec->internalStatistics.tmca;
743         p_Statistics->ifOutBcastPkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TBCA)
744                 + p_Dtsec->internalStatistics.tbca;
745     }
746
747     p_Statistics->eStatFragments = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RFRG)
748             + p_Dtsec->internalStatistics.rfrg;
749     p_Statistics->eStatJabbers = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RJBR)
750             + p_Dtsec->internalStatistics.rjbr;
751     p_Statistics->eStatsDropEvents = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RDRP)
752             + p_Dtsec->internalStatistics.rdrp;
753     p_Statistics->eStatCRCAlignErrors = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RALN)
754             + p_Dtsec->internalStatistics.raln;
755     p_Statistics->eStatUndersizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RUND)
756             + p_Dtsec->internalStatistics.rund;
757     p_Statistics->eStatOversizePkts = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_ROVR)
758             + p_Dtsec->internalStatistics.rovr;
759     p_Statistics->reStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_RXPF)
760             + p_Dtsec->internalStatistics.rxpf;
761     p_Statistics->teStatPause = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TXPF)
762             + p_Dtsec->internalStatistics.txpf;
763     p_Statistics->ifInDiscards = p_Statistics->eStatsDropEvents;
764     p_Statistics->ifInErrors = p_Statistics->eStatsDropEvents + p_Statistics->eStatCRCAlignErrors
765             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RFLR) + p_Dtsec->internalStatistics.rflr
766             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCDE) + p_Dtsec->internalStatistics.rcde
767             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_RCSE) + p_Dtsec->internalStatistics.rcse;
768
769     p_Statistics->ifOutDiscards = fman_dtsec_get_stat_counter(p_DtsecMemMap, E_DTSEC_STAT_TDRP)
770             + p_Dtsec->internalStatistics.tdrp;
771     p_Statistics->ifOutErrors = p_Statistics->ifOutDiscards                                           /**< Number of frames transmitted with error: */
772             + fman_dtsec_get_stat_counter(p_DtsecMemMap,E_DTSEC_STAT_TFCS)
773             + p_Dtsec->internalStatistics.tfcs;
774
775     return E_OK;
776 }
777
778 /* .............................................................................. */
779
780 static t_Error DtsecModifyMacAddress (t_Handle h_Dtsec, t_EnetAddr *p_EnetAddr)
781 {
782     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
783
784     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
785     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
786
787     /* Initialize MAC Station Address registers (1 & 2)    */
788     /* Station address have to be swapped (big endian to little endian */
789     p_Dtsec->addr = ENET_ADDR_TO_UINT64(*p_EnetAddr);
790     fman_dtsec_set_mac_address(p_Dtsec->p_MemMap, (uint8_t *)(*p_EnetAddr));
791
792     return E_OK;
793 }
794
795 /* .............................................................................. */
796
797 static t_Error DtsecResetCounters (t_Handle h_Dtsec)
798 {
799     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
800
801     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
802     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
803
804     /* clear HW counters */
805     fman_dtsec_reset_stat(p_Dtsec->p_MemMap);
806
807     /* clear SW counters holding carries */
808     memset(&p_Dtsec->internalStatistics, 0, sizeof(t_InternalStatistics));
809
810     return E_OK;
811 }
812
813 /* .............................................................................. */
814
815 static t_Error DtsecAddExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
816 {
817     t_Dtsec   *p_Dtsec = (t_Dtsec *) h_Dtsec;
818     uint64_t  ethAddr;
819     uint8_t   paddrNum;
820
821     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
822     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
823
824     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
825
826     if (ethAddr & GROUP_ADDRESS)
827         /* Multicast address has no effect in PADDR */
828         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
829
830     /* Make sure no PADDR contains this address */
831     for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
832         if (p_Dtsec->indAddrRegUsed[paddrNum])
833             if (p_Dtsec->paddr[paddrNum] == ethAddr)
834                 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
835
836     /* Find first unused PADDR */
837     for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
838         if (!(p_Dtsec->indAddrRegUsed[paddrNum]))
839         {
840             /* mark this PADDR as used */
841             p_Dtsec->indAddrRegUsed[paddrNum] = TRUE;
842             /* store address */
843             p_Dtsec->paddr[paddrNum] = ethAddr;
844
845             /* put in hardware */
846             fman_dtsec_add_addr_in_paddr(p_Dtsec->p_MemMap, (uint64_t)PTR_TO_UINT(&ethAddr), paddrNum);
847             p_Dtsec->numOfIndAddrInRegs++;
848
849             return E_OK;
850         }
851
852     /* No free PADDR */
853     RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
854 }
855
856 /* .............................................................................. */
857
858 static t_Error DtsecDelExactMatchMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
859 {
860     t_Dtsec   *p_Dtsec = (t_Dtsec *) h_Dtsec;
861     uint64_t  ethAddr;
862     uint8_t   paddrNum;
863
864     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
865     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
866
867     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
868
869     /* Find used PADDR containing this address */
870     for (paddrNum = 0; paddrNum < DTSEC_NUM_OF_PADDRS; paddrNum++)
871     {
872         if ((p_Dtsec->indAddrRegUsed[paddrNum]) &&
873             (p_Dtsec->paddr[paddrNum] == ethAddr))
874         {
875             /* mark this PADDR as not used */
876             p_Dtsec->indAddrRegUsed[paddrNum] = FALSE;
877             /* clear in hardware */
878             fman_dtsec_clear_addr_in_paddr(p_Dtsec->p_MemMap, paddrNum);
879             p_Dtsec->numOfIndAddrInRegs--;
880
881             return E_OK;
882         }
883     }
884
885     RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
886 }
887
888 /* .............................................................................. */
889
890 static t_Error DtsecAddHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
891 {
892     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
893     t_EthHashEntry  *p_HashEntry;
894     uint64_t        ethAddr;
895     int32_t         bucket;
896     uint32_t        crc;
897     bool            mcast, ghtx;
898
899     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
900     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
901
902     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
903
904     ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
905     mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
906
907     if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
908         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
909
910     crc = GetMacAddrHashCode(ethAddr);
911
912     /* considering the 9 highest order bits in crc H[8:0]:
913      * if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
914      * and H[5:1] (next 5 bits) identify the hash bit
915      * if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
916      * and H[4:0] (next 5 bits) identify the hash bit.
917      *
918      * In bucket index output the low 5 bits identify the hash register bit,
919      * while the higher 4 bits identify the hash register
920      */
921
922     if (ghtx)
923         bucket = (int32_t)((crc >> 23) & 0x1ff);
924     else {
925         bucket = (int32_t)((crc >> 24) & 0xff);
926         /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
927         if (mcast)
928             bucket += 0x100;
929     }
930
931     fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, TRUE);
932
933     /* Create element to be added to the driver hash table */
934     p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
935     p_HashEntry->addr = ethAddr;
936     INIT_LIST(&p_HashEntry->node);
937
938     if (ethAddr & MAC_GROUP_ADDRESS)
939         /* Group Address */
940         NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]));
941     else
942         NCSW_LIST_AddToTail(&(p_HashEntry->node), &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]));
943
944     return E_OK;
945 }
946
947 /* .............................................................................. */
948
949 static t_Error DtsecDelHashMacAddress(t_Handle h_Dtsec, t_EnetAddr *p_EthAddr)
950 {
951     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
952     t_List          *p_Pos;
953     t_EthHashEntry  *p_HashEntry = NULL;
954     uint64_t        ethAddr;
955     int32_t         bucket;
956     uint32_t        crc;
957     bool            mcast, ghtx;
958
959     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
960     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
961
962     ethAddr = ENET_ADDR_TO_UINT64(*p_EthAddr);
963
964     ghtx = (bool)((fman_dtsec_get_rctrl(p_Dtsec->p_MemMap) & RCTRL_GHTX) ? TRUE : FALSE);
965     mcast = (bool)((ethAddr & MAC_GROUP_ADDRESS) ? TRUE : FALSE);
966
967     if (ghtx && !mcast) /* Cannot handle unicast mac addr when GHTX is on */
968         RETURN_ERROR(MAJOR, E_INVALID_STATE, ("Could not compute hash bucket"));
969
970     crc = GetMacAddrHashCode(ethAddr);
971
972     if (ghtx)
973         bucket = (int32_t)((crc >> 23) & 0x1ff);
974     else {
975         bucket = (int32_t)((crc >> 24) & 0xff);
976         /* if !ghtx and mcast the bit must be set in gaddr instead of igaddr. */
977         if (mcast)
978             bucket += 0x100;
979     }
980
981     if (ethAddr & MAC_GROUP_ADDRESS)
982     {
983         /* Group Address */
984         NCSW_LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
985         {
986             p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
987             if (p_HashEntry->addr == ethAddr)
988             {
989                 NCSW_LIST_DelAndInit(&p_HashEntry->node);
990                 XX_Free(p_HashEntry);
991                 break;
992             }
993         }
994         if (NCSW_LIST_IsEmpty(&p_Dtsec->p_MulticastAddrHash->p_Lsts[bucket]))
995             fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
996     }
997     else
998     {
999         /* Individual Address */
1000         NCSW_LIST_FOR_EACH(p_Pos, &(p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
1001         {
1002             p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
1003             if (p_HashEntry->addr == ethAddr)
1004             {
1005                 NCSW_LIST_DelAndInit(&p_HashEntry->node);
1006                 XX_Free(p_HashEntry);
1007                 break;
1008             }
1009         }
1010         if (NCSW_LIST_IsEmpty(&p_Dtsec->p_UnicastAddrHash->p_Lsts[bucket]))
1011             fman_dtsec_set_bucket(p_Dtsec->p_MemMap, bucket, FALSE);
1012     }
1013
1014     /* address does not exist */
1015     ASSERT_COND(p_HashEntry != NULL);
1016
1017     return E_OK;
1018 }
1019
1020 /* .............................................................................. */
1021
1022 static t_Error DtsecSetPromiscuous(t_Handle h_Dtsec, bool newVal)
1023 {
1024     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
1025
1026     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1027     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1028
1029     fman_dtsec_set_uc_promisc(p_Dtsec->p_MemMap, newVal);
1030     fman_dtsec_set_mc_promisc(p_Dtsec->p_MemMap, newVal);
1031
1032     return E_OK;
1033 }
1034
1035 /* .............................................................................. */
1036
1037 static t_Error DtsecSetStatistics(t_Handle h_Dtsec, e_FmMacStatisticsLevel statisticsLevel)
1038 {
1039     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
1040     t_Error     err;
1041
1042     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1043     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1044
1045     p_Dtsec->statisticsLevel = statisticsLevel;
1046
1047     err = (t_Error)fman_dtsec_set_stat_level(p_Dtsec->p_MemMap,
1048                                         (enum dtsec_stat_level)statisticsLevel);
1049     if (err != E_OK)
1050         return err;
1051
1052     switch (statisticsLevel)
1053     {
1054     case (e_FM_MAC_NONE_STATISTICS):
1055             p_Dtsec->exceptions &= ~DTSEC_IMASK_MSROEN;
1056             break;
1057     case (e_FM_MAC_PARTIAL_STATISTICS):
1058             p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
1059             break;
1060     case (e_FM_MAC_FULL_STATISTICS):
1061             p_Dtsec->exceptions |= DTSEC_IMASK_MSROEN;
1062             break;
1063         default:
1064             RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
1065     }
1066
1067     return E_OK;
1068 }
1069
1070 /* .............................................................................. */
1071
1072 static t_Error DtsecSetWakeOnLan(t_Handle h_Dtsec, bool en)
1073 {
1074     t_Dtsec         *p_Dtsec = (t_Dtsec *)h_Dtsec;
1075
1076     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_STATE);
1077     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1078
1079     fman_dtsec_set_wol(p_Dtsec->p_MemMap, en);
1080
1081     return E_OK;
1082 }
1083
1084 /* .............................................................................. */
1085
1086 static t_Error DtsecAdjustLink(t_Handle h_Dtsec, e_EnetSpeed speed, bool fullDuplex)
1087 {
1088     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
1089     int                 err;
1090     enum enet_interface enet_interface;
1091     enum enet_speed     enet_speed;
1092
1093     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1094     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1095
1096     p_Dtsec->enetMode = MAKE_ENET_MODE(ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode), speed);
1097     enet_interface = (enum enet_interface) ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
1098     enet_speed = (enum enet_speed) ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
1099     p_Dtsec->halfDuplex = !fullDuplex;
1100
1101     err = fman_dtsec_adjust_link(p_Dtsec->p_MemMap, enet_interface, enet_speed, fullDuplex);
1102
1103     if (err == -EINVAL)
1104         RETURN_ERROR(MAJOR, E_CONFLICT, ("Ethernet interface does not support Half Duplex mode"));
1105
1106     return (t_Error)err;
1107 }
1108
1109 /* .............................................................................. */
1110
1111 static t_Error DtsecRestartAutoneg(t_Handle h_Dtsec)
1112 {
1113     t_Dtsec      *p_Dtsec = (t_Dtsec *)h_Dtsec;
1114     uint16_t     tmpReg16;
1115
1116     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1117     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1118
1119     DTSEC_MII_ReadPhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, &tmpReg16);
1120
1121     tmpReg16 &= ~( PHY_CR_SPEED0 | PHY_CR_SPEED1 );
1122     tmpReg16 |= (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
1123
1124     DTSEC_MII_WritePhyReg(p_Dtsec, p_Dtsec->tbi_phy_addr, 0, tmpReg16);
1125
1126     return E_OK;
1127 }
1128
1129 /* .............................................................................. */
1130
1131 static t_Error DtsecGetId(t_Handle h_Dtsec, uint32_t *macId)
1132 {
1133     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
1134
1135     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1136     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1137
1138     *macId = p_Dtsec->macId;
1139
1140     return E_OK;
1141 }
1142
1143 /* .............................................................................. */
1144
1145 static t_Error DtsecGetVersion(t_Handle h_Dtsec, uint32_t *macVersion)
1146 {
1147     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
1148
1149     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1150     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1151
1152     *macVersion = fman_dtsec_get_revision(p_Dtsec->p_MemMap);
1153
1154     return E_OK;
1155 }
1156
1157 /* .............................................................................. */
1158
1159 static t_Error DtsecSetException(t_Handle h_Dtsec, e_FmMacExceptions exception, bool enable)
1160 {
1161     t_Dtsec     *p_Dtsec = (t_Dtsec *)h_Dtsec;
1162     uint32_t    bitMask = 0;
1163
1164     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1165     SANITY_CHECK_RETURN_ERROR(!p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1166
1167     if (exception != e_FM_MAC_EX_1G_1588_TS_RX_ERR)
1168     {
1169         GET_EXCEPTION_FLAG(bitMask, exception);
1170         if (bitMask)
1171         {
1172             if (enable)
1173                 p_Dtsec->exceptions |= bitMask;
1174             else
1175                 p_Dtsec->exceptions &= ~bitMask;
1176         }
1177         else
1178             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
1179
1180         if (enable)
1181             fman_dtsec_enable_interrupt(p_Dtsec->p_MemMap, bitMask);
1182         else
1183             fman_dtsec_disable_interrupt(p_Dtsec->p_MemMap, bitMask);
1184     }
1185     else
1186     {
1187         if (!p_Dtsec->ptpTsuEnabled)
1188             RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Exception valid for 1588 only"));
1189
1190         if (enable)
1191         {
1192             p_Dtsec->enTsuErrExeption = TRUE;
1193             fman_dtsec_enable_tmr_interrupt(p_Dtsec->p_MemMap);
1194         }
1195         else
1196         {
1197             p_Dtsec->enTsuErrExeption = FALSE;
1198             fman_dtsec_disable_tmr_interrupt(p_Dtsec->p_MemMap);
1199         }
1200     }
1201
1202     return E_OK;
1203 }
1204
1205
1206 /*****************************************************************************/
1207 /*                      dTSEC Init & Free API                                   */
1208 /*****************************************************************************/
1209
1210 /* .............................................................................. */
1211
1212 static t_Error DtsecInit(t_Handle h_Dtsec)
1213 {
1214     t_Dtsec             *p_Dtsec = (t_Dtsec *)h_Dtsec;
1215     struct dtsec_cfg    *p_DtsecDriverParam;
1216     t_Error             err;
1217     uint16_t            maxFrmLn;
1218     enum enet_interface enet_interface;
1219     enum enet_speed     enet_speed;
1220     t_EnetAddr          ethAddr;
1221
1222     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1223     SANITY_CHECK_RETURN_ERROR(p_Dtsec->p_DtsecDriverParam, E_INVALID_STATE);
1224     SANITY_CHECK_RETURN_ERROR(p_Dtsec->fmMacControllerDriver.h_Fm, E_INVALID_HANDLE);
1225
1226     FM_GetRevision(p_Dtsec->fmMacControllerDriver.h_Fm, &p_Dtsec->fmMacControllerDriver.fmRevInfo);
1227     CHECK_INIT_PARAMETERS(p_Dtsec, CheckInitParameters);
1228
1229     p_DtsecDriverParam  = p_Dtsec->p_DtsecDriverParam;
1230     p_Dtsec->halfDuplex = p_DtsecDriverParam->halfdup_on;
1231
1232     enet_interface = (enum enet_interface)ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode);
1233     enet_speed = (enum enet_speed)ENET_SPEED_FROM_MODE(p_Dtsec->enetMode);
1234     MAKE_ENET_ADDR_FROM_UINT64(p_Dtsec->addr, ethAddr);
1235
1236     err = (t_Error)fman_dtsec_init(p_Dtsec->p_MemMap,
1237                               p_DtsecDriverParam,
1238                               enet_interface,
1239                               enet_speed,
1240                               (uint8_t*)ethAddr,
1241                               p_Dtsec->fmMacControllerDriver.fmRevInfo.majorRev,
1242                               p_Dtsec->fmMacControllerDriver.fmRevInfo.minorRev,
1243                               p_Dtsec->exceptions);
1244     if (err)
1245     {
1246         FreeInitResources(p_Dtsec);
1247         RETURN_ERROR(MAJOR, err, ("This DTSEC version does not support the required i/f mode"));
1248     }
1249
1250     if (ENET_INTERFACE_FROM_MODE(p_Dtsec->enetMode) == e_ENET_IF_SGMII)
1251     {
1252         uint16_t            tmpReg16;
1253
1254         /* Configure the TBI PHY Control Register */
1255         tmpReg16 = PHY_TBICON_CLK_SEL | PHY_TBICON_SRESET;
1256         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
1257
1258         tmpReg16 = PHY_TBICON_CLK_SEL;
1259         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 17, tmpReg16);
1260
1261         tmpReg16 = (PHY_CR_PHY_RESET | PHY_CR_ANE | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
1262         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
1263
1264         if (p_Dtsec->enetMode & ENET_IF_SGMII_BASEX)
1265             tmpReg16 = PHY_TBIANA_1000X;
1266         else
1267             tmpReg16 = PHY_TBIANA_SGMII;
1268         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 4, tmpReg16);
1269
1270         tmpReg16 = (PHY_CR_ANE | PHY_CR_RESET_AN | PHY_CR_FULLDUPLEX | PHY_CR_SPEED1);
1271
1272         DTSEC_MII_WritePhyReg(p_Dtsec, (uint8_t)p_DtsecDriverParam->tbipa, 0, tmpReg16);
1273     }
1274
1275     /* Max Frame Length */
1276     maxFrmLn = fman_dtsec_get_max_frame_len(p_Dtsec->p_MemMap);
1277     err = FmSetMacMaxFrame(p_Dtsec->fmMacControllerDriver.h_Fm, e_FM_MAC_1G,
1278             p_Dtsec->fmMacControllerDriver.macId, maxFrmLn);
1279     if (err)
1280         RETURN_ERROR(MINOR,err, NO_MSG);
1281
1282     p_Dtsec->p_MulticastAddrHash = AllocHashTable(EXTENDED_HASH_TABLE_SIZE);
1283     if (!p_Dtsec->p_MulticastAddrHash) {
1284         FreeInitResources(p_Dtsec);
1285         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("MC hash table is FAILED"));
1286     }
1287
1288     p_Dtsec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
1289     if (!p_Dtsec->p_UnicastAddrHash)
1290     {
1291         FreeInitResources(p_Dtsec);
1292         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("UC hash table is FAILED"));
1293     }
1294
1295     /* register err intr handler for dtsec to FPM (err)*/
1296     FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
1297                    e_FM_MOD_1G_MAC,
1298                    p_Dtsec->macId,
1299                    e_FM_INTR_TYPE_ERR,
1300                    DtsecIsr,
1301                    p_Dtsec);
1302     /* register 1588 intr handler for TMR to FPM (normal)*/
1303     FmRegisterIntr(p_Dtsec->fmMacControllerDriver.h_Fm,
1304                    e_FM_MOD_1G_MAC,
1305                    p_Dtsec->macId,
1306                    e_FM_INTR_TYPE_NORMAL,
1307                    Dtsec1588Isr,
1308                    p_Dtsec);
1309     /* register normal intr handler for dtsec to main interrupt controller. */
1310     if (p_Dtsec->mdioIrq != NO_IRQ)
1311     {
1312         XX_SetIntr(p_Dtsec->mdioIrq, DtsecMdioIsr, p_Dtsec);
1313         XX_EnableIntr(p_Dtsec->mdioIrq);
1314     }
1315
1316     XX_Free(p_DtsecDriverParam);
1317     p_Dtsec->p_DtsecDriverParam = NULL;
1318
1319     err = DtsecSetStatistics(h_Dtsec, e_FM_MAC_FULL_STATISTICS);
1320     if (err)
1321     {
1322         FreeInitResources(p_Dtsec);
1323         RETURN_ERROR(MAJOR, err, ("Undefined statistics level"));
1324     }
1325
1326     return E_OK;
1327 }
1328
1329 /* ........................................................................... */
1330
1331 static t_Error DtsecFree(t_Handle h_Dtsec)
1332 {
1333     t_Dtsec      *p_Dtsec = (t_Dtsec *)h_Dtsec;
1334
1335     SANITY_CHECK_RETURN_ERROR(p_Dtsec, E_INVALID_HANDLE);
1336
1337     if (p_Dtsec->p_DtsecDriverParam)
1338     {
1339         /* Called after config */
1340         XX_Free(p_Dtsec->p_DtsecDriverParam);
1341         p_Dtsec->p_DtsecDriverParam = NULL;
1342     }
1343     else
1344         /* Called after init */
1345         FreeInitResources(p_Dtsec);
1346
1347     XX_Free(p_Dtsec);
1348
1349     return E_OK;
1350 }
1351
1352 /* .............................................................................. */
1353
1354 static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
1355 {
1356     p_FmMacControllerDriver->f_FM_MAC_Init                      = DtsecInit;
1357     p_FmMacControllerDriver->f_FM_MAC_Free                      = DtsecFree;
1358
1359     p_FmMacControllerDriver->f_FM_MAC_SetStatistics             = DtsecSetStatistics;
1360     p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback            = DtsecConfigLoopback;
1361     p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength      = DtsecConfigMaxFrameLength;
1362
1363     p_FmMacControllerDriver->f_FM_MAC_ConfigWan                 = NULL; /* Not supported on dTSEC */
1364
1365     p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc           = DtsecConfigPadAndCrc;
1366     p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex          = DtsecConfigHalfDuplex;
1367     p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck         = DtsecConfigLengthCheck;
1368     p_FmMacControllerDriver->f_FM_MAC_ConfigTbiPhyAddr          = DtsecConfigTbiPhyAddr;
1369     p_FmMacControllerDriver->f_FM_MAC_ConfigException           = DtsecConfigException;
1370     p_FmMacControllerDriver->f_FM_MAC_ConfigResetOnInit         = NULL;
1371
1372     p_FmMacControllerDriver->f_FM_MAC_Enable                    = DtsecEnable;
1373     p_FmMacControllerDriver->f_FM_MAC_Disable                   = DtsecDisable;
1374     p_FmMacControllerDriver->f_FM_MAC_Resume                    = NULL;
1375
1376     p_FmMacControllerDriver->f_FM_MAC_SetException              = DtsecSetException;
1377
1378     p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous            = DtsecSetPromiscuous;
1379     p_FmMacControllerDriver->f_FM_MAC_AdjustLink                = DtsecAdjustLink;
1380     p_FmMacControllerDriver->f_FM_MAC_SetWakeOnLan              = DtsecSetWakeOnLan;
1381     p_FmMacControllerDriver->f_FM_MAC_RestartAutoneg            = DtsecRestartAutoneg;
1382
1383     p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp       = DtsecEnable1588TimeStamp;
1384     p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp      = DtsecDisable1588TimeStamp;
1385
1386     p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames      = DtsecTxMacPause;
1387     p_FmMacControllerDriver->f_FM_MAC_SetTxPauseFrames          = DtsecSetTxPauseFrames;
1388     p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames    = DtsecRxIgnoreMacPause;
1389
1390     p_FmMacControllerDriver->f_FM_MAC_ResetCounters             = DtsecResetCounters;
1391     p_FmMacControllerDriver->f_FM_MAC_GetStatistics             = DtsecGetStatistics;
1392
1393     p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr             = DtsecModifyMacAddress;
1394     p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr            = DtsecAddHashMacAddress;
1395     p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr         = DtsecDelHashMacAddress;
1396     p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr      = DtsecAddExactMatchMacAddress;
1397     p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr  = DtsecDelExactMatchMacAddress;
1398     p_FmMacControllerDriver->f_FM_MAC_GetId                     = DtsecGetId;
1399     p_FmMacControllerDriver->f_FM_MAC_GetVersion                = DtsecGetVersion;
1400     p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength         = DtsecGetMaxFrameLength;
1401
1402     p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg           = DTSEC_MII_WritePhyReg;
1403     p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg            = DTSEC_MII_ReadPhyReg;
1404
1405 }
1406
1407
1408 /*****************************************************************************/
1409 /*                      dTSEC Config Main Entry                             */
1410 /*****************************************************************************/
1411
1412 /* .............................................................................. */
1413
1414 t_Handle  DTSEC_Config(t_FmMacParams *p_FmMacParam)
1415 {
1416     t_Dtsec             *p_Dtsec;
1417     struct dtsec_cfg    *p_DtsecDriverParam;
1418     uintptr_t           baseAddr;
1419
1420     SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
1421
1422     baseAddr = p_FmMacParam->baseAddr;
1423
1424     /* allocate memory for the UCC GETH data structure. */
1425     p_Dtsec = (t_Dtsec *)XX_Malloc(sizeof(t_Dtsec));
1426     if (!p_Dtsec)
1427     {
1428         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver structure"));
1429         return NULL;
1430     }
1431     memset(p_Dtsec, 0, sizeof(t_Dtsec));
1432     InitFmMacControllerDriver(&p_Dtsec->fmMacControllerDriver);
1433
1434     /* allocate memory for the dTSEC driver parameters data structure. */
1435     p_DtsecDriverParam = (struct dtsec_cfg *) XX_Malloc(sizeof(struct dtsec_cfg));
1436     if (!p_DtsecDriverParam)
1437     {
1438         XX_Free(p_Dtsec);
1439         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("dTSEC driver parameters"));
1440         return NULL;
1441     }
1442     memset(p_DtsecDriverParam, 0, sizeof(struct dtsec_cfg));
1443
1444     /* Plant parameter structure pointer */
1445     p_Dtsec->p_DtsecDriverParam = p_DtsecDriverParam;
1446
1447     fman_dtsec_defconfig(p_DtsecDriverParam);
1448
1449     p_Dtsec->p_MemMap           = (struct dtsec_regs *)UINT_TO_PTR(baseAddr);
1450     p_Dtsec->p_MiiMemMap        = (struct dtsec_mii_reg *)UINT_TO_PTR(baseAddr + DTSEC_TO_MII_OFFSET);
1451     p_Dtsec->addr               = ENET_ADDR_TO_UINT64(p_FmMacParam->addr);
1452     p_Dtsec->enetMode           = p_FmMacParam->enetMode;
1453     p_Dtsec->macId              = p_FmMacParam->macId;
1454     p_Dtsec->exceptions         = DEFAULT_exceptions;
1455     p_Dtsec->mdioIrq            = p_FmMacParam->mdioIrq;
1456     p_Dtsec->f_Exception        = p_FmMacParam->f_Exception;
1457     p_Dtsec->f_Event            = p_FmMacParam->f_Event;
1458     p_Dtsec->h_App              = p_FmMacParam->h_App;
1459     p_Dtsec->ptpTsuEnabled      = p_Dtsec->p_DtsecDriverParam->ptp_tsu_en;
1460     p_Dtsec->enTsuErrExeption   = p_Dtsec->p_DtsecDriverParam->ptp_exception_en;
1461     p_Dtsec->tbi_phy_addr       = p_Dtsec->p_DtsecDriverParam->tbi_phy_addr;
1462
1463     return p_Dtsec;
1464 }