1 /*
2 * Copyright 2021-2023 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "fsl_netc_hw_port.h"
8
NETC_PortIsPseudo(NETC_PORT_Type * base)9 bool NETC_PortIsPseudo(NETC_PORT_Type *base)
10 {
11 return ((base->PCAPR & NETC_PORT_PCAPR_LINK_TYPE_MASK) != 0U);
12 }
13
NETC_PortSetMacAddr(NETC_PORT_Type * base,const uint8_t * macAddr)14 void NETC_PortSetMacAddr(NETC_PORT_Type *base, const uint8_t *macAddr)
15 {
16 uint32_t address;
17
18 /* Set physical address lower register. */
19 address = ((uint32_t *)(uintptr_t)macAddr)[0];
20 base->PMAR0 = address;
21
22 /* Set physical address high register. */
23 address = ((uint32_t)macAddr[5] << 8U) | (uint32_t)macAddr[4];
24 base->PMAR1 = NETC_PORT_PMAR1_PRIM_MAC_ADDR(address);
25 }
26
NETC_PortConfig(NETC_PORT_Type * base,const netc_port_common_t * config)27 status_t NETC_PortConfig(NETC_PORT_Type *base, const netc_port_common_t *config)
28 {
29 status_t result;
30
31 NETC_PortSetParser(base, &config->parser);
32 NETC_PortSetVlanClassify(base, &config->acceptTpid);
33
34 result = NETC_PortSetQosClassify(base, &config->qosMode);
35 if (result != kStatus_Success)
36 {
37 return result;
38 }
39
40 (void)NETC_PortConfigTGS(base, &config->timeGate);
41 NETC_PortSetIPF(base, &config->ipfCfg);
42 NETC_PortSetMacAddr(base, &config->macAddr[0]);
43 base->PCR = NETC_PORT_PCR_PSPEED(config->pSpeed) |
44 #if (defined(FSL_FEATURE_NETC_HAS_PORT_FCSEA) && FSL_FEATURE_NETC_HAS_PORT_FCSEA)
45 NETC_PORT_PCR_FCSEA(!config->stompFcs) |
46 #endif
47 NETC_PORT_PCR_TIMER_CS(config->rxTsSelect);
48 base->PSGCR = NETC_PORT_PSGCR_OGC(config->ogcMode) | NETC_PORT_PSGCR_PDELAY(config->pDelay);
49
50 /* Configure Port SDU overhead */
51 base->PRXSDUOR =
52 NETC_PORT_PRXSDUOR_MACSEC_BCO(config->rxMacsecBco) | NETC_PORT_PRXSDUOR_PPDU_BCO(config->rxPpduBco);
53 base->PTXSDUOR =
54 NETC_PORT_PTXSDUOR_MACSEC_BCO(config->txMacsecBco) | NETC_PORT_PTXSDUOR_PPDU_BCO(config->txPpduBco);
55 return kStatus_Success;
56 }
57
NETC_PortSetMII(NETC_ETH_LINK_Type * base,netc_hw_mii_mode_t miiMode,netc_hw_mii_speed_t speed,netc_hw_mii_duplex_t duplex)58 status_t NETC_PortSetMII(NETC_ETH_LINK_Type *base,
59 netc_hw_mii_mode_t miiMode,
60 netc_hw_mii_speed_t speed,
61 netc_hw_mii_duplex_t duplex)
62 {
63 uint32_t reg = base->PM0_IF_MODE;
64
65 /* Set MAC interface mode */
66 reg &= ~NETC_ETH_LINK_PM0_IF_MODE_IFMODE_MASK;
67 reg |= NETC_ETH_LINK_PM0_IF_MODE_IFMODE(miiMode);
68
69 /* Set MAC speed and duplex */
70 if ((miiMode == kNETC_MiiMode) || (miiMode == kNETC_RmiiMode))
71 {
72 if (speed == kNETC_MiiSpeed10M)
73 {
74 reg |= NETC_ETH_LINK_PM0_IF_MODE_M10_MASK;
75 }
76 else if (speed == kNETC_MiiSpeed100M)
77 {
78 reg &= ~NETC_ETH_LINK_PM0_IF_MODE_M10_MASK;
79 }
80 else
81 {
82 return kStatus_Fail;
83 }
84 reg &= ~NETC_ETH_LINK_PM0_IF_MODE_HD_MASK;
85 reg |= NETC_ETH_LINK_PM0_IF_MODE_HD(duplex != kNETC_MiiFullDuplex);
86 }
87 else if (miiMode == kNETC_RgmiiMode)
88 {
89 reg &= ~NETC_ETH_LINK_PM0_IF_MODE_SSP_MASK;
90 reg &= ~NETC_ETH_LINK_PM0_IF_MODE_HD_MASK;
91 if (speed == kNETC_MiiSpeed1000M)
92 {
93 reg |= NETC_ETH_LINK_PM0_IF_MODE_SSP(speed);
94 reg |= NETC_ETH_LINK_PM0_IF_MODE_HD(0);
95 }
96 else
97 {
98 reg |= NETC_ETH_LINK_PM0_IF_MODE_SSP(speed != kNETC_MiiSpeed100M);
99 reg |= NETC_ETH_LINK_PM0_IF_MODE_HD(duplex != kNETC_MiiFullDuplex);
100 }
101 }
102 else /* kNETC_GmiiMode, force 1Gbps and full speed */
103 {
104 if ((speed < kNETC_MiiSpeed1000M) || (duplex != kNETC_MiiFullDuplex))
105 {
106 return kStatus_InvalidArgument;
107 }
108 }
109 base->PM0_IF_MODE = reg;
110 base->PM1_IF_MODE = reg;
111
112 return kStatus_Success;
113 }
114
NETC_PortSetMaxFrameSize(NETC_ETH_LINK_Type * base,uint16_t size)115 status_t NETC_PortSetMaxFrameSize(NETC_ETH_LINK_Type *base, uint16_t size)
116 {
117 /* The MAC supports reception of any frame size up to 2000 bytes. */
118 if (size > NETC_PORT_MAX_FRAME_SIZE)
119 {
120 return kStatus_InvalidArgument;
121 }
122
123 base->PM0_MAXFRM = NETC_ETH_LINK_PM0_MAXFRM_MAXFRM(size);
124 base->PM1_MAXFRM = NETC_ETH_LINK_PM1_MAXFRM_MAXFRM(size);
125
126 return kStatus_Success;
127 }
128
NETC_PortConfigEthMac(NETC_ETH_LINK_Type * base,const netc_port_ethmac_t * config)129 status_t NETC_PortConfigEthMac(NETC_ETH_LINK_Type *base, const netc_port_ethmac_t *config)
130 {
131 uint32_t reg = 0;
132 status_t result;
133
134 if ((config->rxMinFrameSize < NETC_PORT_MIN_FRAME_SIZE) || (config->rxMaxFrameSize > NETC_PORT_MAX_FRAME_SIZE) ||
135 (config->rxMinFrameSize > config->rxMaxFrameSize))
136 {
137 return kStatus_InvalidArgument;
138 }
139
140 /* Set Rx Frame Maximum/Minimum Length */
141 result = NETC_PortSetMaxFrameSize(base, config->rxMaxFrameSize);
142 if (result != kStatus_Success)
143 {
144 return result;
145 }
146 #if defined(NETC_ETH_LINK_PM0_MINFRM_NUM_BYTES_MASK)
147 base->PM0_MINFRM = NETC_ETH_LINK_PM0_MINFRM_NUM_BYTES(config->rxMinFrameSize);
148 #endif
149 #if defined(NETC_ETH_LINK_PM1_MINFRM_NUM_BYTES_MASK)
150 base->PM1_MINFRM = NETC_ETH_LINK_PM1_MINFRM_NUM_BYTES(config->rxMinFrameSize);
151 #endif
152
153 /* Set MAC interface mode, speed and duplex */
154 result = NETC_PortSetMII(base, config->miiMode, config->miiSpeed, config->miiDuplex);
155 if (result != kStatus_Success)
156 {
157 return result;
158 }
159
160 /* Enable reverse mode */
161 reg = base->PM0_IF_MODE;
162 if (config->enableRevMii)
163 {
164 reg |= NETC_ETH_LINK_PM0_IF_MODE_REVMII_MASK;
165 }
166 else
167 {
168 reg &= ~NETC_ETH_LINK_PM0_IF_MODE_REVMII_MASK;
169 }
170 /* Enable RGMII Tx clock stop status during low power idle. */
171 if (config->rgmiiClkStop)
172 {
173 reg |= NETC_ETH_LINK_PM0_IF_MODE_CLK_STOP_MASK;
174 }
175 else
176 {
177 reg &= ~NETC_ETH_LINK_PM0_IF_MODE_CLK_STOP_MASK;
178 }
179 base->PM0_IF_MODE = reg;
180 base->PM1_IF_MODE = reg;
181
182 base->MAC_MERGE_MMCSR = NETC_ETH_LINK_MAC_MERGE_MMCSR_VT(config->mergeVerifyTime) |
183 NETC_ETH_LINK_MAC_MERGE_MMCSR_VDIS(!config->enMergeVerify) |
184 NETC_ETH_LINK_MAC_MERGE_MMCSR_ME(config->preemptMode);
185
186 #if !(defined(FSL_FEATURE_NETC_HAS_ERRATA_051255) && FSL_FEATURE_NETC_HAS_ERRATA_051255)
187 reg = NETC_ETH_LINK_PM0_SINGLE_STEP_CH(config->enChUpdate) |
188 NETC_ETH_LINK_PM0_SINGLE_STEP_OFFSET(config->oneStepOffset) |
189 NETC_ETH_LINK_PM0_SINGLE_STEP_EN(config->enOneStepTS);
190 base->PM0_SINGLE_STEP = reg;
191 base->PM1_SINGLE_STEP = reg;
192 #endif
193
194 /* Enable Tx/Rx */
195 reg = NETC_ETH_LINK_PM0_COMMAND_CONFIG_TX_EN_MASK | NETC_ETH_LINK_PM0_COMMAND_CONFIG_RX_EN_MASK |
196 NETC_ETH_LINK_PM0_COMMAND_CONFIG_TS_MODE(config->txTsSelect) |
197 NETC_ETH_LINK_PM0_COMMAND_CONFIG_TS_PNT(config->isTsPointPhy) |
198 #if defined(NETC_ETH_LINK_PM0_COMMAND_CONFIG_HD_FCEN_MASK)
199 NETC_ETH_LINK_PM0_COMMAND_CONFIG_HD_FCEN(config->enableHalfDuplexFlowCtrl) |
200 #endif
201 NETC_ETH_LINK_PM0_COMMAND_CONFIG_TXP(config->enTxPad);
202 base->PM0_COMMAND_CONFIG = reg;
203 base->PM1_COMMAND_CONFIG = reg;
204
205 if (config->enableHalfDuplexFlowCtrl)
206 {
207 assert((config->maxBackPressOn <= 3036U) && (config->minBackPressOff <= 20U));
208 reg = NETC_ETH_LINK_PM0_HD_FLOW_CTRL_HD_BP_ON_MAX(config->maxBackPressOn) |
209 NETC_ETH_LINK_PM0_HD_FLOW_CTRL_HD_BP_OFF_MIN(config->minBackPressOff);
210 base->PM0_HD_FLOW_CTRL = reg;
211 base->PM1_HD_FLOW_CTRL = reg;
212 }
213
214 return kStatus_Success;
215 }
216
NETC_GetPortMacInterruptFlags(NETC_ETH_LINK_Type * base,netc_port_phy_mac_type_t macType)217 uint32_t NETC_GetPortMacInterruptFlags(NETC_ETH_LINK_Type *base, netc_port_phy_mac_type_t macType)
218 {
219 if (macType == kNETC_ExpressMAC)
220 {
221 return base->PM0_IEVENT;
222 }
223 else
224 {
225 return base->PM1_IEVENT;
226 }
227 }
228
NETC_ClearPortMacInterruptFlags(NETC_ETH_LINK_Type * base,netc_port_phy_mac_type_t macType,uint32_t mask)229 void NETC_ClearPortMacInterruptFlags(NETC_ETH_LINK_Type *base, netc_port_phy_mac_type_t macType, uint32_t mask)
230 {
231 if (macType == kNETC_ExpressMAC)
232 {
233 base->PM0_IEVENT |= mask;
234 }
235 else
236 {
237 base->PM1_IEVENT |= mask;
238 }
239 }
240
NETC_EnablePortMacInterrupts(NETC_ETH_LINK_Type * base,netc_port_phy_mac_type_t macType,uint32_t mask,bool enable)241 void NETC_EnablePortMacInterrupts(NETC_ETH_LINK_Type *base, netc_port_phy_mac_type_t macType, uint32_t mask, bool enable)
242 {
243 if (macType == kNETC_ExpressMAC)
244 {
245 if (enable)
246 {
247 base->PM0_IMASK |= mask;
248 }
249 else
250 {
251 base->PM0_IMASK &= ~mask;
252 }
253 }
254 else
255 {
256 if (enable)
257 {
258 base->PM1_IMASK |= mask;
259 }
260 else
261 {
262 base->PM1_IMASK &= ~mask;
263 }
264 }
265 }
266
NETC_PortEnableLoopback(NETC_ETH_LINK_Type * base,netc_port_loopback_mode_t loopMode,bool enable)267 status_t NETC_PortEnableLoopback(NETC_ETH_LINK_Type *base, netc_port_loopback_mode_t loopMode, bool enable)
268 {
269 uint32_t reg = base->PM0_COMMAND_CONFIG;
270
271 if (enable)
272 {
273 reg &= ~NETC_ETH_LINK_PM0_COMMAND_CONFIG_LPBK_MODE_MASK;
274 reg |= NETC_ETH_LINK_PM0_COMMAND_CONFIG_LOOP_ENA_MASK | NETC_ETH_LINK_PM0_COMMAND_CONFIG_LPBK_MODE(loopMode);
275 }
276 else
277 {
278 reg &= ~NETC_ETH_LINK_PM0_COMMAND_CONFIG_LOOP_ENA_MASK;
279 }
280
281 base->PM0_COMMAND_CONFIG = reg;
282 base->PM1_COMMAND_CONFIG = reg;
283
284 return kStatus_Success;
285 }
286
NETC_PortGetDiscardStatistic(NETC_PORT_Type * base,netc_port_discard_tpye_t discardType,netc_port_discard_statistic_t * statistic)287 void NETC_PortGetDiscardStatistic(NETC_PORT_Type *base,
288 netc_port_discard_tpye_t discardType,
289 netc_port_discard_statistic_t *statistic)
290 {
291 switch (discardType)
292 {
293 case kNETC_RxDiscard:
294 statistic->count = base->PRXDCR;
295 statistic->reason0 = base->PRXDCRR0;
296 statistic->reason1 = base->PRXDCRR1;
297 break;
298 #if !(defined(FSL_FEATURE_NETC_HAS_NO_SWITCH) && FSL_FEATURE_NETC_HAS_NO_SWITCH)
299 case kNETC_TxDiscard:
300 statistic->count = base->PTXDCR;
301 statistic->reason0 = base->PTXDCRR0;
302 statistic->reason1 = base->PTXDCRR1;
303 break;
304 case kNETC_BridgeDiscard:
305 statistic->count = base->BPDCR;
306 statistic->reason0 = base->BPDCRR0;
307 statistic->reason1 = base->BPDCRR1;
308 break;
309 #endif
310 default:
311 assert(false);
312 break;
313 }
314 }
315
NETC_PortClearDiscardReason(NETC_PORT_Type * base,netc_port_discard_tpye_t discardType,uint32_t reason0,uint32_t reason1)316 void NETC_PortClearDiscardReason(NETC_PORT_Type *base,
317 netc_port_discard_tpye_t discardType,
318 uint32_t reason0,
319 uint32_t reason1)
320 {
321 switch (discardType)
322 {
323 case kNETC_RxDiscard:
324 base->PRXDCRR0 = reason0;
325 base->PRXDCRR1 = reason1;
326 break;
327 #if !(defined(FSL_FEATURE_NETC_HAS_NO_SWITCH) && FSL_FEATURE_NETC_HAS_NO_SWITCH)
328 case kNETC_TxDiscard:
329 base->PTXDCRR0 = reason0;
330 base->PTXDCRR1 = reason1;
331 break;
332 case kNETC_BridgeDiscard:
333 base->BPDCRR0 = reason0;
334 base->BPDCRR1 = reason1;
335 break;
336 #endif
337 default:
338 assert(false);
339 break;
340 }
341 }
342
NETC_PortGetPhyMacTxStatistic(NETC_ETH_LINK_Type * base,netc_port_phy_mac_type_t macType,netc_port_phy_mac_traffic_statistic_t * statistic)343 void NETC_PortGetPhyMacTxStatistic(NETC_ETH_LINK_Type *base,
344 netc_port_phy_mac_type_t macType,
345 netc_port_phy_mac_traffic_statistic_t *statistic)
346 {
347 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
348 uint32_t primask;
349
350 primask = DisableGlobalIRQ();
351 #endif
352 statistic->rxMinPacket = 0;
353 if (macType == kNETC_ExpressMAC)
354 {
355 #if defined(FSL_FEATURE_NETC_HAS_ERRATA_051711) && FSL_FEATURE_NETC_HAS_ERRATA_051711
356 /* ERRATA051711: MAC statistic counters TEOCT and TOCT are inaccurate after Pause frames are transmitted with
357 flexible preamble enabled (PM0_TX_IPG_PREAMBLE[FLEX_PREAMBLE_EN] = 1) and flexible preamble count
358 (PM0_TX_IPG_PREAMBLE[FLEX_PREAMBLE_CNT]) set to less than 7. */
359 uint32_t flexPreambleCnt = (base->PM0_TX_IPG_PREAMBLE & NETC_ETH_LINK_PM0_TX_IPG_PREAMBLE_FLEX_PREAMBLE_CNT_MASK) >> NETC_ETH_LINK_PM0_TX_IPG_PREAMBLE_FLEX_PREAMBLE_CNT_SHIFT;
360 if ((base->PM0_TX_IPG_PREAMBLE & NETC_ETH_LINK_PM0_TX_IPG_PREAMBLE_FLEX_PREAMBLE_EN_MASK) != 0U)
361 {
362 statistic->totalOctet = base->PM0_TEOCTN - base->PM0_TXPFN * ((uint64_t)7U - flexPreambleCnt);
363 statistic->validOctet = base->PM0_TOCTN - base->PM0_TXPFN * ((uint64_t)7U - flexPreambleCnt);
364 }
365 else
366 {
367 statistic->totalOctet = base->PM0_TEOCTN;
368 statistic->validOctet = base->PM0_TOCTN;
369 }
370 #else
371 statistic->totalOctet = base->PM0_TEOCTN;
372 statistic->validOctet = base->PM0_TOCTN;
373 #endif
374 statistic->pauseFrame = base->PM0_TXPFN;
375 #if defined(FSL_FEATURE_NETC_HAS_ERRATA_051710) && FSL_FEATURE_NETC_HAS_ERRATA_051710
376 /* ERRATA051710: After one or more late collision or excessive collision events, counters PMa_TOCTn and PMa_TFRMn will be higher than
377 expected. The accurate value cannot be recovered for PMa_TOCTn, but PMa_TRFMn can be recovered as follows formula. */
378 statistic->validFrame = base->PM0_TFRMN - base->PM0_TLCOLN - base->PM0_TECOLN;
379 #else
380 statistic->validFrame = base->PM0_TFRMN;
381 #endif
382 statistic->vlanFrame = base->PM0_TVLANN;
383 statistic->unicastFrame = base->PM0_TUCAN;
384 statistic->multicastFrame = base->PM0_TMCAN;
385 statistic->boradcastFrame = base->PM0_TBCAN;
386 statistic->totalPacket = base->PM0_TPKTN;
387 statistic->total64BPacket = base->PM0_T64N;
388 statistic->total65To127BPacket = base->PM0_T127N;
389 statistic->total128To255BPacket = base->PM0_T255N;
390 statistic->total256To511BPacket = base->PM0_T511N;
391 statistic->total511To1023BPacket = base->PM0_T1023N;
392 statistic->total1024To1522BPacket = base->PM0_T1522N;
393 statistic->total1523ToMaxBPacket = base->PM0_T1523XN;
394 statistic->controlPacket = base->PM0_TCNPN;
395 }
396 else if (macType == kNETC_PreemptableMAC)
397 {
398 statistic->totalOctet = base->PM1_TEOCTN;
399 statistic->validOctet = base->PM1_TOCTN;
400 statistic->pauseFrame = base->PM1_TXPFN;
401 #if defined(FSL_FEATURE_NETC_HAS_ERRATA_051710) && FSL_FEATURE_NETC_HAS_ERRATA_051710
402 /* ERRATA051710: After one or more late collision or excessive collision events, counters PMa_TOCTn and PMa_TFRMn will be higher than
403 expected. The accurate value cannot be recovered for PMa_TOCTn, but PMa_TRFMn can be recovered as follows formula. */
404 statistic->validFrame = base->PM1_TFRMN - base->PM1_TLCOLN - base->PM1_TECOLN;
405 #else
406 statistic->validFrame = base->PM1_TFRMN;
407 #endif
408 statistic->vlanFrame = base->PM1_TVLANN;
409 statistic->unicastFrame = base->PM1_TUCAN;
410 statistic->multicastFrame = base->PM1_TMCAN;
411 statistic->boradcastFrame = base->PM1_TBCAN;
412 statistic->totalPacket = base->PM1_TPKTN;
413 statistic->total64BPacket = base->PM1_T64N;
414 statistic->total65To127BPacket = base->PM1_T127N;
415 statistic->total128To255BPacket = base->PM1_T255N;
416 statistic->total256To511BPacket = base->PM1_T511N;
417 statistic->total511To1023BPacket = base->PM1_T1023N;
418 statistic->total1024To1522BPacket = base->PM1_T1522N;
419 statistic->total1523ToMaxBPacket = base->PM1_T1523XN;
420 statistic->controlPacket = base->PM1_TCNPN;
421 }
422 else
423 {
424 ; /* Intentional empty */
425 }
426
427 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
428 EnableGlobalIRQ(primask);
429 #endif
430 }
431
NETC_PortGetPhyMacRxStatistic(NETC_ETH_LINK_Type * base,netc_port_phy_mac_type_t macType,netc_port_phy_mac_traffic_statistic_t * statistic)432 void NETC_PortGetPhyMacRxStatistic(NETC_ETH_LINK_Type *base,
433 netc_port_phy_mac_type_t macType,
434 netc_port_phy_mac_traffic_statistic_t *statistic)
435 {
436 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
437 uint32_t primask;
438
439 primask = DisableGlobalIRQ();
440 #endif
441
442 if (macType == kNETC_ExpressMAC)
443 {
444 statistic->totalOctet = base->PM0_REOCTN;
445 statistic->validOctet = base->PM0_ROCTN;
446 statistic->pauseFrame = base->PM0_RXPFN;
447 statistic->validFrame = base->PM0_RFRMN;
448 statistic->vlanFrame = base->PM0_RVLANN;
449 statistic->unicastFrame = base->PM0_RUCAN;
450 statistic->multicastFrame = base->PM0_RMCAN;
451 statistic->boradcastFrame = base->PM0_RBCAN;
452 statistic->totalPacket = base->PM0_RPKTN;
453 statistic->total64BPacket = base->PM0_R64N;
454 statistic->total65To127BPacket = base->PM0_R127N;
455 statistic->total128To255BPacket = base->PM0_R255N;
456 statistic->total256To511BPacket = base->PM0_R511N;
457 statistic->total511To1023BPacket = base->PM0_R1023N;
458 statistic->total1024To1522BPacket = base->PM0_R1522N;
459 statistic->total1523ToMaxBPacket = base->PM0_R1523XN;
460 statistic->controlPacket = base->PM0_RCNPN;
461 #if defined(NETC_ETH_LINK_PM0_RMIN63N_RMIN63n_MASK)
462 statistic->rxMinPacket = base->PM0_RMIN63N;
463 #endif
464 }
465 else if (macType == kNETC_PreemptableMAC)
466 {
467 statistic->totalOctet = base->PM1_REOCTN;
468 statistic->validOctet = base->PM1_ROCTN;
469 statistic->pauseFrame = base->PM1_RXPFN;
470 statistic->validFrame = base->PM1_RFRMN;
471 statistic->vlanFrame = base->PM1_RVLANN;
472 statistic->unicastFrame = base->PM1_RUCAN;
473 statistic->multicastFrame = base->PM1_RMCAN;
474 statistic->boradcastFrame = base->PM1_RBCAN;
475 statistic->totalPacket = base->PM1_RPKTN;
476 statistic->total64BPacket = base->PM1_R64N;
477 statistic->total65To127BPacket = base->PM1_R127N;
478 statistic->total128To255BPacket = base->PM1_R255N;
479 statistic->total256To511BPacket = base->PM1_R511N;
480 statistic->total511To1023BPacket = base->PM1_R1023N;
481 statistic->total1024To1522BPacket = base->PM1_R1522N;
482 statistic->total1523ToMaxBPacket = base->PM1_R1523XN;
483 statistic->controlPacket = base->PM1_RCNPN;
484 #if defined(NETC_ETH_LINK_PM1_RMIN63N_RMIN63n_MASK)
485 statistic->rxMinPacket = base->PM1_RMIN63N;
486 #endif
487 }
488 else
489 {
490 ; /* Intentional empty */
491 }
492
493 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
494 EnableGlobalIRQ(primask);
495 #endif
496 }
497
NETC_PortGetPhyMacDiscardStatistic(NETC_ETH_LINK_Type * base,netc_port_phy_mac_type_t macType,netc_port_phy_mac_discard_statistic_t * statistic)498 void NETC_PortGetPhyMacDiscardStatistic(NETC_ETH_LINK_Type *base,
499 netc_port_phy_mac_type_t macType,
500 netc_port_phy_mac_discard_statistic_t *statistic)
501 {
502 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
503 uint32_t primask;
504
505 primask = DisableGlobalIRQ();
506 #endif
507 if (macType == kNETC_ExpressMAC)
508 {
509 statistic->rxError = base->PM0_RERRN;
510 statistic->rxUndersized = base->PM0_RUNDN;
511 statistic->rxOversized = base->PM0_ROVRN;
512 statistic->rxErrorFCS = base->PM0_RFCSN;
513 statistic->rxFragment = base->PM0_RFRGN;
514 statistic->rxJabber = base->PM0_RJBRN;
515 statistic->rxDiscard = base->PM0_RDRPN;
516 statistic->rxDiscardNoTruncated = base->PM0_RDRNTPN;
517 statistic->txErrorFCS = base->PM0_TERRN;
518 statistic->txUndersized = base->PM0_TUNDN;
519 }
520 else if (macType == kNETC_PreemptableMAC)
521 {
522 statistic->rxError = base->PM1_RERRN;
523 statistic->rxUndersized = base->PM1_RUNDN;
524 statistic->rxOversized = base->PM1_ROVRN;
525 statistic->rxErrorFCS = base->PM1_RFCSN;
526 statistic->rxFragment = base->PM1_RFRGN;
527 statistic->rxJabber = base->PM1_RJBRN;
528 statistic->rxDiscard = base->PM1_RDRPN;
529 statistic->rxDiscardNoTruncated = base->PM1_RDRNTPN;
530 statistic->txErrorFCS = base->PM1_TERRN;
531 statistic->txUndersized = base->PM1_TUNDN;
532 }
533 else
534 {
535 ; /* Intentional empty */
536 }
537 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
538 EnableGlobalIRQ(primask);
539 #endif
540 }
541
NETC_PortGetPhyMacPreemptionStatistic(NETC_ETH_LINK_Type * base,netc_port_phy_mac_preemption_statistic_t * statistic)542 void NETC_PortGetPhyMacPreemptionStatistic(NETC_ETH_LINK_Type *base,
543 netc_port_phy_mac_preemption_statistic_t *statistic)
544 {
545 statistic->rxReassembledFrame = base->MAC_MERGE_MMFAOCR;
546 #if defined(FSL_FEATURE_NETC_HAS_ERRATA_051707) && FSL_FEATURE_NETC_HAS_ERRATA_051707
547 /* ERRATA051707: The host that is reading MAC_MERGE_MMFAECR register should check status of PM1_RFCS. If the PM1_RFCS indicates no
548 error then MAC_MERGE_MMFAECR is valid and can be used if on other hand there is an error reported in PM1_RFCS register
549 then MAC_MERGE_MMFAECR might be incorrect and should be treated accordingly. */
550 statistic->rxReassembledError = (base->PM1_RFCSN == 0U) ? base->MAC_MERGE_MMFAECR : 0U;
551 #else
552 statistic->rxReassembledError = base->MAC_MERGE_MMFAECR;
553 #endif
554 statistic->rxMPacket = base->MAC_MERGE_MMFCRXR;
555 statistic->rxSMDError = base->MAC_MERGE_MMFSECR;
556 statistic->txPreemptionReq = base->MAC_MERGE_MMHCR;
557 statistic->txMPacket = base->MAC_MERGE_MMFCTXR;
558 }
559
560 #if !(defined(FSL_FEATURE_NETC_HAS_NO_SWITCH) && FSL_FEATURE_NETC_HAS_NO_SWITCH)
NETC_PortGetPseudoMacTrafficStatistic(NETC_PSEUDO_LINK_Type * base,bool getTx,netc_port_pseudo_mac_traffic_statistic_t * statistic)561 void NETC_PortGetPseudoMacTrafficStatistic(NETC_PSEUDO_LINK_Type *base,
562 bool getTx,
563 netc_port_pseudo_mac_traffic_statistic_t *statistic)
564 {
565 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
566 uint32_t primask;
567
568 primask = DisableGlobalIRQ();
569 #endif
570 if (getTx)
571 {
572 statistic->totalOctet = ((uint64_t)base->PPMTOCR[1] << 32U) | base->PPMTOCR[0];
573 statistic->unicastFrame = ((uint64_t)base->PPMTUFCR[1] << 32U) | base->PPMTUFCR[0];
574 statistic->multicastFrame = ((uint64_t)base->PPMTMFCR[1] << 32U) | base->PPMTMFCR[0];
575 statistic->boradcastFrame = ((uint64_t)base->PPMTBFCR[1] << 32U) | base->PPMTBFCR[0];
576 }
577 else
578 {
579 statistic->totalOctet = ((uint64_t)base->PPMROCR[1] << 32U) | base->PPMROCR[0];
580 statistic->unicastFrame = ((uint64_t)base->PPMRUFCR[1] << 32U) | base->PPMRUFCR[0];
581 statistic->multicastFrame = ((uint64_t)base->PPMRMFCR[1] << 32U) | base->PPMRMFCR[0];
582 statistic->boradcastFrame = ((uint64_t)base->PPMRBFCR[1] << 32U) | base->PPMRBFCR[0];
583 }
584 #if (defined(FSL_FEATURE_NETC_HAS_ERRATA_050679) && FSL_FEATURE_NETC_HAS_ERRATA_050679)
585 EnableGlobalIRQ(primask);
586 #endif
587 }
588 #endif
589
NETC_PortConfigTcCBS(NETC_PORT_Type * base,netc_hw_tc_idx_t tcIdx,const netc_port_tc_cbs_config_t * config)590 status_t NETC_PortConfigTcCBS(NETC_PORT_Type *base, netc_hw_tc_idx_t tcIdx, const netc_port_tc_cbs_config_t *config)
591 {
592 status_t result = kStatus_Success;
593 uint8_t usedBw = 0U;
594 uint8_t index;
595
596 for (index = (uint8_t)kNETC_TxTC0; index <= (uint8_t)kNETC_TxTC7; index++)
597 {
598 if (index == (uint8_t)tcIdx)
599 {
600 continue;
601 }
602
603 if (0U != (base->TCT_NUM[index].PTCCBSR0 & NETC_PORT_PTCCBSR0_CBSE_MASK))
604 {
605 usedBw += (uint8_t)(base->TCT_NUM[index].PTCCBSR0 & NETC_PORT_PTCCBSR0_BW_MASK);
606 }
607 }
608
609 if ((usedBw + config->bwWeight) <= 100U)
610 {
611 base->TCT_NUM[tcIdx].PTCCBSR0 = NETC_PORT_PTCCBSR0_BW(config->bwWeight) | NETC_PORT_PTCCBSR0_CBSE_MASK;
612 base->TCT_NUM[tcIdx].PTCCBSR1 = NETC_PORT_PTCCBSR1_HI_CREDIT(config->hiCredit);
613 }
614 else
615 {
616 /* The sum of all traffic class credit-based shaper's bandwidth cannot execeed 100 */
617 result = kStatus_Fail;
618 }
619
620 return result;
621 }
622
NETC_PortEthMacGracefulStop(NETC_PORT_Type * base)623 void NETC_PortEthMacGracefulStop(NETC_PORT_Type *base)
624 {
625 NETC_ETH_LINK_Type *eth = (NETC_ETH_LINK_Type *)((uintptr_t)base + 0x1000U);
626 bool hasPM1 = 0U != (eth->MAC_MERGE_MMCSR & NETC_ETH_LINK_MAC_MERGE_MMCSR_ME_MASK);
627
628 /* In order to stop receive */
629 eth->PM0_COMMAND_CONFIG &= ~NETC_ETH_LINK_PM0_COMMAND_CONFIG_RX_EN_MASK;
630 while (0U == (eth->PM0_IEVENT & NETC_ETH_LINK_PM0_IEVENT_RX_EMPTY_MASK))
631 {
632 }
633 if (hasPM1)
634 {
635 eth->PM1_COMMAND_CONFIG &= ~NETC_ETH_LINK_PM1_COMMAND_CONFIG_RX_EN_MASK;
636 while (0U == (eth->PM1_IEVENT & NETC_ETH_LINK_PM1_IEVENT_RX_EMPTY_MASK))
637 {
638 }
639 }
640 while (0U != (base->PSR & NETC_PORT_PSR_RX_BUSY_MASK))
641 {
642 }
643 base->POR |= NETC_PORT_POR_RXDIS_MASK;
644
645 /* In order to stop transmit */
646 base->POR |= NETC_PORT_POR_TXDIS_MASK;
647 while (0U == (eth->PM0_IEVENT & NETC_ETH_LINK_PM0_IEVENT_TX_EMPTY_MASK))
648 {
649 }
650 if (hasPM1)
651 {
652 while (0U == (eth->PM1_IEVENT & NETC_ETH_LINK_PM1_IEVENT_TX_EMPTY_MASK))
653 {
654 }
655 }
656 /* Wait 64 byte time for Tx packet transmission to complete. */
657 SDK_DelayAtLeastUs(512, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY);
658 eth->PM0_COMMAND_CONFIG &= ~NETC_ETH_LINK_PM0_COMMAND_CONFIG_TX_EN_MASK;
659 if (hasPM1)
660 {
661 eth->PM1_COMMAND_CONFIG &= ~NETC_ETH_LINK_PM1_COMMAND_CONFIG_TX_EN_MASK;
662 }
663 }
664