1 /*
2 * Copyright 2021-2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "fsl_netc_hw_enetc.h"
8
NETC_EnetcGetCapability(NETC_ENETC_Type * base,netc_enetc_cap_t * capability)9 void NETC_EnetcGetCapability(NETC_ENETC_Type *base, netc_enetc_cap_t *capability)
10 {
11 uint32_t cap;
12
13 cap = base->ECAPR0;
14 capability->funcSafety = ((cap & NETC_ENETC_ECAPR0_FS_MASK) != 0U);
15 capability->wol = ((cap & NETC_ENETC_ECAPR0_WO_MASK) != 0U);
16 capability->rss = ((cap & NETC_ENETC_ECAPR0_RSS_MASK) != 0U);
17 capability->tsd = ((cap & NETC_ENETC_ECAPR0_TSD_MASK) != 0U);
18 capability->rfs = ((cap & NETC_ENETC_ECAPR0_RFS_MASK) != 0U);
19
20 cap = base->ECAPR1;
21 capability->ipvNum = ((cap & NETC_ENETC_ECAPR1_NUM_IPV_MASK) != 0U) ? 16U : 8U;
22 capability->vsiNum = (cap & NETC_ENETC_ECAPR1_NUM_VSI_MASK) >> NETC_ENETC_ECAPR1_NUM_VSI_SHIFT;
23 capability->msixNum = (cap & NETC_ENETC_ECAPR1_NUM_MSIX_MASK) >> NETC_ENETC_ECAPR1_NUM_MSIX_SHIFT;
24 capability->tcsNum = 1U + ((cap & NETC_ENETC_ECAPR1_NUM_TCS_MASK) >> NETC_ENETC_ECAPR1_NUM_TCS_SHIFT);
25 capability->uchNum =
26 64U * ((uint16_t)1U << ((cap & NETC_ENETC_ECAPR1_NUM_UCH_MASK) >> NETC_ENETC_ECAPR1_NUM_UCH_SHIFT));
27 capability->mchNum =
28 64U * ((uint16_t)1U << ((cap & NETC_ENETC_ECAPR1_NUM_MCH_MASK) >> NETC_ENETC_ECAPR1_NUM_MCH_SHIFT));
29
30 cap = base->ECAPR2;
31 capability->rxBdrNum = (uint16_t)((cap & NETC_ENETC_ECAPR2_NUM_RX_BDR_MASK) >> NETC_ENETC_ECAPR2_NUM_RX_BDR_SHIFT);
32 capability->txBdrNum = (uint16_t)(cap & NETC_ENETC_ECAPR2_NUM_TX_BDR_MASK);
33 }
34
NETC_EnetcSetSIMacAddr(NETC_ENETC_Type * base,uint8_t si,uint8_t * macAddr)35 void NETC_EnetcSetSIMacAddr(NETC_ENETC_Type *base, uint8_t si, uint8_t *macAddr)
36 {
37 /* This API is for VSI. */
38 assert(si != 0U);
39
40 uint32_t address;
41
42 /* Set physical address lower register. */
43 address = ((uint32_t *)(uintptr_t)macAddr)[0];
44 base->NUM_SI[si].PSIPMAR0 = address;
45
46 /* Set physical address high register. */
47 address = (((uint32_t)macAddr[5] << 8U) | (uint32_t)macAddr[4]);
48 base->NUM_SI[si].PSIPMAR1 = address;
49 }
50
NETC_EnetcConfigureSI(NETC_ENETC_Type * base,uint8_t si,const netc_hw_enetc_si_config_t * psConfig)51 status_t NETC_EnetcConfigureSI(NETC_ENETC_Type *base, uint8_t si, const netc_hw_enetc_si_config_t *psConfig)
52 {
53 uint16_t txBdrMax =
54 (uint16_t)((base->ECAPR2 & NETC_ENETC_ECAPR2_NUM_TX_BDR_MASK) >> NETC_ENETC_ECAPR2_NUM_TX_BDR_SHIFT);
55 uint16_t rxBdrMax =
56 (uint16_t)((base->ECAPR2 & NETC_ENETC_ECAPR2_NUM_RX_BDR_MASK) >> NETC_ENETC_ECAPR2_NUM_RX_BDR_SHIFT);
57 uint16_t siMax =
58 (uint16_t)(1U + ((base->ECAPR1 & NETC_ENETC_ECAPR1_NUM_VSI_MASK) >> NETC_ENETC_ECAPR1_NUM_VSI_SHIFT));
59 uint16_t txLeftBdr = txBdrMax;
60 uint16_t rxLeftBdr = rxBdrMax;
61
62 /* SI index ranges from 0 ~ max-1. */
63 if (si >= siMax)
64 {
65 return kStatus_InvalidArgument;
66 }
67
68 /* Minus the ring number used by SIs in front. */
69 for (uint8_t i = 0; i < si; i++)
70 {
71 txLeftBdr -= (uint16_t)((base->NUM_SI[i].PSICFGR0 & NETC_ENETC_PSICFGR0_NUM_TX_BDR_MASK) >>
72 NETC_ENETC_PSICFGR0_NUM_TX_BDR_SHIFT);
73 rxLeftBdr -= (uint16_t)((base->NUM_SI[i].PSICFGR0 & NETC_ENETC_PSICFGR0_NUM_RX_BDR_MASK) >>
74 NETC_ENETC_PSICFGR0_NUM_RX_BDR_SHIFT);
75 }
76
77 if ((psConfig->txRingUse > txLeftBdr) || (psConfig->rxRingUse > rxLeftBdr))
78 {
79 return kStatus_NETC_LackOfResource;
80 }
81
82 /* Configure the station interface. */
83 if ((NETC_EnetcHasManagement(base)) && (si == 0U))
84 {
85 /* Management ENETC SI 0 need allocated one more Tx/Rx ring to do the Switch management frames send and receive.
86 */
87 base->NUM_SI[si].PSICFGR0 =
88 NETC_ENETC_PSICFGR0_SIBW(psConfig->bandWeight) | NETC_ENETC_PSICFGR0_SIVC(psConfig->vlanCtrl) |
89 NETC_ENETC_PSICFGR0_ASE(psConfig->antiSpoofEnable) | NETC_ENETC_PSICFGR0_SIVIE(psConfig->vlanInsertEnable) |
90 NETC_ENETC_PSICFGR0_VTE(psConfig->vlanExtractEnable) |
91 NETC_ENETC_PSICFGR0_SPE(psConfig->sourcePruneEnable) |
92 NETC_ENETC_PSICFGR0_NUM_TX_BDR(psConfig->txRingUse + 1U) |
93 NETC_ENETC_PSICFGR0_NUM_RX_BDR(psConfig->rxRingUse + 1U);
94 }
95 else
96 {
97 base->NUM_SI[si].PSICFGR0 =
98 NETC_ENETC_PSICFGR0_SIBW(psConfig->bandWeight) | NETC_ENETC_PSICFGR0_SIVC(psConfig->vlanCtrl) |
99 NETC_ENETC_PSICFGR0_ASE(psConfig->antiSpoofEnable) | NETC_ENETC_PSICFGR0_SIVIE(psConfig->vlanInsertEnable) |
100 NETC_ENETC_PSICFGR0_VTE(psConfig->vlanExtractEnable) |
101 NETC_ENETC_PSICFGR0_SPE(psConfig->sourcePruneEnable) | NETC_ENETC_PSICFGR0_NUM_TX_BDR(psConfig->txRingUse) |
102 NETC_ENETC_PSICFGR0_NUM_RX_BDR(psConfig->rxRingUse);
103 }
104
105 base->NUM_SI[si].PSIVLANR =
106 NETC_ENETC_PSIVLANR_E(psConfig->enSIBaseVlan) | NETC_ENETC_PSIVLANR_TPID(psConfig->siBaseVlan.tpid) |
107 NETC_ENETC_PSIVLANR_PCP(psConfig->siBaseVlan.pcp) | NETC_ENETC_PSIVLANR_DEI(psConfig->siBaseVlan.dei) |
108 NETC_ENETC_PSIVLANR_VID(psConfig->siBaseVlan.vid);
109
110 return kStatus_Success;
111 }
112
NETC_EnetcSetMsixEntryNum(NETC_ENETC_Type * base,uint8_t si,uint32_t msixNum)113 status_t NETC_EnetcSetMsixEntryNum(NETC_ENETC_Type *base, uint8_t si, uint32_t msixNum)
114 {
115 status_t result = kStatus_Success;
116 uint16_t msixEntryMax =
117 (uint16_t)(((base->ECAPR1 & NETC_ENETC_ECAPR1_NUM_MSIX_MASK) >> NETC_ENETC_ECAPR1_NUM_MSIX_SHIFT) + 1U);
118 uint16_t leftEntry = msixEntryMax;
119 uint32_t entryNum;
120
121 /* Minus the MSIX entry used by SIs in front. */
122 for (uint8_t i = 0; i < si; i++)
123 {
124 leftEntry -= (uint16_t)(1U + ((base->NUM_SI[i].PSICFGR2 & NETC_ENETC_PSICFGR2_NUM_MSIX_MASK) >>
125 NETC_ENETC_PSICFGR2_NUM_MSIX_SHIFT));
126 }
127
128 if (msixNum > leftEntry)
129 {
130 result = kStatus_NETC_LackOfResource;
131 }
132 else
133 {
134 entryNum = (msixNum != 0U) ? msixNum : 1U;
135 base->NUM_SI[si].PSICFGR2 = NETC_ENETC_PSICFGR2_NUM_MSIX(entryNum - 1U);
136 }
137
138 return result;
139 }
140
NETC_EnetcGetPortDiscardStatistic(NETC_ENETC_Type * base,netc_enetc_port_discard_statistic_t * statistic)141 void NETC_EnetcGetPortDiscardStatistic(NETC_ENETC_Type *base, netc_enetc_port_discard_statistic_t *statistic)
142 {
143 for (uint32_t i = 0U; i < 4U; i++)
144 {
145 statistic->ingressDR[i] = base->PICDRADCR[i].PICDRDCR;
146 }
147 statistic->broadcastReject = base->PBFDSIR;
148 statistic->smacPruning = base->PFDMSAPR;
149 statistic->unicastMacFilt = base->PUFDMFR;
150 statistic->multicastMacFilt = base->PMFDMFR;
151 statistic->unicastVlanFilt = base->PUFDVFR;
152 statistic->multicastVlanFilt = base->PMFDVFR;
153 statistic->boradcastVlanFilt = base->PBFDVFR;
154 }
155
NETC_EnetcEnablePromiscuous(NETC_ENETC_Type * base,uint8_t si,bool enableUCPromis,bool enableMCPromis)156 void NETC_EnetcEnablePromiscuous(NETC_ENETC_Type *base, uint8_t si, bool enableUCPromis, bool enableMCPromis)
157 {
158 if (enableUCPromis)
159 {
160 base->PSIPMMR |= ((uint32_t)NETC_ENETC_PSIPMMR_SI0_MAC_UP_MASK << si);
161 }
162 else
163 {
164 base->PSIPMMR &= ~((uint32_t)NETC_ENETC_PSIPMMR_SI0_MAC_UP_MASK << si);
165 }
166
167 if (enableMCPromis)
168 {
169 base->PSIPMMR |= ((uint32_t)NETC_ENETC_PSIPMMR_SI0_MAC_MP_MASK << si);
170 }
171 else
172 {
173 base->PSIPMMR &= ~((uint32_t)NETC_ENETC_PSIPMMR_SI0_MAC_MP_MASK << si);
174 }
175 }
176
NETC_EnetcConfigureVlanFilter(NETC_ENETC_Type * base,uint8_t si,netc_si_l2vf_config_t * config)177 void NETC_EnetcConfigureVlanFilter(NETC_ENETC_Type *base, uint8_t si, netc_si_l2vf_config_t *config)
178 {
179 if (config->acceptUntagged)
180 {
181 base->PSIPVMR |= ((uint32_t)NETC_ENETC_PSIPVMR_SI0_VLAN_UTA_MASK << si);
182 }
183 else
184 {
185 base->PSIPVMR &= ~((uint32_t)NETC_ENETC_PSIPVMR_SI0_VLAN_UTA_MASK << si);
186 }
187
188 if (config->enPromis)
189 {
190 base->PSIPVMR |= ((uint32_t)NETC_ENETC_PSIPVMR_SI0_VLAN_P_MASK << si);
191 }
192 else
193 {
194 base->PSIPVMR &= ~((uint32_t)NETC_ENETC_PSIPVMR_SI0_VLAN_P_MASK << si);
195 }
196
197 base->PSIVLANFMR = NETC_ENETC_PSIVLANFMR_VS(config->useOuterVlanTag);
198 }
199
NETC_EnetcAddMacAddrHash(NETC_ENETC_Type * base,uint8_t si,netc_packet_type_t type,uint8_t hashIndex)200 void NETC_EnetcAddMacAddrHash(NETC_ENETC_Type *base, uint8_t si, netc_packet_type_t type, uint8_t hashIndex)
201 {
202 assert(type != kNETC_PacketBroadcast);
203
204 if (type == kNETC_PacketUnicast)
205 {
206 if (hashIndex < 32U)
207 {
208 base->NUM_SI[si].PSIUMHFR0 |= ((uint32_t)1U << hashIndex);
209 }
210 else
211 {
212 base->NUM_SI[si].PSIUMHFR1 |= ((uint32_t)1U << (hashIndex - 32U));
213 }
214 }
215 else
216 {
217 if (hashIndex < 32U)
218 {
219 base->NUM_SI[si].PSIMMHFR0 |= ((uint32_t)1U << hashIndex);
220 }
221 else
222 {
223 base->NUM_SI[si].PSIMMHFR1 |= ((uint32_t)1U << (hashIndex - 32U));
224 }
225 }
226 }
227
NETC_EnetcDelMacAddrHash(NETC_ENETC_Type * base,uint8_t si,netc_packet_type_t type,uint8_t hashIndex)228 void NETC_EnetcDelMacAddrHash(NETC_ENETC_Type *base, uint8_t si, netc_packet_type_t type, uint8_t hashIndex)
229 {
230 assert(type != kNETC_PacketBroadcast);
231
232 if (type == kNETC_PacketUnicast)
233 {
234 if (hashIndex < 32U)
235 {
236 base->NUM_SI[si].PSIUMHFR0 &= ~((uint32_t)1U << hashIndex);
237 }
238 else
239 {
240 base->NUM_SI[si].PSIUMHFR1 &= ~((uint32_t)1U << (hashIndex - 32U));
241 }
242 }
243 else
244 {
245 if (hashIndex < 32U)
246 {
247 base->NUM_SI[si].PSIMMHFR0 &= ~((uint32_t)1U << hashIndex);
248 }
249 else
250 {
251 base->NUM_SI[si].PSIMMHFR1 &= ~((uint32_t)1U << (hashIndex - 32U));
252 }
253 }
254 }
255
NETC_EnetcAddVlanHash(NETC_ENETC_Type * base,uint8_t si,uint8_t hashIndex)256 void NETC_EnetcAddVlanHash(NETC_ENETC_Type *base, uint8_t si, uint8_t hashIndex)
257 {
258 if (hashIndex < 32U)
259 {
260 base->NUM_SI[si].PSIVHFR0 |= ((uint32_t)1U << hashIndex);
261 }
262 else
263 {
264 base->NUM_SI[si].PSIVHFR1 |= ((uint32_t)1U << (hashIndex - 32U));
265 }
266 }
267
NETC_EnetcDelVlanHash(NETC_ENETC_Type * base,uint8_t si,uint8_t hashIndex)268 void NETC_EnetcDelVlanHash(NETC_ENETC_Type *base, uint8_t si, uint8_t hashIndex)
269 {
270 if (hashIndex < 32U)
271 {
272 base->NUM_SI[si].PSIVHFR0 &= ~((uint32_t)1U << hashIndex);
273 }
274 else
275 {
276 base->NUM_SI[si].PSIVHFR1 &= ~((uint32_t)1U << (hashIndex - 32U));
277 }
278 }
279