xref: /rk3399_rockchip-uboot/drivers/net/ftmac100.c (revision 35affd7a2ff9a77b9946bf93b616228fcf218d60)
1750326e5SPo-Yu Chuang /*
2750326e5SPo-Yu Chuang  * Faraday FTMAC100 Ethernet
3750326e5SPo-Yu Chuang  *
4750326e5SPo-Yu Chuang  * (C) Copyright 2009 Faraday Technology
5750326e5SPo-Yu Chuang  * Po-Yu Chuang <ratbert@faraday-tech.com>
6750326e5SPo-Yu Chuang  *
71a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
8750326e5SPo-Yu Chuang  */
9750326e5SPo-Yu Chuang 
10750326e5SPo-Yu Chuang #include <config.h>
11750326e5SPo-Yu Chuang #include <common.h>
12750326e5SPo-Yu Chuang #include <malloc.h>
13750326e5SPo-Yu Chuang #include <net.h>
14be71a179Srick #include <linux/io.h>
15750326e5SPo-Yu Chuang 
16750326e5SPo-Yu Chuang #include "ftmac100.h"
17be71a179Srick #ifdef CONFIG_DM_ETH
18be71a179Srick #include <dm.h>
19be71a179Srick DECLARE_GLOBAL_DATA_PTR;
20be71a179Srick #endif
21750326e5SPo-Yu Chuang #define ETH_ZLEN	60
22750326e5SPo-Yu Chuang 
23750326e5SPo-Yu Chuang struct ftmac100_data {
246f6e6e09SPo-Yu Chuang 	struct ftmac100_txdes txdes[1];
256f6e6e09SPo-Yu Chuang 	struct ftmac100_rxdes rxdes[PKTBUFSRX];
26750326e5SPo-Yu Chuang 	int rx_index;
27be71a179Srick 	const char *name;
28be71a179Srick 	phys_addr_t iobase;
29750326e5SPo-Yu Chuang };
30750326e5SPo-Yu Chuang 
31750326e5SPo-Yu Chuang /*
32750326e5SPo-Yu Chuang  * Reset MAC
33750326e5SPo-Yu Chuang  */
ftmac100_reset(struct ftmac100_data * priv)34be71a179Srick static void ftmac100_reset(struct ftmac100_data *priv)
35750326e5SPo-Yu Chuang {
36be71a179Srick 	struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
37750326e5SPo-Yu Chuang 
38750326e5SPo-Yu Chuang 	debug ("%s()\n", __func__);
39750326e5SPo-Yu Chuang 
40750326e5SPo-Yu Chuang 	writel (FTMAC100_MACCR_SW_RST, &ftmac100->maccr);
41750326e5SPo-Yu Chuang 
42750326e5SPo-Yu Chuang 	while (readl (&ftmac100->maccr) & FTMAC100_MACCR_SW_RST)
43750326e5SPo-Yu Chuang 		;
44750326e5SPo-Yu Chuang }
45750326e5SPo-Yu Chuang 
46750326e5SPo-Yu Chuang /*
47750326e5SPo-Yu Chuang  * Set MAC address
48750326e5SPo-Yu Chuang  */
ftmac100_set_mac(struct ftmac100_data * priv,const unsigned char * mac)49be71a179Srick static void ftmac100_set_mac(struct ftmac100_data *priv ,
50be71a179Srick 	const unsigned char *mac)
51750326e5SPo-Yu Chuang {
52be71a179Srick 	struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
53750326e5SPo-Yu Chuang 	unsigned int maddr = mac[0] << 8 | mac[1];
54750326e5SPo-Yu Chuang 	unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
55750326e5SPo-Yu Chuang 
56750326e5SPo-Yu Chuang 	debug ("%s(%x %x)\n", __func__, maddr, laddr);
57750326e5SPo-Yu Chuang 
58750326e5SPo-Yu Chuang 	writel (maddr, &ftmac100->mac_madr);
59750326e5SPo-Yu Chuang 	writel (laddr, &ftmac100->mac_ladr);
60750326e5SPo-Yu Chuang }
61750326e5SPo-Yu Chuang 
62750326e5SPo-Yu Chuang /*
63be71a179Srick  * Disable MAC
64750326e5SPo-Yu Chuang  */
_ftmac100_halt(struct ftmac100_data * priv)65be71a179Srick static void _ftmac100_halt(struct ftmac100_data *priv)
66750326e5SPo-Yu Chuang {
67be71a179Srick 	struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
68750326e5SPo-Yu Chuang 	debug ("%s()\n", __func__);
69750326e5SPo-Yu Chuang 	writel (0, &ftmac100->maccr);
70750326e5SPo-Yu Chuang }
71750326e5SPo-Yu Chuang 
72be71a179Srick /*
73be71a179Srick  * Initialize MAC
74be71a179Srick  */
_ftmac100_init(struct ftmac100_data * priv,unsigned char enetaddr[6])75be71a179Srick static int _ftmac100_init(struct ftmac100_data *priv, unsigned char enetaddr[6])
76750326e5SPo-Yu Chuang {
77be71a179Srick 	struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
786f6e6e09SPo-Yu Chuang 	struct ftmac100_txdes *txdes = priv->txdes;
796f6e6e09SPo-Yu Chuang 	struct ftmac100_rxdes *rxdes = priv->rxdes;
80750326e5SPo-Yu Chuang 	unsigned int maccr;
81750326e5SPo-Yu Chuang 	int i;
82750326e5SPo-Yu Chuang 
83750326e5SPo-Yu Chuang 	debug ("%s()\n", __func__);
84750326e5SPo-Yu Chuang 
85be71a179Srick 	ftmac100_reset(priv);
86750326e5SPo-Yu Chuang 
87750326e5SPo-Yu Chuang 	/* set the ethernet address */
88be71a179Srick 	ftmac100_set_mac(priv, enetaddr);
89750326e5SPo-Yu Chuang 
90750326e5SPo-Yu Chuang 
91750326e5SPo-Yu Chuang 	/* disable all interrupts */
92750326e5SPo-Yu Chuang 
93750326e5SPo-Yu Chuang 	writel (0, &ftmac100->imr);
94750326e5SPo-Yu Chuang 
95750326e5SPo-Yu Chuang 	/* initialize descriptors */
96750326e5SPo-Yu Chuang 
97750326e5SPo-Yu Chuang 	priv->rx_index = 0;
98750326e5SPo-Yu Chuang 
99750326e5SPo-Yu Chuang 	txdes[0].txdes1			= FTMAC100_TXDES1_EDOTR;
100750326e5SPo-Yu Chuang 	rxdes[PKTBUFSRX - 1].rxdes1	= FTMAC100_RXDES1_EDORR;
101750326e5SPo-Yu Chuang 
102750326e5SPo-Yu Chuang 	for (i = 0; i < PKTBUFSRX; i++) {
103750326e5SPo-Yu Chuang 		/* RXBUF_BADR */
1041fd92db8SJoe Hershberger 		rxdes[i].rxdes2 = (unsigned int)net_rx_packets[i];
105750326e5SPo-Yu Chuang 		rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN);
106750326e5SPo-Yu Chuang 		rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;
107750326e5SPo-Yu Chuang 	}
108750326e5SPo-Yu Chuang 
109750326e5SPo-Yu Chuang 	/* transmit ring */
110750326e5SPo-Yu Chuang 
111750326e5SPo-Yu Chuang 	writel ((unsigned int)txdes, &ftmac100->txr_badr);
112750326e5SPo-Yu Chuang 
113750326e5SPo-Yu Chuang 	/* receive ring */
114750326e5SPo-Yu Chuang 
115750326e5SPo-Yu Chuang 	writel ((unsigned int)rxdes, &ftmac100->rxr_badr);
116750326e5SPo-Yu Chuang 
117750326e5SPo-Yu Chuang 	/* poll receive descriptor automatically */
118750326e5SPo-Yu Chuang 
119750326e5SPo-Yu Chuang 	writel (FTMAC100_APTC_RXPOLL_CNT (1), &ftmac100->aptc);
120750326e5SPo-Yu Chuang 
121750326e5SPo-Yu Chuang 	/* enable transmitter, receiver */
122750326e5SPo-Yu Chuang 
123750326e5SPo-Yu Chuang 	maccr = FTMAC100_MACCR_XMT_EN |
124750326e5SPo-Yu Chuang 		FTMAC100_MACCR_RCV_EN |
125750326e5SPo-Yu Chuang 		FTMAC100_MACCR_XDMA_EN |
126750326e5SPo-Yu Chuang 		FTMAC100_MACCR_RDMA_EN |
127750326e5SPo-Yu Chuang 		FTMAC100_MACCR_CRC_APD |
128750326e5SPo-Yu Chuang 		FTMAC100_MACCR_ENRX_IN_HALFTX |
129750326e5SPo-Yu Chuang 		FTMAC100_MACCR_RX_RUNT |
130750326e5SPo-Yu Chuang 		FTMAC100_MACCR_RX_BROADPKT;
131750326e5SPo-Yu Chuang 
132750326e5SPo-Yu Chuang 	writel (maccr, &ftmac100->maccr);
133750326e5SPo-Yu Chuang 
134750326e5SPo-Yu Chuang 	return 0;
135750326e5SPo-Yu Chuang }
136750326e5SPo-Yu Chuang 
137750326e5SPo-Yu Chuang /*
138be71a179Srick  * Free receiving buffer
139750326e5SPo-Yu Chuang  */
_ftmac100_free_pkt(struct ftmac100_data * priv)140be71a179Srick static int _ftmac100_free_pkt(struct ftmac100_data *priv)
141750326e5SPo-Yu Chuang {
142be71a179Srick 	struct ftmac100_rxdes *curr_des;
143be71a179Srick 	curr_des = &priv->rxdes[priv->rx_index];
144be71a179Srick 	/* release buffer to DMA */
145be71a179Srick 	curr_des->rxdes0 |= FTMAC100_RXDES0_RXDMA_OWN;
146be71a179Srick 	priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
147be71a179Srick 	return 0;
148be71a179Srick }
149be71a179Srick 
150be71a179Srick /*
151be71a179Srick  * Receive a data block via Ethernet
152be71a179Srick  */
__ftmac100_recv(struct ftmac100_data * priv)153be71a179Srick static int __ftmac100_recv(struct ftmac100_data *priv)
154be71a179Srick {
1556f6e6e09SPo-Yu Chuang 	struct ftmac100_rxdes *curr_des;
156750326e5SPo-Yu Chuang 	unsigned short rxlen;
157750326e5SPo-Yu Chuang 
158750326e5SPo-Yu Chuang 	curr_des = &priv->rxdes[priv->rx_index];
159750326e5SPo-Yu Chuang 
160750326e5SPo-Yu Chuang 	if (curr_des->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN)
161be71a179Srick 		return 0;
162750326e5SPo-Yu Chuang 
163750326e5SPo-Yu Chuang 	if (curr_des->rxdes0 & (FTMAC100_RXDES0_RX_ERR |
164750326e5SPo-Yu Chuang 				FTMAC100_RXDES0_CRC_ERR |
165750326e5SPo-Yu Chuang 				FTMAC100_RXDES0_FTL |
166750326e5SPo-Yu Chuang 				FTMAC100_RXDES0_RUNT |
167750326e5SPo-Yu Chuang 				FTMAC100_RXDES0_RX_ODD_NB)) {
168be71a179Srick 		return 0;
169750326e5SPo-Yu Chuang 	}
170750326e5SPo-Yu Chuang 
171750326e5SPo-Yu Chuang 	rxlen = FTMAC100_RXDES0_RFL (curr_des->rxdes0);
172750326e5SPo-Yu Chuang 
173750326e5SPo-Yu Chuang 	debug ("%s(): RX buffer %d, %x received\n",
174750326e5SPo-Yu Chuang 	       __func__, priv->rx_index, rxlen);
175750326e5SPo-Yu Chuang 
176be71a179Srick 	return rxlen;
177750326e5SPo-Yu Chuang }
178750326e5SPo-Yu Chuang 
179750326e5SPo-Yu Chuang /*
180750326e5SPo-Yu Chuang  * Send a data block via Ethernet
181750326e5SPo-Yu Chuang  */
_ftmac100_send(struct ftmac100_data * priv,void * packet,int length)182be71a179Srick static int _ftmac100_send(struct ftmac100_data *priv, void *packet, int length)
183750326e5SPo-Yu Chuang {
184be71a179Srick 	struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
1856f6e6e09SPo-Yu Chuang 	struct ftmac100_txdes *curr_des = priv->txdes;
1868d8fd5b6SPo-Yu Chuang 	ulong start;
187750326e5SPo-Yu Chuang 
188750326e5SPo-Yu Chuang 	if (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
189750326e5SPo-Yu Chuang 		debug ("%s(): no TX descriptor available\n", __func__);
190750326e5SPo-Yu Chuang 		return -1;
191750326e5SPo-Yu Chuang 	}
192750326e5SPo-Yu Chuang 
193750326e5SPo-Yu Chuang 	debug ("%s(%x, %x)\n", __func__, (int)packet, length);
194750326e5SPo-Yu Chuang 
195750326e5SPo-Yu Chuang 	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
196750326e5SPo-Yu Chuang 
197750326e5SPo-Yu Chuang 	/* initiate a transmit sequence */
198750326e5SPo-Yu Chuang 
199750326e5SPo-Yu Chuang 	curr_des->txdes2 = (unsigned int)packet;	/* TXBUF_BADR */
200750326e5SPo-Yu Chuang 
201750326e5SPo-Yu Chuang 	curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;
202750326e5SPo-Yu Chuang 	curr_des->txdes1 |= FTMAC100_TXDES1_FTS |
203750326e5SPo-Yu Chuang 			    FTMAC100_TXDES1_LTS |
204750326e5SPo-Yu Chuang 			    FTMAC100_TXDES1_TXBUF_SIZE (length);
205750326e5SPo-Yu Chuang 
206750326e5SPo-Yu Chuang 	curr_des->txdes0 = FTMAC100_TXDES0_TXDMA_OWN;
207750326e5SPo-Yu Chuang 
208750326e5SPo-Yu Chuang 	/* start transmit */
209750326e5SPo-Yu Chuang 
210750326e5SPo-Yu Chuang 	writel (1, &ftmac100->txpd);
211750326e5SPo-Yu Chuang 
212750326e5SPo-Yu Chuang 	/* wait for transfer to succeed */
213750326e5SPo-Yu Chuang 
2148d8fd5b6SPo-Yu Chuang 	start = get_timer(0);
215750326e5SPo-Yu Chuang 	while (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
2168d8fd5b6SPo-Yu Chuang 		if (get_timer(start) >= 5) {
217750326e5SPo-Yu Chuang 			debug ("%s(): timed out\n", __func__);
218750326e5SPo-Yu Chuang 			return -1;
219750326e5SPo-Yu Chuang 		}
220750326e5SPo-Yu Chuang 	}
221750326e5SPo-Yu Chuang 
222750326e5SPo-Yu Chuang 	debug ("%s(): packet sent\n", __func__);
223750326e5SPo-Yu Chuang 
224750326e5SPo-Yu Chuang 	return 0;
225750326e5SPo-Yu Chuang }
226750326e5SPo-Yu Chuang 
227be71a179Srick #ifndef CONFIG_DM_ETH
228be71a179Srick /*
229be71a179Srick  * disable transmitter, receiver
230be71a179Srick  */
ftmac100_halt(struct eth_device * dev)231be71a179Srick static void ftmac100_halt(struct eth_device *dev)
232be71a179Srick {
233be71a179Srick 	struct ftmac100_data *priv = dev->priv;
234be71a179Srick 	return _ftmac100_halt(priv);
235be71a179Srick }
236be71a179Srick 
ftmac100_init(struct eth_device * dev,bd_t * bd)237be71a179Srick static int ftmac100_init(struct eth_device *dev, bd_t *bd)
238be71a179Srick {
239be71a179Srick 	struct ftmac100_data *priv = dev->priv;
240be71a179Srick 	return _ftmac100_init(priv , dev->enetaddr);
241be71a179Srick }
242be71a179Srick 
_ftmac100_recv(struct ftmac100_data * priv)243be71a179Srick static int _ftmac100_recv(struct ftmac100_data *priv)
244be71a179Srick {
245be71a179Srick 	struct ftmac100_rxdes *curr_des;
246be71a179Srick 	unsigned short len;
247be71a179Srick 	curr_des = &priv->rxdes[priv->rx_index];
248be71a179Srick 	len = __ftmac100_recv(priv);
249be71a179Srick 	if (len) {
250be71a179Srick 		/* pass the packet up to the protocol layers. */
251be71a179Srick 		net_process_received_packet((void *)curr_des->rxdes2, len);
252be71a179Srick 		_ftmac100_free_pkt(priv);
253be71a179Srick 	}
254be71a179Srick 	return len ? 1 : 0;
255be71a179Srick }
256be71a179Srick 
257be71a179Srick /*
258be71a179Srick  * Get a data block via Ethernet
259be71a179Srick  */
ftmac100_recv(struct eth_device * dev)260be71a179Srick static int ftmac100_recv(struct eth_device *dev)
261be71a179Srick {
262be71a179Srick 	struct ftmac100_data *priv = dev->priv;
263be71a179Srick 	return _ftmac100_recv(priv);
264be71a179Srick }
265be71a179Srick 
266be71a179Srick /*
267be71a179Srick  * Send a data block via Ethernet
268be71a179Srick  */
ftmac100_send(struct eth_device * dev,void * packet,int length)269be71a179Srick static int ftmac100_send(struct eth_device *dev, void *packet, int length)
270be71a179Srick {
271be71a179Srick 	struct ftmac100_data *priv = dev->priv;
272be71a179Srick 	return _ftmac100_send(priv , packet , length);
273be71a179Srick }
274be71a179Srick 
ftmac100_initialize(bd_t * bd)275750326e5SPo-Yu Chuang int ftmac100_initialize (bd_t *bd)
276750326e5SPo-Yu Chuang {
277750326e5SPo-Yu Chuang 	struct eth_device *dev;
278750326e5SPo-Yu Chuang 	struct ftmac100_data *priv;
279750326e5SPo-Yu Chuang 	dev = malloc (sizeof *dev);
280750326e5SPo-Yu Chuang 	if (!dev) {
281750326e5SPo-Yu Chuang 		printf ("%s(): failed to allocate dev\n", __func__);
282750326e5SPo-Yu Chuang 		goto out;
283750326e5SPo-Yu Chuang 	}
284750326e5SPo-Yu Chuang 	/* Transmit and receive descriptors should align to 16 bytes */
285750326e5SPo-Yu Chuang 	priv = memalign (16, sizeof (struct ftmac100_data));
286750326e5SPo-Yu Chuang 	if (!priv) {
287750326e5SPo-Yu Chuang 		printf ("%s(): failed to allocate priv\n", __func__);
288750326e5SPo-Yu Chuang 		goto free_dev;
289750326e5SPo-Yu Chuang 	}
290750326e5SPo-Yu Chuang 	memset (dev, 0, sizeof (*dev));
291750326e5SPo-Yu Chuang 	memset (priv, 0, sizeof (*priv));
292750326e5SPo-Yu Chuang 
293192bc694SBen Whitten 	strcpy(dev->name, "FTMAC100");
294750326e5SPo-Yu Chuang 	dev->iobase	= CONFIG_FTMAC100_BASE;
295750326e5SPo-Yu Chuang 	dev->init	= ftmac100_init;
296750326e5SPo-Yu Chuang 	dev->halt	= ftmac100_halt;
297750326e5SPo-Yu Chuang 	dev->send	= ftmac100_send;
298750326e5SPo-Yu Chuang 	dev->recv	= ftmac100_recv;
299750326e5SPo-Yu Chuang 	dev->priv	= priv;
300be71a179Srick 	priv->iobase	= dev->iobase;
301750326e5SPo-Yu Chuang 	eth_register (dev);
302750326e5SPo-Yu Chuang 
303750326e5SPo-Yu Chuang 	return 1;
304750326e5SPo-Yu Chuang 
305750326e5SPo-Yu Chuang free_dev:
306750326e5SPo-Yu Chuang 	free (dev);
307750326e5SPo-Yu Chuang out:
308750326e5SPo-Yu Chuang 	return 0;
309750326e5SPo-Yu Chuang }
310be71a179Srick #endif
311be71a179Srick 
312be71a179Srick #ifdef CONFIG_DM_ETH
ftmac100_start(struct udevice * dev)313be71a179Srick static int ftmac100_start(struct udevice *dev)
314be71a179Srick {
315be71a179Srick 	struct eth_pdata *plat = dev_get_platdata(dev);
316be71a179Srick 	struct ftmac100_data *priv = dev_get_priv(dev);
317be71a179Srick 
318be71a179Srick 	return _ftmac100_init(priv, plat->enetaddr);
319be71a179Srick }
320be71a179Srick 
ftmac100_stop(struct udevice * dev)321be71a179Srick static void ftmac100_stop(struct udevice *dev)
322be71a179Srick {
323be71a179Srick 	struct ftmac100_data *priv = dev_get_priv(dev);
324be71a179Srick 	_ftmac100_halt(priv);
325be71a179Srick }
326be71a179Srick 
ftmac100_send(struct udevice * dev,void * packet,int length)327be71a179Srick static int ftmac100_send(struct udevice *dev, void *packet, int length)
328be71a179Srick {
329be71a179Srick 	struct ftmac100_data *priv = dev_get_priv(dev);
330be71a179Srick 	int ret;
331be71a179Srick 	ret = _ftmac100_send(priv , packet , length);
332be71a179Srick 	return ret ? 0 : -ETIMEDOUT;
333be71a179Srick }
334be71a179Srick 
ftmac100_recv(struct udevice * dev,int flags,uchar ** packetp)335be71a179Srick static int ftmac100_recv(struct udevice *dev, int flags, uchar **packetp)
336be71a179Srick {
337be71a179Srick 	struct ftmac100_data *priv = dev_get_priv(dev);
338be71a179Srick 	struct ftmac100_rxdes *curr_des;
339be71a179Srick 	curr_des = &priv->rxdes[priv->rx_index];
340be71a179Srick 	int len;
341be71a179Srick 	len = __ftmac100_recv(priv);
342be71a179Srick 	if (len)
343be71a179Srick 		*packetp = (void *)curr_des->rxdes2;
344be71a179Srick 
345be71a179Srick 	return len ? len : -EAGAIN;
346be71a179Srick }
347be71a179Srick 
ftmac100_free_pkt(struct udevice * dev,uchar * packet,int length)348be71a179Srick static int ftmac100_free_pkt(struct udevice *dev, uchar *packet, int length)
349be71a179Srick {
350be71a179Srick 	struct ftmac100_data *priv = dev_get_priv(dev);
351be71a179Srick 	_ftmac100_free_pkt(priv);
352be71a179Srick 	return 0;
353be71a179Srick }
354be71a179Srick 
ftmac100_read_rom_hwaddr(struct udevice * dev)355be71a179Srick int ftmac100_read_rom_hwaddr(struct udevice *dev)
356be71a179Srick {
357be71a179Srick 	struct eth_pdata *pdata = dev_get_platdata(dev);
358*35affd7aSSimon Glass 	eth_env_get_enetaddr("ethaddr", pdata->enetaddr);
359be71a179Srick 	return 0;
360be71a179Srick }
361be71a179Srick 
dtbmacaddr(u32 ifno)362be71a179Srick static const char *dtbmacaddr(u32 ifno)
363be71a179Srick {
364be71a179Srick 	int node, len;
365be71a179Srick 	char enet[16];
366be71a179Srick 	const char *mac;
367be71a179Srick 	const char *path;
368be71a179Srick 	if (gd->fdt_blob == NULL) {
369be71a179Srick 		printf("%s: don't have a valid gd->fdt_blob!\n", __func__);
370be71a179Srick 		return NULL;
371be71a179Srick 	}
372be71a179Srick 	node = fdt_path_offset(gd->fdt_blob, "/aliases");
373be71a179Srick 	if (node < 0)
374be71a179Srick 		return NULL;
375be71a179Srick 
376be71a179Srick 	sprintf(enet, "ethernet%d", ifno);
377be71a179Srick 	path = fdt_getprop(gd->fdt_blob, node, enet, NULL);
378be71a179Srick 	if (!path) {
379be71a179Srick 		printf("no alias for %s\n", enet);
380be71a179Srick 		return NULL;
381be71a179Srick 	}
382be71a179Srick 	node = fdt_path_offset(gd->fdt_blob, path);
383be71a179Srick 	mac = fdt_getprop(gd->fdt_blob, node, "mac-address", &len);
384be71a179Srick 	if (mac && is_valid_ethaddr((u8 *)mac))
385be71a179Srick 		return mac;
386be71a179Srick 
387be71a179Srick 	return NULL;
388be71a179Srick }
389be71a179Srick 
ftmac100_ofdata_to_platdata(struct udevice * dev)390be71a179Srick static int ftmac100_ofdata_to_platdata(struct udevice *dev)
391be71a179Srick {
392be71a179Srick 	struct ftmac100_data *priv = dev_get_priv(dev);
393be71a179Srick 	struct eth_pdata *pdata = dev_get_platdata(dev);
394be71a179Srick 	const char *mac;
395a821c4afSSimon Glass 	pdata->iobase = devfdt_get_addr(dev);
396be71a179Srick 	priv->iobase = pdata->iobase;
397be71a179Srick 	mac = dtbmacaddr(0);
398be71a179Srick 	if (mac)
399be71a179Srick 		memcpy(pdata->enetaddr , mac , 6);
400be71a179Srick 
401be71a179Srick 	return 0;
402be71a179Srick }
403be71a179Srick 
ftmac100_probe(struct udevice * dev)404be71a179Srick static int ftmac100_probe(struct udevice *dev)
405be71a179Srick {
406be71a179Srick 	struct ftmac100_data *priv = dev_get_priv(dev);
407be71a179Srick 	priv->name = dev->name;
408be71a179Srick 	return 0;
409be71a179Srick }
410be71a179Srick 
ftmac100_bind(struct udevice * dev)411be71a179Srick static int ftmac100_bind(struct udevice *dev)
412be71a179Srick {
413be71a179Srick 	return device_set_name(dev, dev->name);
414be71a179Srick }
415be71a179Srick 
416be71a179Srick static const struct eth_ops ftmac100_ops = {
417be71a179Srick 	.start	= ftmac100_start,
418be71a179Srick 	.send	= ftmac100_send,
419be71a179Srick 	.recv	= ftmac100_recv,
420be71a179Srick 	.stop	= ftmac100_stop,
421be71a179Srick 	.free_pkt = ftmac100_free_pkt,
422be71a179Srick };
423be71a179Srick 
424be71a179Srick static const struct udevice_id ftmac100_ids[] = {
425be71a179Srick 	{ .compatible = "andestech,atmac100" },
426be71a179Srick 	{ }
427be71a179Srick };
428be71a179Srick 
429be71a179Srick U_BOOT_DRIVER(ftmac100) = {
430be71a179Srick 	.name	= "nds32_mac",
431be71a179Srick 	.id	= UCLASS_ETH,
432be71a179Srick 	.of_match = ftmac100_ids,
433be71a179Srick 	.bind	= ftmac100_bind,
434be71a179Srick 	.ofdata_to_platdata = ftmac100_ofdata_to_platdata,
435be71a179Srick 	.probe	= ftmac100_probe,
436be71a179Srick 	.ops	= &ftmac100_ops,
437be71a179Srick 	.priv_auto_alloc_size = sizeof(struct ftmac100_data),
438be71a179Srick 	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
439be71a179Srick 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
440be71a179Srick };
441be71a179Srick #endif
442