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