xref: /freebsd/sys/contrib/ncsw/Peripherals/FM/MAC/tgec.c (revision d6b92ffa)
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          tgec.c
35 
36  @Description   FM 10G MAC ...
37 *//***************************************************************************/
38 
39 #include "std_ext.h"
40 #include "string_ext.h"
41 #include "error_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 "tgec.h"
49 
50 
51 /*****************************************************************************/
52 /*                      Internal routines                                    */
53 /*****************************************************************************/
54 
55 static t_Error CheckInitParameters(t_Tgec    *p_Tgec)
56 {
57     if(ENET_SPEED_FROM_MODE(p_Tgec->enetMode) < e_ENET_SPEED_10000)
58         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC driver only support 10G speed"));
59 #if (FM_MAX_NUM_OF_10G_MACS > 0)
60     if(p_Tgec->macId >= FM_MAX_NUM_OF_10G_MACS)
61         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("macId of 10G can not be greater than 0"));
62 #endif
63     if(p_Tgec->addr == 0)
64         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Ethernet 10G MAC Must have a valid MAC Address"));
65     if(!p_Tgec->f_Exception)
66         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Exception"));
67     if(!p_Tgec->f_Event)
68         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("uninitialized f_Event"));
69     return E_OK;
70 }
71 
72 /* .............................................................................. */
73 
74 static void SetDefaultParam(t_TgecDriverParam *p_TgecDriverParam)
75 {
76     p_TgecDriverParam->wanModeEnable            = DEFAULT_wanModeEnable;
77     p_TgecDriverParam->promiscuousModeEnable    = DEFAULT_promiscuousModeEnable;
78     p_TgecDriverParam->pauseForwardEnable       = DEFAULT_pauseForwardEnable;
79     p_TgecDriverParam->pauseIgnore              = DEFAULT_pauseIgnore;
80     p_TgecDriverParam->txAddrInsEnable          = DEFAULT_txAddrInsEnable;
81 
82     p_TgecDriverParam->loopbackEnable           = DEFAULT_loopbackEnable;
83     p_TgecDriverParam->cmdFrameEnable           = DEFAULT_cmdFrameEnable;
84     p_TgecDriverParam->rxErrorDiscard           = DEFAULT_rxErrorDiscard;
85     p_TgecDriverParam->phyTxenaOn               = DEFAULT_phyTxenaOn;
86     p_TgecDriverParam->sendIdleEnable           = DEFAULT_sendIdleEnable;
87     p_TgecDriverParam->noLengthCheckEnable      = DEFAULT_noLengthCheckEnable;
88     p_TgecDriverParam->lgthCheckNostdr          = DEFAULT_lgthCheckNostdr;
89     p_TgecDriverParam->timeStampEnable          = DEFAULT_timeStampEnable;
90     p_TgecDriverParam->rxSfdAny                 = DEFAULT_rxSfdAny;
91     p_TgecDriverParam->rxPblFwd                 = DEFAULT_rxPblFwd;
92     p_TgecDriverParam->txPblFwd                 = DEFAULT_txPblFwd;
93 
94     p_TgecDriverParam->txIpgLength              = DEFAULT_txIpgLength;
95     p_TgecDriverParam->maxFrameLength           = DEFAULT_maxFrameLength;
96 
97     p_TgecDriverParam->debugMode                = DEFAULT_debugMode;
98 
99     p_TgecDriverParam->pauseTime                = DEFAULT_pauseTime;
100 
101 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
102     p_TgecDriverParam->skipFman11Workaround     = DEFAULT_skipFman11Workaround;
103 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
104 }
105 
106 /* ........................................................................... */
107 
108 static void TgecErrException(t_Handle h_Tgec)
109 {
110     t_Tgec             *p_Tgec = (t_Tgec *)h_Tgec;
111     uint32_t            event;
112     t_TgecMemMap        *p_TgecMemMap = p_Tgec->p_MemMap;
113 
114     event = GET_UINT32(p_TgecMemMap->ievent);
115     /* do not handle MDIO events */
116     event &= ~(IMASK_MDIO_SCAN_EVENTMDIO | IMASK_MDIO_CMD_CMPL);
117 
118     event &= GET_UINT32(p_TgecMemMap->imask);
119 
120     WRITE_UINT32(p_TgecMemMap->ievent, event);
121 
122     if (event & IMASK_REM_FAULT)
123         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_REM_FAULT);
124     if (event & IMASK_LOC_FAULT)
125         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_LOC_FAULT);
126     if (event & IMASK_1TX_ECC_ER)
127         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_1TX_ECC_ER);
128     if (event & IMASK_TX_FIFO_UNFL)
129         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_UNFL);
130     if (event & IMASK_TX_FIFO_OVFL)
131         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_FIFO_OVFL);
132     if (event & IMASK_TX_ER)
133         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_TX_ER);
134     if (event & IMASK_RX_FIFO_OVFL)
135         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FIFO_OVFL);
136     if (event & IMASK_RX_ECC_ER)
137         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ECC_ER);
138     if (event & IMASK_RX_JAB_FRM)
139         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_JAB_FRM);
140     if (event & IMASK_RX_OVRSZ_FRM)
141         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_OVRSZ_FRM);
142     if (event & IMASK_RX_RUNT_FRM)
143         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_RUNT_FRM);
144     if (event & IMASK_RX_FRAG_FRM)
145         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_FRAG_FRM);
146     if (event & IMASK_RX_LEN_ER)
147         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_LEN_ER);
148     if (event & IMASK_RX_CRC_ER)
149         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_CRC_ER);
150     if (event & IMASK_RX_ALIGN_ER)
151         p_Tgec->f_Exception(p_Tgec->h_App, e_FM_MAC_EX_10G_RX_ALIGN_ER);
152 }
153 
154 static void TgecException(t_Handle h_Tgec)
155 {
156      t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
157      uint32_t            event;
158      t_TgecMemMap        *p_TgecMemMap = p_Tgec->p_MemMap;
159 
160      event = GET_UINT32(p_TgecMemMap->ievent);
161      /* handle only MDIO events */
162      event &= (IMASK_MDIO_SCAN_EVENTMDIO | IMASK_MDIO_CMD_CMPL);
163      event &= GET_UINT32(p_TgecMemMap->imask);
164 
165      WRITE_UINT32(p_TgecMemMap->ievent, event);
166 
167      if(event & IMASK_MDIO_SCAN_EVENTMDIO)
168          p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_SCAN_EVENTMDIO);
169      if(event & IMASK_MDIO_CMD_CMPL)
170          p_Tgec->f_Event(p_Tgec->h_App, e_FM_MAC_EX_10G_MDIO_CMD_CMPL);
171 }
172 
173 static void FreeInitResources(t_Tgec *p_Tgec)
174 {
175     if ((p_Tgec->mdioIrq != 0) && (p_Tgec->mdioIrq != NO_IRQ))
176     {
177         XX_DisableIntr(p_Tgec->mdioIrq);
178         XX_FreeIntr(p_Tgec->mdioIrq);
179     }
180     else if (p_Tgec->mdioIrq == 0)
181         REPORT_ERROR(MINOR, E_NOT_SUPPORTED, (NO_MSG));
182     FmUnregisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR);
183 
184     /* release the driver's group hash table */
185     FreeHashTable(p_Tgec->p_MulticastAddrHash);
186     p_Tgec->p_MulticastAddrHash =   NULL;
187 
188     /* release the driver's individual hash table */
189     FreeHashTable(p_Tgec->p_UnicastAddrHash);
190     p_Tgec->p_UnicastAddrHash =     NULL;
191 }
192 
193 /* .............................................................................. */
194 
195 static void HardwareClearAddrInPaddr(t_Tgec   *p_Tgec, uint8_t paddrNum)
196 {
197     if (paddrNum != 0)
198         return;             /* At this time MAC has only one address */
199 
200     WRITE_UINT32(p_Tgec->p_MemMap->mac_addr_2, 0x0);
201     WRITE_UINT32(p_Tgec->p_MemMap->mac_addr_3, 0x0);
202 }
203 
204 /* ........................................................................... */
205 
206 static void HardwareAddAddrInPaddr(t_Tgec   *p_Tgec, uint64_t *p_Addr, uint8_t paddrNum)
207 {
208     uint32_t        tmpReg32 = 0;
209     uint64_t        addr = *p_Addr;
210     t_TgecMemMap    *p_TgecMemMap = p_Tgec->p_MemMap;
211 
212     if (paddrNum != 0)
213         return;             /* At this time MAC has only one address */
214 
215     tmpReg32 = (uint32_t)(addr>>16);
216     SwapUint32P(&tmpReg32);
217     WRITE_UINT32(p_TgecMemMap->mac_addr_2, tmpReg32);
218 
219     tmpReg32 = (uint32_t)(addr);
220     SwapUint32P(&tmpReg32);
221     tmpReg32 >>= 16;
222     WRITE_UINT32(p_TgecMemMap->mac_addr_3, tmpReg32);
223 }
224 
225 /*****************************************************************************/
226 /*                     10G MAC API routines                                  */
227 /*****************************************************************************/
228 
229 /* .............................................................................. */
230 
231 static t_Error TgecEnable(t_Handle h_Tgec,  e_CommMode mode)
232 {
233     t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
234     t_TgecMemMap       *p_MemMap ;
235     uint32_t            tmpReg32 = 0;
236 
237     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
238     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
239 
240     p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap);
241 
242     tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
243 
244     switch (mode)
245     {
246         case e_COMM_MODE_NONE:
247             tmpReg32 &= ~(CMD_CFG_TX_EN | CMD_CFG_RX_EN);
248             break;
249         case e_COMM_MODE_RX :
250             tmpReg32 |= CMD_CFG_RX_EN ;
251             break;
252         case e_COMM_MODE_TX :
253             tmpReg32 |= CMD_CFG_TX_EN ;
254             break;
255         case e_COMM_MODE_RX_AND_TX:
256             tmpReg32 |= (CMD_CFG_TX_EN | CMD_CFG_RX_EN);
257             break;
258     }
259 
260     WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
261 
262     return E_OK;
263 }
264 
265 /* .............................................................................. */
266 
267 static t_Error TgecDisable (t_Handle h_Tgec, e_CommMode mode)
268 {
269     t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
270     t_TgecMemMap       *p_MemMap ;
271     uint32_t            tmpReg32 = 0;
272 
273     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
274     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
275 
276     p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap);
277 
278     tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
279     switch (mode)
280     {
281         case e_COMM_MODE_RX:
282             tmpReg32 &= ~CMD_CFG_RX_EN;
283             break;
284         case e_COMM_MODE_TX:
285             tmpReg32 &= ~CMD_CFG_TX_EN;
286             break;
287         case e_COMM_MODE_RX_AND_TX:
288             tmpReg32 &= ~(CMD_CFG_TX_EN | CMD_CFG_RX_EN);
289         break;
290         default:
291             RETURN_ERROR(MINOR, E_INVALID_SELECTION, NO_MSG);
292     }
293     WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
294 
295     return E_OK;
296 }
297 
298 /* .............................................................................. */
299 
300 static t_Error TgecSetPromiscuous(t_Handle h_Tgec, bool newVal)
301 {
302     t_Tgec       *p_Tgec = (t_Tgec *)h_Tgec;
303     t_TgecMemMap *p_TgecMemMap;
304     uint32_t     tmpReg32;
305 
306     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
307     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
308     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
309 
310     p_TgecMemMap = p_Tgec->p_MemMap;
311 
312     tmpReg32 = GET_UINT32(p_TgecMemMap->cmd_conf_ctrl);
313 
314     if (newVal)
315         tmpReg32 |= CMD_CFG_PROMIS_EN;
316     else
317         tmpReg32 &= ~CMD_CFG_PROMIS_EN;
318 
319     WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, tmpReg32);
320 
321     return E_OK;
322 }
323 
324 
325 /*****************************************************************************/
326 /*                      Tgec Configs modification functions                 */
327 /*****************************************************************************/
328 
329 /* .............................................................................. */
330 
331 static t_Error TgecConfigLoopback(t_Handle h_Tgec, bool newVal)
332 {
333     t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
334 
335     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
336     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
337 
338 #ifdef FM_NO_TGEC_LOOPBACK
339     {
340         t_FmRevisionInfo revInfo;
341         FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
342         if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
343             RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("no loopback in this chip rev!"));
344     }
345 #endif /* FM_NO_TGEC_LOOPBACK */
346 
347     p_Tgec->p_TgecDriverParam->loopbackEnable = newVal;
348 
349     return E_OK;
350 }
351 
352 /* .............................................................................. */
353 
354 static t_Error TgecConfigWan(t_Handle h_Tgec, bool newVal)
355 {
356     t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
357 
358     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
359     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
360 
361     p_Tgec->p_TgecDriverParam->wanModeEnable = newVal;
362 
363     return E_OK;
364 }
365 
366 /* .............................................................................. */
367 
368 static t_Error TgecConfigMaxFrameLength(t_Handle h_Tgec, uint16_t newVal)
369 {
370     t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
371 
372     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
373     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
374 
375     p_Tgec->p_TgecDriverParam->maxFrameLength = newVal;
376 
377     return E_OK;
378 }
379 
380 /* .............................................................................. */
381 
382 static t_Error TgecConfigLengthCheck(t_Handle h_Tgec, bool newVal)
383 {
384 #ifdef FM_LEN_CHECK_ERRATA_FMAN_SW002
385 UNUSED(h_Tgec);
386     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("LengthCheck!"));
387 
388 #else
389     t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
390 
391     UNUSED(newVal);
392 
393     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
394     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
395 
396     p_Tgec->p_TgecDriverParam->noLengthCheckEnable = !newVal;
397 
398     return E_OK;
399 #endif /* FM_LEN_CHECK_ERRATA_FMAN_SW002 */
400 }
401 
402 /* .............................................................................. */
403 
404 static t_Error TgecConfigException(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
405 {
406     t_Tgec      *p_Tgec = (t_Tgec *)h_Tgec;
407     uint32_t    bitMask = 0;
408 
409     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
410     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
411 #ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
412     {
413         t_FmRevisionInfo revInfo;
414         FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
415         if((revInfo.majorRev <=2) &&
416             enable &&
417             ((exception == e_FM_MAC_EX_10G_LOC_FAULT) || (exception == e_FM_MAC_EX_10G_REM_FAULT)))
418                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_MAC_EX_10G_LOC_FAULT and e_FM_MAC_EX_10G_REM_FAULT !"));
419     }
420 #endif   /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */
421 
422     GET_EXCEPTION_FLAG(bitMask, exception);
423     if(bitMask)
424     {
425         if (enable)
426             p_Tgec->exceptions |= bitMask;
427         else
428             p_Tgec->exceptions &= ~bitMask;
429     }
430     else
431         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
432 
433     return E_OK;
434 }
435 
436 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
437 /* .............................................................................. */
438 
439 static t_Error TgecConfigSkipFman11Workaround(t_Handle h_Tgec)
440 {
441     t_Tgec      *p_Tgec = (t_Tgec *)h_Tgec;
442 
443     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
444     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
445 
446     p_Tgec->p_TgecDriverParam->skipFman11Workaround     = TRUE;
447 
448     return E_OK;
449 }
450 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
451 
452 
453 /*****************************************************************************/
454 /*                      Tgec Run Time API functions                         */
455 /*****************************************************************************/
456 
457 /* .............................................................................. */
458 
459 static t_Error TgecTxMacPause(t_Handle h_Tgec, uint16_t pauseTime)
460 {
461     t_Tgec          *p_Tgec = (t_Tgec *)h_Tgec;
462     uint32_t        ptv = 0;
463     t_TgecMemMap    *p_MemMap;
464 
465     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
466     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
467     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_STATE);
468 
469     p_MemMap = (t_TgecMemMap*)(p_Tgec->p_MemMap);
470 
471     ptv = (uint32_t)pauseTime;
472 
473     WRITE_UINT32(p_MemMap->pause_quant, ptv);
474 
475     return E_OK;
476 }
477 
478 /* .............................................................................. */
479 
480 static t_Error TgecRxIgnoreMacPause(t_Handle h_Tgec, bool en)
481 {
482     t_Tgec          *p_Tgec = (t_Tgec *)h_Tgec;
483     t_TgecMemMap    *p_MemMap;
484     uint32_t        tmpReg32;
485 
486     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_STATE);
487     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
488     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_STATE);
489 
490     p_MemMap = (t_TgecMemMap*)(p_Tgec->p_MemMap);
491     tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
492     if (en)
493         tmpReg32 |= CMD_CFG_PAUSE_IGNORE;
494     else
495         tmpReg32 &= ~CMD_CFG_PAUSE_IGNORE;
496     WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
497 
498     return E_OK;
499 }
500 
501 /* Counters handling */
502 /* .............................................................................. */
503 
504 static t_Error TgecGetStatistics(t_Handle h_Tgec, t_FmMacStatistics *p_Statistics)
505 {
506     t_Tgec          *p_Tgec = (t_Tgec *)h_Tgec;
507     t_TgecMemMap    *p_TgecMemMap;
508 
509     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
510     SANITY_CHECK_RETURN_ERROR(p_Statistics, E_NULL_POINTER);
511     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
512 
513     p_TgecMemMap = p_Tgec->p_MemMap;
514 
515     p_Statistics->eStatPkts64           = GET_UINT64(p_TgecMemMap->R64);
516     p_Statistics->eStatPkts65to127      = GET_UINT64(p_TgecMemMap->R127);
517     p_Statistics->eStatPkts128to255     = GET_UINT64(p_TgecMemMap->R255);
518     p_Statistics->eStatPkts256to511     = GET_UINT64(p_TgecMemMap->R511);
519     p_Statistics->eStatPkts512to1023    = GET_UINT64(p_TgecMemMap->R1023);
520     p_Statistics->eStatPkts1024to1518   = GET_UINT64(p_TgecMemMap->R1518);
521     p_Statistics->eStatPkts1519to1522   = GET_UINT64(p_TgecMemMap->R1519X);
522 /* */
523     p_Statistics->eStatFragments        = GET_UINT64(p_TgecMemMap->TRFRG);
524     p_Statistics->eStatJabbers          = GET_UINT64(p_TgecMemMap->TRJBR);
525 
526     p_Statistics->eStatsDropEvents      = GET_UINT64(p_TgecMemMap->RDRP);
527     p_Statistics->eStatCRCAlignErrors   = GET_UINT64(p_TgecMemMap->RALN);
528 
529     p_Statistics->eStatUndersizePkts    = GET_UINT64(p_TgecMemMap->TRUND);
530     p_Statistics->eStatOversizePkts     = GET_UINT64(p_TgecMemMap->TROVR);
531 /* Pause */
532     p_Statistics->reStatPause           = GET_UINT64(p_TgecMemMap->RXPF);
533     p_Statistics->teStatPause           = GET_UINT64(p_TgecMemMap->TXPF);
534 
535 
536 /* MIB II */
537     p_Statistics->ifInOctets            = GET_UINT64(p_TgecMemMap->ROCT);
538     p_Statistics->ifInMcastPkts         = GET_UINT64(p_TgecMemMap->RMCA);
539     p_Statistics->ifInBcastPkts         = GET_UINT64(p_TgecMemMap->RBCA);
540     p_Statistics->ifInPkts              = GET_UINT64(p_TgecMemMap->RUCA)
541                                         + p_Statistics->ifInMcastPkts
542                                         + p_Statistics->ifInBcastPkts;
543     p_Statistics->ifInDiscards          = 0;
544     p_Statistics->ifInErrors            = GET_UINT64(p_TgecMemMap->RERR);
545 
546     p_Statistics->ifOutOctets           = GET_UINT64(p_TgecMemMap->TOCT);
547     p_Statistics->ifOutMcastPkts        = GET_UINT64(p_TgecMemMap->TMCA);
548     p_Statistics->ifOutBcastPkts        = GET_UINT64(p_TgecMemMap->TBCA);
549     p_Statistics->ifOutPkts             = GET_UINT64(p_TgecMemMap->TUCA);
550     p_Statistics->ifOutDiscards         = 0;
551     p_Statistics->ifOutErrors           = GET_UINT64(p_TgecMemMap->TERR);
552 
553     return E_OK;
554 }
555 
556 /* .............................................................................. */
557 
558 static t_Error TgecEnable1588TimeStamp(t_Handle h_Tgec)
559 {
560     t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
561     t_TgecMemMap        *p_TgecMemMap;
562 
563     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
564     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
565 
566     p_TgecMemMap = p_Tgec->p_MemMap;
567     SANITY_CHECK_RETURN_ERROR(p_TgecMemMap, E_INVALID_HANDLE);
568 
569     WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, GET_UINT32(p_TgecMemMap->cmd_conf_ctrl) | CMD_CFG_EN_TIMESTAMP);
570 
571     return E_OK;
572 }
573 
574 /* .............................................................................. */
575 
576 static t_Error TgecDisable1588TimeStamp(t_Handle h_Tgec)
577 {
578     t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
579     t_TgecMemMap        *p_TgecMemMap;
580 
581     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
582     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
583 
584     p_TgecMemMap = p_Tgec->p_MemMap;
585     SANITY_CHECK_RETURN_ERROR(p_TgecMemMap, E_INVALID_HANDLE);
586 
587     WRITE_UINT32(p_TgecMemMap->cmd_conf_ctrl, GET_UINT32(p_TgecMemMap->cmd_conf_ctrl) & ~CMD_CFG_EN_TIMESTAMP);
588 
589     return E_OK;
590 }
591 
592 /* .............................................................................. */
593 
594 static t_Error TgecModifyMacAddress (t_Handle h_Tgec, t_EnetAddr *p_EnetAddr)
595 {
596     t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
597     t_TgecMemMap        *p_TgecMemMap;
598     uint32_t            tmpReg32 = 0;
599     uint64_t            addr;
600 
601     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
602     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
603 
604     p_TgecMemMap = p_Tgec->p_MemMap;
605 
606     /*  Initialize MAC Station Address registers (1 & 2)    */
607     /*  Station address have to be swapped (big endian to little endian */
608 
609     addr = ((*(uint64_t *)p_EnetAddr) >> 16);
610     p_Tgec->addr = addr;
611 
612     tmpReg32 = (uint32_t)(addr>>16);
613     SwapUint32P(&tmpReg32);
614     WRITE_UINT32(p_TgecMemMap->mac_addr_0, tmpReg32);
615 
616     tmpReg32 = (uint32_t)(addr);
617     SwapUint32P(&tmpReg32);
618     tmpReg32 >>= 16;
619     WRITE_UINT32(p_TgecMemMap->mac_addr_1, tmpReg32);
620 
621     return E_OK;
622 }
623 
624 /* .............................................................................. */
625 
626 static t_Error TgecResetCounters (t_Handle h_Tgec)
627 {
628     t_Tgec *p_Tgec = (t_Tgec *)h_Tgec;
629     t_TgecMemMap       *p_MemMap ;
630     uint32_t            tmpReg32, cmdConfCtrl;
631     int i;
632 
633     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
634     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
635 
636     p_MemMap= (t_TgecMemMap*)(p_Tgec->p_MemMap);
637 
638     cmdConfCtrl = GET_UINT32(p_MemMap->cmd_conf_ctrl);
639 
640     cmdConfCtrl |= CMD_CFG_STAT_CLR;
641 
642     WRITE_UINT32(p_MemMap->cmd_conf_ctrl, cmdConfCtrl);
643 
644     for (i=0; i<1000; i++)
645     {
646         tmpReg32 = GET_UINT32(p_MemMap->cmd_conf_ctrl);
647         if (!(tmpReg32 & CMD_CFG_STAT_CLR))
648             break;
649     }
650 
651     cmdConfCtrl &= ~CMD_CFG_STAT_CLR;
652     WRITE_UINT32(p_MemMap->cmd_conf_ctrl, cmdConfCtrl);
653 
654     return E_OK;
655 }
656 
657 /* .............................................................................. */
658 
659 static t_Error TgecAddExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
660 {
661     t_Tgec   *p_Tgec = (t_Tgec *) h_Tgec;
662     uint64_t  ethAddr;
663     uint8_t   paddrNum;
664 
665     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
666 
667     ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
668 
669     if (ethAddr & GROUP_ADDRESS)
670         /* Multicast address has no effect in PADDR */
671         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Multicast address"));
672 
673     /* Make sure no PADDR contains this address */
674     for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
675     {
676         if (p_Tgec->indAddrRegUsed[paddrNum])
677         {
678             if (p_Tgec->paddr[paddrNum] == ethAddr)
679             {
680                 RETURN_ERROR(MAJOR, E_ALREADY_EXISTS, NO_MSG);
681             }
682         }
683     }
684 
685     /* Find first unused PADDR */
686     for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
687     {
688         if (!(p_Tgec->indAddrRegUsed[paddrNum]))
689         {
690             /* mark this PADDR as used */
691             p_Tgec->indAddrRegUsed[paddrNum] = TRUE;
692             /* store address */
693             p_Tgec->paddr[paddrNum] = ethAddr;
694 
695             /* put in hardware */
696             HardwareAddAddrInPaddr(p_Tgec, &ethAddr, paddrNum);
697             p_Tgec->numOfIndAddrInRegs++;
698 
699             return E_OK;
700         }
701     }
702 
703     /* No free PADDR */
704     RETURN_ERROR(MAJOR, E_FULL, NO_MSG);
705 }
706 
707 /* .............................................................................. */
708 
709 static t_Error TgecDelExactMatchMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
710 {
711     t_Tgec   *p_Tgec = (t_Tgec *) h_Tgec;
712     uint64_t  ethAddr;
713     uint8_t   paddrNum;
714 
715     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
716     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
717 
718     ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
719 
720     /* Find used PADDR containing this address */
721     for (paddrNum = 0; paddrNum < TGEC_NUM_OF_PADDRS; paddrNum++)
722     {
723         if ((p_Tgec->indAddrRegUsed[paddrNum]) &&
724             (p_Tgec->paddr[paddrNum] == ethAddr))
725         {
726             /* mark this PADDR as not used */
727             p_Tgec->indAddrRegUsed[paddrNum] = FALSE;
728             /* clear in hardware */
729             HardwareClearAddrInPaddr(p_Tgec, paddrNum);
730             p_Tgec->numOfIndAddrInRegs--;
731 
732             return E_OK;
733         }
734     }
735 
736     RETURN_ERROR(MAJOR, E_NOT_FOUND, NO_MSG);
737 }
738 
739 /* .............................................................................. */
740 
741 static t_Error TgecAddHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
742 {
743     t_Tgec          *p_Tgec = (t_Tgec *)h_Tgec;
744     t_TgecMemMap    *p_TgecMemMap;
745     t_EthHashEntry  *p_HashEntry;
746     uint32_t        crc;
747     uint32_t        hash;
748     uint64_t        ethAddr;
749 
750     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
751     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
752 
753     p_TgecMemMap = p_Tgec->p_MemMap;
754     ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
755 
756     if (!(ethAddr & GROUP_ADDRESS))
757         /* Unicast addresses not supported in hash */
758         RETURN_ERROR(MAJOR, E_NOT_SUPPORTED, ("Unicast Address"));
759 
760     /* CRC calculation */
761     GET_MAC_ADDR_CRC(ethAddr, crc);
762     crc = MIRROR_32(crc);
763 
764     hash = (crc >> HASH_CTRL_MCAST_SHIFT) & HASH_ADDR_MASK;        /* Take 9 MSB bits */
765 
766     /* Create element to be added to the driver hash table */
767     p_HashEntry = (t_EthHashEntry *)XX_Malloc(sizeof(t_EthHashEntry));
768     p_HashEntry->addr = ethAddr;
769     INIT_LIST(&p_HashEntry->node);
770 
771     LIST_AddToTail(&(p_HashEntry->node), &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]));
772     WRITE_UINT32(p_TgecMemMap->hashtable_ctrl, (hash | HASH_CTRL_MCAST_EN));
773 
774     return E_OK;
775 }
776 
777 /* .............................................................................. */
778 
779 static t_Error TgecDelHashMacAddress(t_Handle h_Tgec, t_EnetAddr *p_EthAddr)
780 {
781     t_Tgec          *p_Tgec = (t_Tgec *)h_Tgec;
782     t_TgecMemMap    *p_TgecMemMap;
783     t_EthHashEntry  *p_HashEntry = NULL;
784     t_List          *p_Pos;
785     uint32_t        crc;
786     uint32_t        hash;
787     uint64_t        ethAddr;
788 
789     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_NULL_POINTER);
790     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
791 
792     p_TgecMemMap = p_Tgec->p_MemMap;
793     ethAddr = ((*(uint64_t *)p_EthAddr) >> 16);
794 
795     /* CRC calculation */
796     GET_MAC_ADDR_CRC(ethAddr, crc);
797     crc = MIRROR_32(crc);
798 
799     hash = (crc >> HASH_CTRL_MCAST_SHIFT) & HASH_ADDR_MASK;        /* Take 9 MSB bits */
800 
801     LIST_FOR_EACH(p_Pos, &(p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
802     {
803 
804         p_HashEntry = ETH_HASH_ENTRY_OBJ(p_Pos);
805         if(p_HashEntry->addr == ethAddr)
806         {
807             LIST_DelAndInit(&p_HashEntry->node);
808             XX_Free(p_HashEntry);
809             break;
810         }
811     }
812     if(LIST_IsEmpty(&p_Tgec->p_MulticastAddrHash->p_Lsts[hash]))
813         WRITE_UINT32(p_TgecMemMap->hashtable_ctrl, (hash & ~HASH_CTRL_MCAST_EN));
814 
815     return E_OK;
816 }
817 
818 /* .............................................................................. */
819 
820 static t_Error TgecGetId(t_Handle h_Tgec, uint32_t *macId)
821 {
822     t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
823 
824     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
825     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
826 
827     UNUSED(p_Tgec);
828     UNUSED(macId);
829     RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("TgecGetId Not Supported"));
830 }
831 
832 /* .............................................................................. */
833 
834 static t_Error TgecGetVersion(t_Handle h_Tgec, uint32_t *macVersion)
835 {
836     t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
837     t_TgecMemMap        *p_TgecMemMap;
838 
839     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
840     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
841     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
842 
843     p_TgecMemMap = p_Tgec->p_MemMap;
844     *macVersion = GET_UINT32(p_TgecMemMap->tgec_id);
845 
846     return E_OK;
847 }
848 
849 /* .............................................................................. */
850 
851 static t_Error TgecSetExcpetion(t_Handle h_Tgec, e_FmMacExceptions exception, bool enable)
852 {
853     t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
854     uint32_t            bitMask = 0, tmpReg;
855     t_TgecMemMap        *p_TgecMemMap;
856 
857     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
858     SANITY_CHECK_RETURN_ERROR(!p_Tgec->p_TgecDriverParam, E_NULL_POINTER);
859     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_NULL_POINTER);
860 
861     p_TgecMemMap = p_Tgec->p_MemMap;
862 #ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
863     {
864         t_FmRevisionInfo revInfo;
865         FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
866         if((revInfo.majorRev <=2) &&
867             enable &&
868             ((exception == e_FM_MAC_EX_10G_LOC_FAULT) || (exception == e_FM_MAC_EX_10G_REM_FAULT)))
869                 RETURN_ERROR(MINOR, E_NOT_SUPPORTED, ("e_FM_MAC_EX_10G_LOC_FAULT and e_FM_MAC_EX_10G_REM_FAULT !"));
870     }
871 #endif   /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */
872 
873     GET_EXCEPTION_FLAG(bitMask, exception);
874     if(bitMask)
875     {
876         if (enable)
877             p_Tgec->exceptions |= bitMask;
878         else
879             p_Tgec->exceptions &= ~bitMask;
880    }
881     else
882         RETURN_ERROR(MAJOR, E_INVALID_VALUE, ("Undefined exception"));
883 
884     tmpReg = GET_UINT32(p_TgecMemMap->imask);
885     if(enable)
886         tmpReg |= bitMask;
887     else
888         tmpReg &= ~bitMask;
889     WRITE_UINT32(p_TgecMemMap->imask, tmpReg);
890     return E_OK;
891 }
892 
893 /* .............................................................................. */
894 
895 static uint16_t TgecGetMaxFrameLength(t_Handle h_Tgec)
896 {
897     t_Tgec              *p_Tgec = (t_Tgec *)h_Tgec;
898 
899     SANITY_CHECK_RETURN_VALUE(p_Tgec, E_INVALID_HANDLE, 0);
900 
901     return (uint16_t)GET_UINT32(p_Tgec->p_MemMap->maxfrm);
902 }
903 
904 /* .............................................................................. */
905 
906 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
907 static t_Error TgecTxEccWorkaround(t_Tgec *p_Tgec)
908 {
909     t_Error err;
910 
911     XX_Print("Applying 10G tx-ecc error workaround (10GMAC-A004) ...");
912     /* enable and set promiscuous */
913     WRITE_UINT32(p_Tgec->p_MemMap->cmd_conf_ctrl, CMD_CFG_PROMIS_EN | CMD_CFG_TX_EN | CMD_CFG_RX_EN);
914     err = Fm10GTxEccWorkaround(p_Tgec->fmMacControllerDriver.h_Fm, p_Tgec->macId);
915     /* disable */
916     WRITE_UINT32(p_Tgec->p_MemMap->cmd_conf_ctrl, 0);
917     if (err)
918         XX_Print("FAILED!\n");
919     else
920         XX_Print("done.\n");
921     TgecResetCounters (p_Tgec);
922 
923     return err;
924 }
925 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
926 
927 /* .............................................................................. */
928 
929 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
930 static t_Error TgecDumpRegs(t_Handle h_Tgec)
931 {
932     t_Tgec    *p_Tgec = (t_Tgec *)h_Tgec;
933 
934     DECLARE_DUMP;
935 
936     if (p_Tgec->p_MemMap)
937     {
938         DUMP_TITLE(p_Tgec->p_MemMap, ("10G MAC %d: ", p_Tgec->macId));
939         DUMP_VAR(p_Tgec->p_MemMap, tgec_id);
940         DUMP_VAR(p_Tgec->p_MemMap, scratch);
941         DUMP_VAR(p_Tgec->p_MemMap, cmd_conf_ctrl);
942         DUMP_VAR(p_Tgec->p_MemMap, mac_addr_0);
943         DUMP_VAR(p_Tgec->p_MemMap, mac_addr_1);
944         DUMP_VAR(p_Tgec->p_MemMap, maxfrm);
945         DUMP_VAR(p_Tgec->p_MemMap, pause_quant);
946         DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_sections);
947         DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_sections);
948         DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_almost_f_e);
949         DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_almost_f_e);
950         DUMP_VAR(p_Tgec->p_MemMap, hashtable_ctrl);
951         DUMP_VAR(p_Tgec->p_MemMap, mdio_cfg_status);
952         DUMP_VAR(p_Tgec->p_MemMap, mdio_command);
953         DUMP_VAR(p_Tgec->p_MemMap, mdio_data);
954         DUMP_VAR(p_Tgec->p_MemMap, mdio_regaddr);
955         DUMP_VAR(p_Tgec->p_MemMap, status);
956         DUMP_VAR(p_Tgec->p_MemMap, tx_ipg_len);
957         DUMP_VAR(p_Tgec->p_MemMap, mac_addr_2);
958         DUMP_VAR(p_Tgec->p_MemMap, mac_addr_3);
959         DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_rd);
960         DUMP_VAR(p_Tgec->p_MemMap, rx_fifo_ptr_wr);
961         DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_rd);
962         DUMP_VAR(p_Tgec->p_MemMap, tx_fifo_ptr_wr);
963         DUMP_VAR(p_Tgec->p_MemMap, imask);
964         DUMP_VAR(p_Tgec->p_MemMap, ievent);
965         DUMP_VAR(p_Tgec->p_MemMap, udp_port);
966         DUMP_VAR(p_Tgec->p_MemMap, type_1588v2);
967     }
968 
969     return E_OK;
970 }
971 #endif /* (defined(DEBUG_ERRORS) && ... */
972 
973 
974 /*****************************************************************************/
975 /*                      FM Init & Free API                                   */
976 /*****************************************************************************/
977 
978 /* .............................................................................. */
979 
980 static t_Error TgecInit(t_Handle h_Tgec)
981 {
982     t_Tgec                  *p_Tgec = (t_Tgec *)h_Tgec;
983     t_TgecDriverParam       *p_TgecDriverParam;
984     t_TgecMemMap            *p_MemMap;
985     uint64_t                addr;
986     uint32_t                tmpReg32;
987     t_Error                 err;
988 
989     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
990     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_TgecDriverParam, E_INVALID_STATE);
991     SANITY_CHECK_RETURN_ERROR(p_Tgec->p_MemMap, E_INVALID_HANDLE);
992 
993 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
994     if (!p_Tgec->p_TgecDriverParam->skipFman11Workaround &&
995         ((err = TgecTxEccWorkaround(p_Tgec)) != E_OK))
996 #ifdef NCSW_LINUX
997     {
998         /* the workaround fails in simics, just report and continue initialization */
999         REPORT_ERROR(MAJOR, err, ("TgecTxEccWorkaround FAILED, skipping workaround"));
1000     }
1001 #else
1002     {
1003         FreeInitResources(p_Tgec);
1004         RETURN_ERROR(MAJOR, err, ("TgecTxEccWorkaround FAILED"));
1005     }
1006 #endif
1007 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
1008 
1009     CHECK_INIT_PARAMETERS(p_Tgec, CheckInitParameters);
1010 
1011     p_TgecDriverParam = p_Tgec->p_TgecDriverParam;
1012     p_MemMap = p_Tgec->p_MemMap;
1013 
1014     /* MAC Address */
1015     addr = p_Tgec->addr;
1016     tmpReg32 = (uint32_t)(addr>>16);
1017     SwapUint32P(&tmpReg32);
1018     WRITE_UINT32(p_MemMap->mac_addr_0, tmpReg32);
1019 
1020     tmpReg32 = (uint32_t)(addr);
1021     SwapUint32P(&tmpReg32);
1022     tmpReg32 >>= 16;
1023     WRITE_UINT32(p_MemMap->mac_addr_1, tmpReg32);
1024 
1025     /* Config */
1026     tmpReg32 = 0;
1027     if (p_TgecDriverParam->wanModeEnable)
1028         tmpReg32 |= CMD_CFG_WAN_MODE;
1029     if (p_TgecDriverParam->promiscuousModeEnable)
1030         tmpReg32 |= CMD_CFG_PROMIS_EN;
1031     if (p_TgecDriverParam->pauseForwardEnable)
1032         tmpReg32 |= CMD_CFG_PAUSE_FWD;
1033     if (p_TgecDriverParam->pauseIgnore)
1034         tmpReg32 |= CMD_CFG_PAUSE_IGNORE;
1035     if (p_TgecDriverParam->txAddrInsEnable)
1036         tmpReg32 |= CMD_CFG_TX_ADDR_INS;
1037     if (p_TgecDriverParam->loopbackEnable)
1038         tmpReg32 |= CMD_CFG_LOOPBACK_EN;
1039     if (p_TgecDriverParam->cmdFrameEnable)
1040         tmpReg32 |= CMD_CFG_CMD_FRM_EN;
1041     if (p_TgecDriverParam->rxErrorDiscard)
1042         tmpReg32 |= CMD_CFG_RX_ER_DISC;
1043     if (p_TgecDriverParam->phyTxenaOn)
1044         tmpReg32 |= CMD_CFG_PHY_TX_EN;
1045     if (p_TgecDriverParam->sendIdleEnable)
1046         tmpReg32 |= CMD_CFG_SEND_IDLE;
1047     if (p_TgecDriverParam->noLengthCheckEnable)
1048         tmpReg32 |= CMD_CFG_NO_LEN_CHK;
1049     if (p_TgecDriverParam->lgthCheckNostdr)
1050         tmpReg32 |= CMD_CFG_LEN_CHK_NOSTDR;
1051     if (p_TgecDriverParam->timeStampEnable)
1052         tmpReg32 |= CMD_CFG_EN_TIMESTAMP;
1053     if (p_TgecDriverParam->rxSfdAny)
1054         tmpReg32 |= RX_SFD_ANY;
1055     if (p_TgecDriverParam->rxPblFwd)
1056         tmpReg32 |= CMD_CFG_RX_PBL_FWD;
1057     if (p_TgecDriverParam->txPblFwd)
1058         tmpReg32 |= CMD_CFG_TX_PBL_FWD;
1059     tmpReg32 |= 0x40;
1060     WRITE_UINT32(p_MemMap->cmd_conf_ctrl, tmpReg32);
1061 
1062     /* Max Frame Length */
1063     WRITE_UINT32(p_MemMap->maxfrm, (uint32_t)p_TgecDriverParam->maxFrameLength);
1064     err = FmSetMacMaxFrame(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MAC_10G, p_Tgec->fmMacControllerDriver.macId, p_TgecDriverParam->maxFrameLength);
1065     if(err)
1066     {
1067         FreeInitResources(p_Tgec);
1068         RETURN_ERROR(MAJOR, err, NO_MSG);
1069     }
1070 
1071     /* Pause Time */
1072     WRITE_UINT32(p_MemMap->pause_quant, p_TgecDriverParam->pauseTime);
1073 
1074 #ifdef FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007
1075     WRITE_UINT32(p_Tgec->p_MemMap->tx_ipg_len,
1076         (GET_UINT32(p_Tgec->p_MemMap->tx_ipg_len) & ~TX_IPG_LENGTH_MASK) | DEFAULT_txIpgLength);
1077 #endif /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 */
1078 
1079     /* Configure MII */
1080     tmpReg32  = GET_UINT32(p_Tgec->p_MiiMemMap->mdio_cfg_status);
1081 #ifdef FM_10G_MDIO_HOLD_ERRATA_XAUI3
1082     {
1083         t_FmRevisionInfo revInfo;
1084         FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
1085         if ((revInfo.majorRev == 1) && (revInfo.minorRev == 0))
1086             tmpReg32 |= (MIIMCOM_MDIO_HOLD_4_REG_CLK << 2);
1087     }
1088 #endif /* FM_10G_MDIO_HOLD_ERRATA_XAUI3 */
1089     tmpReg32 &= ~MIIMCOM_DIV_MASK;
1090      /* (one half of fm clock => 2.5Mhz) */
1091     tmpReg32 |=((((p_Tgec->fmMacControllerDriver.clkFreq*10)/2)/25) << MIIMCOM_DIV_SHIFT);
1092     WRITE_UINT32(p_Tgec->p_MiiMemMap->mdio_cfg_status, tmpReg32);
1093 
1094     p_Tgec->p_MulticastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
1095     if(!p_Tgec->p_MulticastAddrHash)
1096     {
1097         FreeInitResources(p_Tgec);
1098         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
1099     }
1100 
1101     p_Tgec->p_UnicastAddrHash = AllocHashTable(HASH_TABLE_SIZE);
1102     if(!p_Tgec->p_UnicastAddrHash)
1103     {
1104         FreeInitResources(p_Tgec);
1105         RETURN_ERROR(MAJOR, E_NO_MEMORY, ("allocation hash table is FAILED"));
1106     }
1107 
1108     /* interrupts */
1109 #ifdef FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001
1110     {
1111         t_FmRevisionInfo revInfo;
1112         FM_GetRevision(p_Tgec->fmMacControllerDriver.h_Fm, &revInfo);
1113         if (revInfo.majorRev <=2)
1114             p_Tgec->exceptions &= ~(IMASK_REM_FAULT | IMASK_LOC_FAULT);
1115     }
1116 #endif /* FM_10G_REM_N_LCL_FLT_EX_ERRATA_10GMAC001 */
1117     WRITE_UINT32(p_MemMap->ievent, EVENTS_MASK);
1118     WRITE_UINT32(p_MemMap->imask, p_Tgec->exceptions);
1119 
1120     FmRegisterIntr(p_Tgec->fmMacControllerDriver.h_Fm, e_FM_MOD_10G_MAC, p_Tgec->macId, e_FM_INTR_TYPE_ERR, TgecErrException , p_Tgec);
1121     if ((p_Tgec->mdioIrq != 0) && (p_Tgec->mdioIrq != NO_IRQ))
1122     {
1123         XX_SetIntr(p_Tgec->mdioIrq, TgecException, p_Tgec);
1124         XX_EnableIntr(p_Tgec->mdioIrq);
1125     }
1126     else if (p_Tgec->mdioIrq == 0)
1127         REPORT_ERROR(MINOR, E_NOT_SUPPORTED, (NO_MSG));
1128 
1129     XX_Free(p_TgecDriverParam);
1130     p_Tgec->p_TgecDriverParam = NULL;
1131 
1132     return E_OK;
1133 }
1134 
1135 /* .............................................................................. */
1136 
1137 static t_Error TgecFree(t_Handle h_Tgec)
1138 {
1139     t_Tgec       *p_Tgec = (t_Tgec *)h_Tgec;
1140 
1141     SANITY_CHECK_RETURN_ERROR(p_Tgec, E_INVALID_HANDLE);
1142 
1143     FreeInitResources(p_Tgec);
1144 
1145     if (p_Tgec->p_TgecDriverParam)
1146     {
1147         XX_Free(p_Tgec->p_TgecDriverParam);
1148         p_Tgec->p_TgecDriverParam = NULL;
1149     }
1150     XX_Free (p_Tgec);
1151 
1152     return E_OK;
1153 }
1154 
1155 /* .............................................................................. */
1156 
1157 static void InitFmMacControllerDriver(t_FmMacControllerDriver *p_FmMacControllerDriver)
1158 {
1159     p_FmMacControllerDriver->f_FM_MAC_Init                      = TgecInit;
1160     p_FmMacControllerDriver->f_FM_MAC_Free                      = TgecFree;
1161 
1162     p_FmMacControllerDriver->f_FM_MAC_ConfigLoopback            = TgecConfigLoopback;
1163     p_FmMacControllerDriver->f_FM_MAC_ConfigMaxFrameLength      = TgecConfigMaxFrameLength;
1164 
1165     p_FmMacControllerDriver->f_FM_MAC_ConfigWan                 = TgecConfigWan;
1166 
1167     p_FmMacControllerDriver->f_FM_MAC_ConfigPadAndCrc           = NULL; /* TGEC always works with pad+crc */
1168     p_FmMacControllerDriver->f_FM_MAC_ConfigHalfDuplex          = NULL; /* half-duplex is not supported in xgec */
1169     p_FmMacControllerDriver->f_FM_MAC_ConfigLengthCheck         = TgecConfigLengthCheck;
1170     p_FmMacControllerDriver->f_FM_MAC_ConfigException           = TgecConfigException;
1171 
1172 #ifdef FM_TX_ECC_FRMS_ERRATA_10GMAC_A004
1173     p_FmMacControllerDriver->f_FM_MAC_ConfigSkipFman11Workaround= TgecConfigSkipFman11Workaround;
1174 #endif /* FM_TX_ECC_FRMS_ERRATA_10GMAC_A004 */
1175 
1176     p_FmMacControllerDriver->f_FM_MAC_SetException              = TgecSetExcpetion;
1177 
1178     p_FmMacControllerDriver->f_FM_MAC_Enable1588TimeStamp       = TgecEnable1588TimeStamp;
1179     p_FmMacControllerDriver->f_FM_MAC_Disable1588TimeStamp      = TgecDisable1588TimeStamp;
1180 
1181     p_FmMacControllerDriver->f_FM_MAC_SetPromiscuous            = TgecSetPromiscuous;
1182     p_FmMacControllerDriver->f_FM_MAC_AdjustLink                = NULL;
1183 
1184     p_FmMacControllerDriver->f_FM_MAC_Enable                    = TgecEnable;
1185     p_FmMacControllerDriver->f_FM_MAC_Disable                   = TgecDisable;
1186 
1187     p_FmMacControllerDriver->f_FM_MAC_SetTxAutoPauseFrames      = TgecTxMacPause;
1188     p_FmMacControllerDriver->f_FM_MAC_SetRxIgnorePauseFrames    = TgecRxIgnoreMacPause;
1189 
1190     p_FmMacControllerDriver->f_FM_MAC_ResetCounters             = TgecResetCounters;
1191     p_FmMacControllerDriver->f_FM_MAC_GetStatistics             = TgecGetStatistics;
1192 
1193     p_FmMacControllerDriver->f_FM_MAC_ModifyMacAddr             = TgecModifyMacAddress;
1194     p_FmMacControllerDriver->f_FM_MAC_AddHashMacAddr            = TgecAddHashMacAddress;
1195     p_FmMacControllerDriver->f_FM_MAC_RemoveHashMacAddr         = TgecDelHashMacAddress;
1196     p_FmMacControllerDriver->f_FM_MAC_AddExactMatchMacAddr      = TgecAddExactMatchMacAddress;
1197     p_FmMacControllerDriver->f_FM_MAC_RemovelExactMatchMacAddr  = TgecDelExactMatchMacAddress;
1198     p_FmMacControllerDriver->f_FM_MAC_GetId                     = TgecGetId;
1199     p_FmMacControllerDriver->f_FM_MAC_GetVersion                = TgecGetVersion;
1200     p_FmMacControllerDriver->f_FM_MAC_GetMaxFrameLength         = TgecGetMaxFrameLength;
1201 
1202     p_FmMacControllerDriver->f_FM_MAC_MII_WritePhyReg           = TGEC_MII_WritePhyReg;
1203     p_FmMacControllerDriver->f_FM_MAC_MII_ReadPhyReg            = TGEC_MII_ReadPhyReg;
1204 
1205 #if (defined(DEBUG_ERRORS) && (DEBUG_ERRORS > 0))
1206     p_FmMacControllerDriver->f_FM_MAC_DumpRegs                  = TgecDumpRegs;
1207 #endif /* (defined(DEBUG_ERRORS) && ... */
1208 }
1209 
1210 
1211 /*****************************************************************************/
1212 /*                      Tgec Config  Main Entry                             */
1213 /*****************************************************************************/
1214 
1215 /* .............................................................................. */
1216 
1217 t_Handle TGEC_Config(t_FmMacParams *p_FmMacParam)
1218 {
1219     t_Tgec                  *p_Tgec;
1220     t_TgecDriverParam       *p_TgecDriverParam;
1221     uintptr_t               baseAddr;
1222     uint8_t                 i;
1223 
1224     SANITY_CHECK_RETURN_VALUE(p_FmMacParam, E_NULL_POINTER, NULL);
1225 
1226     baseAddr = p_FmMacParam->baseAddr;
1227     /* allocate memory for the UCC GETH data structure. */
1228     p_Tgec = (t_Tgec *) XX_Malloc(sizeof(t_Tgec));
1229     if (!p_Tgec)
1230     {
1231         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver structure"));
1232         return NULL;
1233     }
1234     /* Zero out * p_Tgec */
1235     memset(p_Tgec, 0, sizeof(t_Tgec));
1236     InitFmMacControllerDriver(&p_Tgec->fmMacControllerDriver);
1237 
1238     /* allocate memory for the 10G MAC driver parameters data structure. */
1239     p_TgecDriverParam = (t_TgecDriverParam *) XX_Malloc(sizeof(t_TgecDriverParam));
1240     if (!p_TgecDriverParam)
1241     {
1242         REPORT_ERROR(MAJOR, E_NO_MEMORY, ("10G MAC driver parameters"));
1243         TgecFree(p_Tgec);
1244         return NULL;
1245     }
1246     /* Zero out */
1247     memset(p_TgecDriverParam, 0, sizeof(t_TgecDriverParam));
1248 
1249     /* Plant parameter structure pointer */
1250     p_Tgec->p_TgecDriverParam = p_TgecDriverParam;
1251 
1252     SetDefaultParam(p_TgecDriverParam);
1253 
1254     for (i=0; i < sizeof(p_FmMacParam->addr); i++)
1255         p_Tgec->addr |= ((uint64_t)p_FmMacParam->addr[i] << ((5-i) * 8));
1256 
1257     p_Tgec->p_MemMap        = (t_TgecMemMap *)UINT_TO_PTR(baseAddr);
1258     p_Tgec->p_MiiMemMap     = (t_TgecMiiAccessMemMap *)UINT_TO_PTR(baseAddr + TGEC_TO_MII_OFFSET);
1259     p_Tgec->enetMode        = p_FmMacParam->enetMode;
1260     p_Tgec->macId           = p_FmMacParam->macId;
1261     p_Tgec->exceptions      = DEFAULT_exceptions;
1262     p_Tgec->mdioIrq         = p_FmMacParam->mdioIrq;
1263     p_Tgec->f_Exception     = p_FmMacParam->f_Exception;
1264     p_Tgec->f_Event         = p_FmMacParam->f_Event;
1265     p_Tgec->h_App           = p_FmMacParam->h_App;
1266 
1267     return p_Tgec;
1268 }
1269