1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2020-2021 NXP
5 #include <ethdev_vdev.h>
6 #include <ethdev_driver.h>
8 #include "enet_pmd_logs.h"
9 #include "enet_ethdev.h"
10 #include "enet_regs.h"
13 #define ENETFEC_NAME_PMD net_enetfec
15 /* FEC receive acceleration */
16 #define ENETFEC_RACC_IPDIS RTE_BIT32(1)
17 #define ENETFEC_RACC_PRODIS RTE_BIT32(2)
18 #define ENETFEC_RACC_SHIFT16 RTE_BIT32(7)
19 #define ENETFEC_RACC_OPTIONS (ENETFEC_RACC_IPDIS | \
22 #define ENETFEC_PAUSE_FLAG_AUTONEG 0x1
23 #define ENETFEC_PAUSE_FLAG_ENABLE 0x2
25 /* Pause frame field and FIFO threshold */
26 #define ENETFEC_FCE RTE_BIT32(5)
27 #define ENETFEC_RSEM_V 0x84
28 #define ENETFEC_RSFL_V 16
29 #define ENETFEC_RAEM_V 0x8
30 #define ENETFEC_RAFL_V 0x8
31 #define ENETFEC_OPD_V 0xFFF0
33 #define NUM_OF_BD_QUEUES 6
36 * This function is called to start or restart the ENETFEC during a link
37 * change, transmit timeout, or to reconfigure the ENETFEC. The network
38 * packet processing for this device must be stopped before this call.
41 enetfec_restart(struct rte_eth_dev *dev)
43 struct enetfec_private *fep = dev->data->dev_private;
44 uint32_t rcntl = OPT_FRAME_SIZE | 0x04;
45 uint32_t ecntl = ENETFEC_ETHEREN;
48 /* Clear any outstanding interrupt. */
49 writel(0xffffffff, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_EIR);
52 if (fep->full_duplex == FULL_DUPLEX) {
54 rte_write32(rte_cpu_to_le_32(0x04),
55 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_TCR);
59 rte_write32(0, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_TCR);
62 if (fep->quirks & QUIRK_RACC) {
63 val = rte_read32((uint8_t *)fep->hw_baseaddr_v + ENETFEC_RACC);
65 val |= ENETFEC_RACC_SHIFT16;
66 val &= ~ENETFEC_RACC_OPTIONS;
67 rte_write32(rte_cpu_to_le_32(val),
68 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_RACC);
69 rte_write32(rte_cpu_to_le_32(PKT_MAX_BUF_SIZE),
70 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_FRAME_TRL);
74 * The phy interface and speed need to get configured
75 * differently on enet-mac.
77 if (fep->quirks & QUIRK_HAS_ENETFEC_MAC) {
78 /* Enable flow control and length check */
79 rcntl |= 0x40000000 | 0x00000020;
81 /* RGMII, RMII or MII */
82 rcntl |= RTE_BIT32(6);
83 ecntl |= RTE_BIT32(5);
86 /* enable pause frame*/
87 if ((fep->flag_pause & ENETFEC_PAUSE_FLAG_ENABLE) ||
88 ((fep->flag_pause & ENETFEC_PAUSE_FLAG_AUTONEG)
89 /*&& ndev->phydev && ndev->phydev->pause*/)) {
92 /* set FIFO threshold parameter to reduce overrun */
93 rte_write32(rte_cpu_to_le_32(ENETFEC_RSEM_V),
94 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_R_FIFO_SEM);
95 rte_write32(rte_cpu_to_le_32(ENETFEC_RSFL_V),
96 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_R_FIFO_SFL);
97 rte_write32(rte_cpu_to_le_32(ENETFEC_RAEM_V),
98 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_R_FIFO_AEM);
99 rte_write32(rte_cpu_to_le_32(ENETFEC_RAFL_V),
100 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_R_FIFO_AFL);
103 rte_write32(rte_cpu_to_le_32(ENETFEC_OPD_V),
104 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_OPD);
106 rcntl &= ~ENETFEC_FCE;
109 rte_write32(rte_cpu_to_le_32(rcntl),
110 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_RCR);
112 rte_write32(0, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_IAUR);
113 rte_write32(0, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_IALR);
115 if (fep->quirks & QUIRK_HAS_ENETFEC_MAC) {
116 /* enable ENETFEC endian swap */
118 /* enable ENETFEC store and forward mode */
119 rte_write32(rte_cpu_to_le_32(1 << 8),
120 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_TFWR);
124 if (fep->quirks & QUIRK_SUPPORT_DELAYED_CLKS &&
125 fep->rgmii_txc_delay)
126 ecntl |= ENETFEC_TXC_DLY;
127 if (fep->quirks & QUIRK_SUPPORT_DELAYED_CLKS &&
128 fep->rgmii_rxc_delay)
129 ecntl |= ENETFEC_RXC_DLY;
130 /* Enable the MIB statistic event counters */
131 rte_write32(0, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_MIBC);
134 fep->enetfec_e_cntl = ecntl;
135 /* And last, enable the transmit and receive processing */
136 rte_write32(rte_cpu_to_le_32(ecntl),
137 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_ECR);
142 enetfec_eth_configure(struct rte_eth_dev *dev)
144 if (dev->data->dev_conf.rxmode.offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
145 ENETFEC_PMD_ERR("PMD does not support KEEP_CRC offload");
151 enetfec_eth_start(struct rte_eth_dev *dev)
153 enetfec_restart(dev);
158 /* ENETFEC disable function.
159 * @param[in] base ENETFEC base address
162 enetfec_disable(struct enetfec_private *fep)
164 rte_write32(rte_read32((uint8_t *)fep->hw_baseaddr_v + ENETFEC_ECR)
165 & ~(fep->enetfec_e_cntl),
166 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_ECR);
170 enetfec_eth_stop(struct rte_eth_dev *dev)
172 struct enetfec_private *fep = dev->data->dev_private;
174 dev->data->dev_started = 0;
175 enetfec_disable(fep);
180 static const struct eth_dev_ops enetfec_ops = {
181 .dev_configure = enetfec_eth_configure,
182 .dev_start = enetfec_eth_start,
183 .dev_stop = enetfec_eth_stop
187 enetfec_eth_init(struct rte_eth_dev *dev)
189 struct enetfec_private *fep = dev->data->dev_private;
191 fep->full_duplex = FULL_DUPLEX;
192 dev->dev_ops = &enetfec_ops;
193 rte_eth_dev_probing_finish(dev);
198 pmd_enetfec_probe(struct rte_vdev_device *vdev)
200 struct rte_eth_dev *dev = NULL;
201 struct enetfec_private *fep;
207 name = rte_vdev_device_name(vdev);
208 ENETFEC_PMD_LOG(INFO, "Initializing pmd_fec for %s", name);
210 dev = rte_eth_vdev_allocate(vdev, sizeof(*fep));
214 /* setup board info structure */
215 fep = dev->data->dev_private;
218 fep->max_rx_queues = ENETFEC_MAX_Q;
219 fep->max_tx_queues = ENETFEC_MAX_Q;
220 fep->quirks = QUIRK_HAS_ENETFEC_MAC | QUIRK_GBIT
223 rc = enetfec_configure();
226 rc = config_enetfec_uio(fep);
230 /* Get the BD size for distributing among six queues */
231 bdsize = (fep->bd_size) / NUM_OF_BD_QUEUES;
233 for (i = 0; i < fep->max_tx_queues; i++) {
234 fep->dma_baseaddr_t[i] = fep->bd_addr_v;
235 fep->bd_addr_p_t[i] = fep->bd_addr_p;
236 fep->bd_addr_v = (uint8_t *)fep->bd_addr_v + bdsize;
237 fep->bd_addr_p = fep->bd_addr_p + bdsize;
239 for (i = 0; i < fep->max_rx_queues; i++) {
240 fep->dma_baseaddr_r[i] = fep->bd_addr_v;
241 fep->bd_addr_p_r[i] = fep->bd_addr_p;
242 fep->bd_addr_v = (uint8_t *)fep->bd_addr_v + bdsize;
243 fep->bd_addr_p = fep->bd_addr_p + bdsize;
246 rc = enetfec_eth_init(dev);
253 ENETFEC_PMD_ERR("Failed to init");
258 pmd_enetfec_remove(struct rte_vdev_device *vdev)
260 struct rte_eth_dev *eth_dev = NULL;
263 /* find the ethdev entry */
264 eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(vdev));
268 ret = rte_eth_dev_release_port(eth_dev);
272 ENETFEC_PMD_INFO("Release enetfec sw device");
276 static struct rte_vdev_driver pmd_enetfec_drv = {
277 .probe = pmd_enetfec_probe,
278 .remove = pmd_enetfec_remove,
281 RTE_PMD_REGISTER_VDEV(ENETFEC_NAME_PMD, pmd_enetfec_drv);
282 RTE_LOG_REGISTER_DEFAULT(enetfec_logtype_pmd, NOTICE);