0d8d9f2324d9a1ad98c11c4ab8f53be5e72d6ef6
[dpdk.git] / drivers / net / enetfec / enet_ethdev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020-2021 NXP
3  */
4
5 #include <ethdev_vdev.h>
6 #include <ethdev_driver.h>
7 #include <rte_io.h>
8 #include "enet_pmd_logs.h"
9 #include "enet_ethdev.h"
10 #include "enet_regs.h"
11 #include "enet_uio.h"
12
13 #define ENETFEC_NAME_PMD                net_enetfec
14
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 | \
20                                                 ENETFEC_RACC_PRODIS)
21
22 #define ENETFEC_PAUSE_FLAG_AUTONEG      0x1
23 #define ENETFEC_PAUSE_FLAG_ENABLE       0x2
24
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
32
33 #define NUM_OF_BD_QUEUES                6
34
35 /*
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.
39  */
40 static void
41 enetfec_restart(struct rte_eth_dev *dev)
42 {
43         struct enetfec_private *fep = dev->data->dev_private;
44         uint32_t rcntl = OPT_FRAME_SIZE | 0x04;
45         uint32_t ecntl = ENETFEC_ETHEREN;
46         uint32_t val;
47
48         /* Clear any outstanding interrupt. */
49         writel(0xffffffff, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_EIR);
50
51         /* Enable MII mode */
52         if (fep->full_duplex == FULL_DUPLEX) {
53                 /* FD enable */
54                 rte_write32(rte_cpu_to_le_32(0x04),
55                         (uint8_t *)fep->hw_baseaddr_v + ENETFEC_TCR);
56         } else {
57         /* No Rcv on Xmit */
58                 rcntl |= 0x02;
59                 rte_write32(0, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_TCR);
60         }
61
62         if (fep->quirks & QUIRK_RACC) {
63                 val = rte_read32((uint8_t *)fep->hw_baseaddr_v + ENETFEC_RACC);
64                 /* align IP header */
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);
71         }
72
73         /*
74          * The phy interface and speed need to get configured
75          * differently on enet-mac.
76          */
77         if (fep->quirks & QUIRK_HAS_ENETFEC_MAC) {
78                 /* Enable flow control and length check */
79                 rcntl |= 0x40000000 | 0x00000020;
80
81                 /* RGMII, RMII or MII */
82                 rcntl |= RTE_BIT32(6);
83                 ecntl |= RTE_BIT32(5);
84         }
85
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*/)) {
90                 rcntl |= ENETFEC_FCE;
91
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);
101
102                 /* OPD */
103                 rte_write32(rte_cpu_to_le_32(ENETFEC_OPD_V),
104                         (uint8_t *)fep->hw_baseaddr_v + ENETFEC_OPD);
105         } else {
106                 rcntl &= ~ENETFEC_FCE;
107         }
108
109         rte_write32(rte_cpu_to_le_32(rcntl),
110                 (uint8_t *)fep->hw_baseaddr_v + ENETFEC_RCR);
111
112         rte_write32(0, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_IAUR);
113         rte_write32(0, (uint8_t *)fep->hw_baseaddr_v + ENETFEC_IALR);
114
115         if (fep->quirks & QUIRK_HAS_ENETFEC_MAC) {
116                 /* enable ENETFEC endian swap */
117                 ecntl |= (1 << 8);
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);
121         }
122         if (fep->bufdesc_ex)
123                 ecntl |= (1 << 4);
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);
132
133         ecntl |= 0x70000000;
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);
138         rte_delay_us(10);
139 }
140
141 static int
142 enetfec_eth_configure(struct rte_eth_dev *dev)
143 {
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");
146
147         return 0;
148 }
149
150 static int
151 enetfec_eth_start(struct rte_eth_dev *dev)
152 {
153         enetfec_restart(dev);
154
155         return 0;
156 }
157
158 /* ENETFEC disable function.
159  * @param[in] base      ENETFEC base address
160  */
161 static void
162 enetfec_disable(struct enetfec_private *fep)
163 {
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);
167 }
168
169 static int
170 enetfec_eth_stop(struct rte_eth_dev *dev)
171 {
172         struct enetfec_private *fep = dev->data->dev_private;
173
174         dev->data->dev_started = 0;
175         enetfec_disable(fep);
176
177         return 0;
178 }
179
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
184 };
185
186 static int
187 enetfec_eth_init(struct rte_eth_dev *dev)
188 {
189         struct enetfec_private *fep = dev->data->dev_private;
190
191         fep->full_duplex = FULL_DUPLEX;
192         dev->dev_ops = &enetfec_ops;
193         rte_eth_dev_probing_finish(dev);
194         return 0;
195 }
196
197 static int
198 pmd_enetfec_probe(struct rte_vdev_device *vdev)
199 {
200         struct rte_eth_dev *dev = NULL;
201         struct enetfec_private *fep;
202         const char *name;
203         int rc;
204         int i;
205         unsigned int bdsize;
206
207         name = rte_vdev_device_name(vdev);
208         ENETFEC_PMD_LOG(INFO, "Initializing pmd_fec for %s", name);
209
210         dev = rte_eth_vdev_allocate(vdev, sizeof(*fep));
211         if (dev == NULL)
212                 return -ENOMEM;
213
214         /* setup board info structure */
215         fep = dev->data->dev_private;
216         fep->dev = dev;
217
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
221                 | QUIRK_RACC;
222
223         rc = enetfec_configure();
224         if (rc != 0)
225                 return -ENOMEM;
226         rc = config_enetfec_uio(fep);
227         if (rc != 0)
228                 return -ENOMEM;
229
230         /* Get the BD size for distributing among six queues */
231         bdsize = (fep->bd_size) / NUM_OF_BD_QUEUES;
232
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;
238         }
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;
244         }
245
246         rc = enetfec_eth_init(dev);
247         if (rc)
248                 goto failed_init;
249
250         return 0;
251
252 failed_init:
253         ENETFEC_PMD_ERR("Failed to init");
254         return rc;
255 }
256
257 static int
258 pmd_enetfec_remove(struct rte_vdev_device *vdev)
259 {
260         struct rte_eth_dev *eth_dev = NULL;
261         int ret;
262
263         /* find the ethdev entry */
264         eth_dev = rte_eth_dev_allocated(rte_vdev_device_name(vdev));
265         if (eth_dev == NULL)
266                 return -ENODEV;
267
268         ret = rte_eth_dev_release_port(eth_dev);
269         if (ret != 0)
270                 return -EINVAL;
271
272         ENETFEC_PMD_INFO("Release enetfec sw device");
273         return 0;
274 }
275
276 static struct rte_vdev_driver pmd_enetfec_drv = {
277         .probe = pmd_enetfec_probe,
278         .remove = pmd_enetfec_remove,
279 };
280
281 RTE_PMD_REGISTER_VDEV(ENETFEC_NAME_PMD, pmd_enetfec_drv);
282 RTE_LOG_REGISTER_DEFAULT(enetfec_logtype_pmd, NOTICE);