common: Drop linux/delay.h from common header
[oweals/u-boot.git] / drivers / net / ftmac100.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Faraday FTMAC100 Ethernet
4  *
5  * (C) Copyright 2009 Faraday Technology
6  * Po-Yu Chuang <ratbert@faraday-tech.com>
7  */
8
9 #include <config.h>
10 #include <common.h>
11 #include <cpu_func.h>
12 #include <env.h>
13 #include <malloc.h>
14 #include <net.h>
15 #include <linux/delay.h>
16 #include <linux/io.h>
17
18 #include "ftmac100.h"
19 #ifdef CONFIG_DM_ETH
20 #include <dm.h>
21 DECLARE_GLOBAL_DATA_PTR;
22 #endif
23 #define ETH_ZLEN        60
24
25 struct ftmac100_data {
26         struct ftmac100_txdes txdes[1];
27         struct ftmac100_rxdes rxdes[PKTBUFSRX];
28         int rx_index;
29         const char *name;
30         phys_addr_t iobase;
31 };
32
33 /*
34  * Reset MAC
35  */
36 static void ftmac100_reset(struct ftmac100_data *priv)
37 {
38         struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
39
40         debug ("%s()\n", __func__);
41
42         writel (FTMAC100_MACCR_SW_RST, &ftmac100->maccr);
43
44         while (readl (&ftmac100->maccr) & FTMAC100_MACCR_SW_RST)
45                 mdelay(1);
46         /*
47          * When soft reset complete, write mac address immediately maybe fail somehow
48          *  Wait for a while can avoid this problem
49          */
50         mdelay(1);
51 }
52
53 /*
54  * Set MAC address
55  */
56 static void ftmac100_set_mac(struct ftmac100_data *priv ,
57         const unsigned char *mac)
58 {
59         struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
60         unsigned int maddr = mac[0] << 8 | mac[1];
61         unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
62
63         debug ("%s(%x %x)\n", __func__, maddr, laddr);
64
65         writel (maddr, &ftmac100->mac_madr);
66         writel (laddr, &ftmac100->mac_ladr);
67 }
68
69 /*
70  * Disable MAC
71  */
72 static void _ftmac100_halt(struct ftmac100_data *priv)
73 {
74         struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
75         debug ("%s()\n", __func__);
76         writel (0, &ftmac100->maccr);
77 }
78
79 /*
80  * Initialize MAC
81  */
82 static int _ftmac100_init(struct ftmac100_data *priv, unsigned char enetaddr[6])
83 {
84         struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
85         struct ftmac100_txdes *txdes = priv->txdes;
86         struct ftmac100_rxdes *rxdes = priv->rxdes;
87         unsigned int maccr;
88         int i;
89         debug ("%s()\n", __func__);
90
91         ftmac100_reset(priv);
92
93         /* set the ethernet address */
94         ftmac100_set_mac(priv, enetaddr);
95
96
97         /* disable all interrupts */
98
99         writel (0, &ftmac100->imr);
100
101         /* initialize descriptors */
102
103         priv->rx_index = 0;
104
105         txdes[0].txdes1                 = FTMAC100_TXDES1_EDOTR;
106         rxdes[PKTBUFSRX - 1].rxdes1     = FTMAC100_RXDES1_EDORR;
107
108         for (i = 0; i < PKTBUFSRX; i++) {
109                 /* RXBUF_BADR */
110                 rxdes[i].rxdes2 = (unsigned int)(unsigned long)net_rx_packets[i];
111                 rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN);
112                 rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;
113         }
114
115         /* transmit ring */
116
117         writel ((unsigned long)txdes, &ftmac100->txr_badr);
118
119         /* receive ring */
120
121         writel ((unsigned long)rxdes, &ftmac100->rxr_badr);
122
123         /* poll receive descriptor automatically */
124
125         writel (FTMAC100_APTC_RXPOLL_CNT (1), &ftmac100->aptc);
126
127         /* enable transmitter, receiver */
128
129         maccr = FTMAC100_MACCR_XMT_EN |
130                 FTMAC100_MACCR_RCV_EN |
131                 FTMAC100_MACCR_XDMA_EN |
132                 FTMAC100_MACCR_RDMA_EN |
133                 FTMAC100_MACCR_CRC_APD |
134                 FTMAC100_MACCR_ENRX_IN_HALFTX |
135                 FTMAC100_MACCR_RX_RUNT |
136                 FTMAC100_MACCR_RX_BROADPKT;
137
138         writel (maccr, &ftmac100->maccr);
139
140         return 0;
141 }
142
143 /*
144  * Free receiving buffer
145  */
146 static int _ftmac100_free_pkt(struct ftmac100_data *priv)
147 {
148         struct ftmac100_rxdes *curr_des;
149         curr_des = &priv->rxdes[priv->rx_index];
150         /* release buffer to DMA */
151         curr_des->rxdes0 |= FTMAC100_RXDES0_RXDMA_OWN;
152         priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
153         return 0;
154 }
155
156 /*
157  * Receive a data block via Ethernet
158  */
159 static int __ftmac100_recv(struct ftmac100_data *priv)
160 {
161         struct ftmac100_rxdes *curr_des;
162         unsigned short rxlen;
163
164         curr_des = &priv->rxdes[priv->rx_index];
165         if (curr_des->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN)
166                 return 0;
167
168         if (curr_des->rxdes0 & (FTMAC100_RXDES0_RX_ERR |
169                                 FTMAC100_RXDES0_CRC_ERR |
170                                 FTMAC100_RXDES0_FTL |
171                                 FTMAC100_RXDES0_RUNT |
172                                 FTMAC100_RXDES0_RX_ODD_NB)) {
173                 return 0;
174         }
175
176         rxlen = FTMAC100_RXDES0_RFL (curr_des->rxdes0);
177         invalidate_dcache_range(curr_des->rxdes2,curr_des->rxdes2+rxlen);
178         debug ("%s(): RX buffer %d, %x received\n",
179                __func__, priv->rx_index, rxlen);
180
181         return rxlen;
182 }
183
184 /*
185  * Send a data block via Ethernet
186  */
187 static int _ftmac100_send(struct ftmac100_data *priv, void *packet, int length)
188 {
189         struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
190         struct ftmac100_txdes *curr_des = priv->txdes;
191         ulong start;
192
193         if (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
194                 debug ("%s(): no TX descriptor available\n", __func__);
195                 return -1;
196         }
197
198         debug ("%s(%lx, %x)\n", __func__, (unsigned long)packet, length);
199
200         length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
201
202         /* initiate a transmit sequence */
203
204         flush_dcache_range((unsigned long)packet,(unsigned long)packet+length);
205         curr_des->txdes2 = (unsigned int)(unsigned long)packet; /* TXBUF_BADR */
206
207         curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;
208         curr_des->txdes1 |= FTMAC100_TXDES1_FTS |
209                             FTMAC100_TXDES1_LTS |
210                             FTMAC100_TXDES1_TXBUF_SIZE (length);
211
212         curr_des->txdes0 = FTMAC100_TXDES0_TXDMA_OWN;
213
214         /* start transmit */
215
216         writel (1, &ftmac100->txpd);
217
218         /* wait for transfer to succeed */
219
220         start = get_timer(0);
221         while (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
222                 if (get_timer(start) >= 5) {
223                         debug ("%s(): timed out\n", __func__);
224                         return -1;
225                 }
226         }
227
228         debug ("%s(): packet sent\n", __func__);
229
230         return 0;
231 }
232
233 #ifndef CONFIG_DM_ETH
234 /*
235  * disable transmitter, receiver
236  */
237 static void ftmac100_halt(struct eth_device *dev)
238 {
239         struct ftmac100_data *priv = dev->priv;
240         return _ftmac100_halt(priv);
241 }
242
243 static int ftmac100_init(struct eth_device *dev, bd_t *bd)
244 {
245         struct ftmac100_data *priv = dev->priv;
246         return _ftmac100_init(priv , dev->enetaddr);
247 }
248
249 static int _ftmac100_recv(struct ftmac100_data *priv)
250 {
251         struct ftmac100_rxdes *curr_des;
252         unsigned short len;
253         curr_des = &priv->rxdes[priv->rx_index];
254         len = __ftmac100_recv(priv);
255         if (len) {
256                 /* pass the packet up to the protocol layers. */
257                 net_process_received_packet((void *)curr_des->rxdes2, len);
258                 _ftmac100_free_pkt(priv);
259         }
260         return len ? 1 : 0;
261 }
262
263 /*
264  * Get a data block via Ethernet
265  */
266 static int ftmac100_recv(struct eth_device *dev)
267 {
268         struct ftmac100_data *priv = dev->priv;
269         return _ftmac100_recv(priv);
270 }
271
272 /*
273  * Send a data block via Ethernet
274  */
275 static int ftmac100_send(struct eth_device *dev, void *packet, int length)
276 {
277         struct ftmac100_data *priv = dev->priv;
278         return _ftmac100_send(priv , packet , length);
279 }
280
281 int ftmac100_initialize (bd_t *bd)
282 {
283         struct eth_device *dev;
284         struct ftmac100_data *priv;
285         dev = malloc (sizeof *dev);
286         if (!dev) {
287                 printf ("%s(): failed to allocate dev\n", __func__);
288                 goto out;
289         }
290         /* Transmit and receive descriptors should align to 16 bytes */
291         priv = memalign (16, sizeof (struct ftmac100_data));
292         if (!priv) {
293                 printf ("%s(): failed to allocate priv\n", __func__);
294                 goto free_dev;
295         }
296         memset (dev, 0, sizeof (*dev));
297         memset (priv, 0, sizeof (*priv));
298
299         strcpy(dev->name, "FTMAC100");
300         dev->iobase     = CONFIG_FTMAC100_BASE;
301         dev->init       = ftmac100_init;
302         dev->halt       = ftmac100_halt;
303         dev->send       = ftmac100_send;
304         dev->recv       = ftmac100_recv;
305         dev->priv       = priv;
306         priv->iobase    = dev->iobase;
307         eth_register (dev);
308
309         return 1;
310
311 free_dev:
312         free (dev);
313 out:
314         return 0;
315 }
316 #endif
317
318 #ifdef CONFIG_DM_ETH
319 static int ftmac100_start(struct udevice *dev)
320 {
321         struct eth_pdata *plat = dev_get_platdata(dev);
322         struct ftmac100_data *priv = dev_get_priv(dev);
323
324         return _ftmac100_init(priv, plat->enetaddr);
325 }
326
327 static void ftmac100_stop(struct udevice *dev)
328 {
329         struct ftmac100_data *priv = dev_get_priv(dev);
330         _ftmac100_halt(priv);
331 }
332
333 static int ftmac100_send(struct udevice *dev, void *packet, int length)
334 {
335         struct ftmac100_data *priv = dev_get_priv(dev);
336         int ret;
337         ret = _ftmac100_send(priv , packet , length);
338         return ret ? 0 : -ETIMEDOUT;
339 }
340
341 static int ftmac100_recv(struct udevice *dev, int flags, uchar **packetp)
342 {
343         struct ftmac100_data *priv = dev_get_priv(dev);
344         struct ftmac100_rxdes *curr_des;
345         curr_des = &priv->rxdes[priv->rx_index];
346         int len;
347         len = __ftmac100_recv(priv);
348         if (len)
349                 *packetp = (uchar *)(unsigned long)curr_des->rxdes2;
350
351         return len ? len : -EAGAIN;
352 }
353
354 static int ftmac100_free_pkt(struct udevice *dev, uchar *packet, int length)
355 {
356         struct ftmac100_data *priv = dev_get_priv(dev);
357         _ftmac100_free_pkt(priv);
358         return 0;
359 }
360
361 int ftmac100_read_rom_hwaddr(struct udevice *dev)
362 {
363         struct eth_pdata *pdata = dev_get_platdata(dev);
364         eth_env_get_enetaddr("ethaddr", pdata->enetaddr);
365         return 0;
366 }
367
368 static const char *dtbmacaddr(u32 ifno)
369 {
370         int node, len;
371         char enet[16];
372         const char *mac;
373         const char *path;
374         if (gd->fdt_blob == NULL) {
375                 printf("%s: don't have a valid gd->fdt_blob!\n", __func__);
376                 return NULL;
377         }
378         node = fdt_path_offset(gd->fdt_blob, "/aliases");
379         if (node < 0)
380                 return NULL;
381
382         sprintf(enet, "ethernet%d", ifno);
383         path = fdt_getprop(gd->fdt_blob, node, enet, NULL);
384         if (!path) {
385                 printf("no alias for %s\n", enet);
386                 return NULL;
387         }
388         node = fdt_path_offset(gd->fdt_blob, path);
389         mac = fdt_getprop(gd->fdt_blob, node, "mac-address", &len);
390         if (mac && is_valid_ethaddr((u8 *)mac))
391                 return mac;
392
393         return NULL;
394 }
395
396 static int ftmac100_ofdata_to_platdata(struct udevice *dev)
397 {
398         struct ftmac100_data *priv = dev_get_priv(dev);
399         struct eth_pdata *pdata = dev_get_platdata(dev);
400         const char *mac;
401         pdata->iobase = devfdt_get_addr(dev);
402         priv->iobase = pdata->iobase;
403         mac = dtbmacaddr(0);
404         if (mac)
405                 memcpy(pdata->enetaddr , mac , 6);
406
407         return 0;
408 }
409
410 static int ftmac100_probe(struct udevice *dev)
411 {
412         struct ftmac100_data *priv = dev_get_priv(dev);
413         priv->name = dev->name;
414         return 0;
415 }
416
417 static int ftmac100_bind(struct udevice *dev)
418 {
419         return device_set_name(dev, dev->name);
420 }
421
422 static const struct eth_ops ftmac100_ops = {
423         .start  = ftmac100_start,
424         .send   = ftmac100_send,
425         .recv   = ftmac100_recv,
426         .stop   = ftmac100_stop,
427         .free_pkt = ftmac100_free_pkt,
428 };
429
430 static const struct udevice_id ftmac100_ids[] = {
431         { .compatible = "andestech,atmac100" },
432         { }
433 };
434
435 U_BOOT_DRIVER(ftmac100) = {
436         .name   = "nds32_mac",
437         .id     = UCLASS_ETH,
438         .of_match = ftmac100_ids,
439         .bind   = ftmac100_bind,
440         .ofdata_to_platdata = ftmac100_ofdata_to_platdata,
441         .probe  = ftmac100_probe,
442         .ops    = &ftmac100_ops,
443         .priv_auto_alloc_size = sizeof(struct ftmac100_data),
444         .platdata_auto_alloc_size = sizeof(struct eth_pdata),
445         .flags  = DM_FLAG_ALLOC_PRIV_DMA,
446 };
447 #endif