Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/ncsw/Peripherals/FM/MAC/dtsec.c
48524 views
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
}
1465
1466