183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2750326e5SPo-Yu Chuang /*
3750326e5SPo-Yu Chuang * Faraday FTMAC100 Ethernet
4750326e5SPo-Yu Chuang *
5750326e5SPo-Yu Chuang * (C) Copyright 2009 Faraday Technology
6750326e5SPo-Yu Chuang * Po-Yu Chuang <ratbert@faraday-tech.com>
7750326e5SPo-Yu Chuang */
8750326e5SPo-Yu Chuang
9750326e5SPo-Yu Chuang #include <config.h>
10750326e5SPo-Yu Chuang #include <common.h>
11750326e5SPo-Yu Chuang #include <malloc.h>
12750326e5SPo-Yu Chuang #include <net.h>
13be71a179Srick #include <linux/io.h>
14750326e5SPo-Yu Chuang
15750326e5SPo-Yu Chuang #include "ftmac100.h"
16be71a179Srick #ifdef CONFIG_DM_ETH
17be71a179Srick #include <dm.h>
18be71a179Srick DECLARE_GLOBAL_DATA_PTR;
19be71a179Srick #endif
20750326e5SPo-Yu Chuang #define ETH_ZLEN 60
21750326e5SPo-Yu Chuang
22750326e5SPo-Yu Chuang struct ftmac100_data {
236f6e6e09SPo-Yu Chuang struct ftmac100_txdes txdes[1];
246f6e6e09SPo-Yu Chuang struct ftmac100_rxdes rxdes[PKTBUFSRX];
25750326e5SPo-Yu Chuang int rx_index;
26be71a179Srick const char *name;
27be71a179Srick phys_addr_t iobase;
28750326e5SPo-Yu Chuang };
29750326e5SPo-Yu Chuang
30750326e5SPo-Yu Chuang /*
31750326e5SPo-Yu Chuang * Reset MAC
32750326e5SPo-Yu Chuang */
ftmac100_reset(struct ftmac100_data * priv)33be71a179Srick static void ftmac100_reset(struct ftmac100_data *priv)
34750326e5SPo-Yu Chuang {
35be71a179Srick struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
36750326e5SPo-Yu Chuang
37750326e5SPo-Yu Chuang debug ("%s()\n", __func__);
38750326e5SPo-Yu Chuang
39750326e5SPo-Yu Chuang writel (FTMAC100_MACCR_SW_RST, &ftmac100->maccr);
40750326e5SPo-Yu Chuang
41750326e5SPo-Yu Chuang while (readl (&ftmac100->maccr) & FTMAC100_MACCR_SW_RST)
421341494cSrick mdelay(1);
431341494cSrick /*
441341494cSrick * When soft reset complete, write mac address immediately maybe fail somehow
451341494cSrick * Wait for a while can avoid this problem
461341494cSrick */
471341494cSrick mdelay(1);
48750326e5SPo-Yu Chuang }
49750326e5SPo-Yu Chuang
50750326e5SPo-Yu Chuang /*
51750326e5SPo-Yu Chuang * Set MAC address
52750326e5SPo-Yu Chuang */
ftmac100_set_mac(struct ftmac100_data * priv,const unsigned char * mac)53be71a179Srick static void ftmac100_set_mac(struct ftmac100_data *priv ,
54be71a179Srick const unsigned char *mac)
55750326e5SPo-Yu Chuang {
56be71a179Srick struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
57750326e5SPo-Yu Chuang unsigned int maddr = mac[0] << 8 | mac[1];
58750326e5SPo-Yu Chuang unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
59750326e5SPo-Yu Chuang
60750326e5SPo-Yu Chuang debug ("%s(%x %x)\n", __func__, maddr, laddr);
61750326e5SPo-Yu Chuang
62750326e5SPo-Yu Chuang writel (maddr, &ftmac100->mac_madr);
63750326e5SPo-Yu Chuang writel (laddr, &ftmac100->mac_ladr);
64750326e5SPo-Yu Chuang }
65750326e5SPo-Yu Chuang
66750326e5SPo-Yu Chuang /*
67be71a179Srick * Disable MAC
68750326e5SPo-Yu Chuang */
_ftmac100_halt(struct ftmac100_data * priv)69be71a179Srick static void _ftmac100_halt(struct ftmac100_data *priv)
70750326e5SPo-Yu Chuang {
71be71a179Srick struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
72750326e5SPo-Yu Chuang debug ("%s()\n", __func__);
73750326e5SPo-Yu Chuang writel (0, &ftmac100->maccr);
74750326e5SPo-Yu Chuang }
75750326e5SPo-Yu Chuang
76be71a179Srick /*
77be71a179Srick * Initialize MAC
78be71a179Srick */
_ftmac100_init(struct ftmac100_data * priv,unsigned char enetaddr[6])79be71a179Srick static int _ftmac100_init(struct ftmac100_data *priv, unsigned char enetaddr[6])
80750326e5SPo-Yu Chuang {
81be71a179Srick struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
826f6e6e09SPo-Yu Chuang struct ftmac100_txdes *txdes = priv->txdes;
836f6e6e09SPo-Yu Chuang struct ftmac100_rxdes *rxdes = priv->rxdes;
84750326e5SPo-Yu Chuang unsigned int maccr;
85750326e5SPo-Yu Chuang int i;
86750326e5SPo-Yu Chuang debug ("%s()\n", __func__);
87750326e5SPo-Yu Chuang
88be71a179Srick ftmac100_reset(priv);
89750326e5SPo-Yu Chuang
90750326e5SPo-Yu Chuang /* set the ethernet address */
91be71a179Srick ftmac100_set_mac(priv, enetaddr);
92750326e5SPo-Yu Chuang
93750326e5SPo-Yu Chuang
94750326e5SPo-Yu Chuang /* disable all interrupts */
95750326e5SPo-Yu Chuang
96750326e5SPo-Yu Chuang writel (0, &ftmac100->imr);
97750326e5SPo-Yu Chuang
98750326e5SPo-Yu Chuang /* initialize descriptors */
99750326e5SPo-Yu Chuang
100750326e5SPo-Yu Chuang priv->rx_index = 0;
101750326e5SPo-Yu Chuang
102750326e5SPo-Yu Chuang txdes[0].txdes1 = FTMAC100_TXDES1_EDOTR;
103750326e5SPo-Yu Chuang rxdes[PKTBUFSRX - 1].rxdes1 = FTMAC100_RXDES1_EDORR;
104750326e5SPo-Yu Chuang
105750326e5SPo-Yu Chuang for (i = 0; i < PKTBUFSRX; i++) {
106750326e5SPo-Yu Chuang /* RXBUF_BADR */
107*28b52a6fSRick Chen rxdes[i].rxdes2 = (unsigned int)(unsigned long)net_rx_packets[i];
108750326e5SPo-Yu Chuang rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN);
109750326e5SPo-Yu Chuang rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;
110750326e5SPo-Yu Chuang }
111750326e5SPo-Yu Chuang
112750326e5SPo-Yu Chuang /* transmit ring */
113750326e5SPo-Yu Chuang
114*28b52a6fSRick Chen writel ((unsigned long)txdes, &ftmac100->txr_badr);
115750326e5SPo-Yu Chuang
116750326e5SPo-Yu Chuang /* receive ring */
117750326e5SPo-Yu Chuang
118*28b52a6fSRick Chen writel ((unsigned long)rxdes, &ftmac100->rxr_badr);
119750326e5SPo-Yu Chuang
120750326e5SPo-Yu Chuang /* poll receive descriptor automatically */
121750326e5SPo-Yu Chuang
122750326e5SPo-Yu Chuang writel (FTMAC100_APTC_RXPOLL_CNT (1), &ftmac100->aptc);
123750326e5SPo-Yu Chuang
124750326e5SPo-Yu Chuang /* enable transmitter, receiver */
125750326e5SPo-Yu Chuang
126750326e5SPo-Yu Chuang maccr = FTMAC100_MACCR_XMT_EN |
127750326e5SPo-Yu Chuang FTMAC100_MACCR_RCV_EN |
128750326e5SPo-Yu Chuang FTMAC100_MACCR_XDMA_EN |
129750326e5SPo-Yu Chuang FTMAC100_MACCR_RDMA_EN |
130750326e5SPo-Yu Chuang FTMAC100_MACCR_CRC_APD |
131750326e5SPo-Yu Chuang FTMAC100_MACCR_ENRX_IN_HALFTX |
132750326e5SPo-Yu Chuang FTMAC100_MACCR_RX_RUNT |
133750326e5SPo-Yu Chuang FTMAC100_MACCR_RX_BROADPKT;
134750326e5SPo-Yu Chuang
135750326e5SPo-Yu Chuang writel (maccr, &ftmac100->maccr);
136750326e5SPo-Yu Chuang
137750326e5SPo-Yu Chuang return 0;
138750326e5SPo-Yu Chuang }
139750326e5SPo-Yu Chuang
140750326e5SPo-Yu Chuang /*
141be71a179Srick * Free receiving buffer
142750326e5SPo-Yu Chuang */
_ftmac100_free_pkt(struct ftmac100_data * priv)143be71a179Srick static int _ftmac100_free_pkt(struct ftmac100_data *priv)
144750326e5SPo-Yu Chuang {
145be71a179Srick struct ftmac100_rxdes *curr_des;
146be71a179Srick curr_des = &priv->rxdes[priv->rx_index];
147be71a179Srick /* release buffer to DMA */
148be71a179Srick curr_des->rxdes0 |= FTMAC100_RXDES0_RXDMA_OWN;
149be71a179Srick priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
150be71a179Srick return 0;
151be71a179Srick }
152be71a179Srick
153be71a179Srick /*
154be71a179Srick * Receive a data block via Ethernet
155be71a179Srick */
__ftmac100_recv(struct ftmac100_data * priv)156be71a179Srick static int __ftmac100_recv(struct ftmac100_data *priv)
157be71a179Srick {
1586f6e6e09SPo-Yu Chuang struct ftmac100_rxdes *curr_des;
159750326e5SPo-Yu Chuang unsigned short rxlen;
160750326e5SPo-Yu Chuang
161750326e5SPo-Yu Chuang curr_des = &priv->rxdes[priv->rx_index];
162750326e5SPo-Yu Chuang if (curr_des->rxdes0 & FTMAC100_RXDES0_RXDMA_OWN)
163be71a179Srick return 0;
164750326e5SPo-Yu Chuang
165750326e5SPo-Yu Chuang if (curr_des->rxdes0 & (FTMAC100_RXDES0_RX_ERR |
166750326e5SPo-Yu Chuang FTMAC100_RXDES0_CRC_ERR |
167750326e5SPo-Yu Chuang FTMAC100_RXDES0_FTL |
168750326e5SPo-Yu Chuang FTMAC100_RXDES0_RUNT |
169750326e5SPo-Yu Chuang FTMAC100_RXDES0_RX_ODD_NB)) {
170be71a179Srick return 0;
171750326e5SPo-Yu Chuang }
172750326e5SPo-Yu Chuang
173750326e5SPo-Yu Chuang rxlen = FTMAC100_RXDES0_RFL (curr_des->rxdes0);
174ce4e2370Srick invalidate_dcache_range(curr_des->rxdes2,curr_des->rxdes2+rxlen);
175750326e5SPo-Yu Chuang debug ("%s(): RX buffer %d, %x received\n",
176750326e5SPo-Yu Chuang __func__, priv->rx_index, rxlen);
177750326e5SPo-Yu Chuang
178be71a179Srick return rxlen;
179750326e5SPo-Yu Chuang }
180750326e5SPo-Yu Chuang
181750326e5SPo-Yu Chuang /*
182750326e5SPo-Yu Chuang * Send a data block via Ethernet
183750326e5SPo-Yu Chuang */
_ftmac100_send(struct ftmac100_data * priv,void * packet,int length)184be71a179Srick static int _ftmac100_send(struct ftmac100_data *priv, void *packet, int length)
185750326e5SPo-Yu Chuang {
186be71a179Srick struct ftmac100 *ftmac100 = (struct ftmac100 *)priv->iobase;
1876f6e6e09SPo-Yu Chuang struct ftmac100_txdes *curr_des = priv->txdes;
1888d8fd5b6SPo-Yu Chuang ulong start;
189750326e5SPo-Yu Chuang
190750326e5SPo-Yu Chuang if (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
191750326e5SPo-Yu Chuang debug ("%s(): no TX descriptor available\n", __func__);
192750326e5SPo-Yu Chuang return -1;
193750326e5SPo-Yu Chuang }
194750326e5SPo-Yu Chuang
195*28b52a6fSRick Chen debug ("%s(%lx, %x)\n", __func__, (unsigned long)packet, length);
196750326e5SPo-Yu Chuang
197750326e5SPo-Yu Chuang length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
198750326e5SPo-Yu Chuang
199750326e5SPo-Yu Chuang /* initiate a transmit sequence */
200750326e5SPo-Yu Chuang
201*28b52a6fSRick Chen flush_dcache_range((unsigned long)packet,(unsigned long)packet+length);
202*28b52a6fSRick Chen curr_des->txdes2 = (unsigned int)(unsigned long)packet; /* TXBUF_BADR */
203750326e5SPo-Yu Chuang
204750326e5SPo-Yu Chuang curr_des->txdes1 &= FTMAC100_TXDES1_EDOTR;
205750326e5SPo-Yu Chuang curr_des->txdes1 |= FTMAC100_TXDES1_FTS |
206750326e5SPo-Yu Chuang FTMAC100_TXDES1_LTS |
207750326e5SPo-Yu Chuang FTMAC100_TXDES1_TXBUF_SIZE (length);
208750326e5SPo-Yu Chuang
209750326e5SPo-Yu Chuang curr_des->txdes0 = FTMAC100_TXDES0_TXDMA_OWN;
210750326e5SPo-Yu Chuang
211750326e5SPo-Yu Chuang /* start transmit */
212750326e5SPo-Yu Chuang
213750326e5SPo-Yu Chuang writel (1, &ftmac100->txpd);
214750326e5SPo-Yu Chuang
215750326e5SPo-Yu Chuang /* wait for transfer to succeed */
216750326e5SPo-Yu Chuang
2178d8fd5b6SPo-Yu Chuang start = get_timer(0);
218750326e5SPo-Yu Chuang while (curr_des->txdes0 & FTMAC100_TXDES0_TXDMA_OWN) {
2198d8fd5b6SPo-Yu Chuang if (get_timer(start) >= 5) {
220750326e5SPo-Yu Chuang debug ("%s(): timed out\n", __func__);
221750326e5SPo-Yu Chuang return -1;
222750326e5SPo-Yu Chuang }
223750326e5SPo-Yu Chuang }
224750326e5SPo-Yu Chuang
225750326e5SPo-Yu Chuang debug ("%s(): packet sent\n", __func__);
226750326e5SPo-Yu Chuang
227750326e5SPo-Yu Chuang return 0;
228750326e5SPo-Yu Chuang }
229750326e5SPo-Yu Chuang
230be71a179Srick #ifndef CONFIG_DM_ETH
231be71a179Srick /*
232be71a179Srick * disable transmitter, receiver
233be71a179Srick */
ftmac100_halt(struct eth_device * dev)234be71a179Srick static void ftmac100_halt(struct eth_device *dev)
235be71a179Srick {
236be71a179Srick struct ftmac100_data *priv = dev->priv;
237be71a179Srick return _ftmac100_halt(priv);
238be71a179Srick }
239be71a179Srick
ftmac100_init(struct eth_device * dev,bd_t * bd)240be71a179Srick static int ftmac100_init(struct eth_device *dev, bd_t *bd)
241be71a179Srick {
242be71a179Srick struct ftmac100_data *priv = dev->priv;
243be71a179Srick return _ftmac100_init(priv , dev->enetaddr);
244be71a179Srick }
245be71a179Srick
_ftmac100_recv(struct ftmac100_data * priv)246be71a179Srick static int _ftmac100_recv(struct ftmac100_data *priv)
247be71a179Srick {
248be71a179Srick struct ftmac100_rxdes *curr_des;
249be71a179Srick unsigned short len;
250be71a179Srick curr_des = &priv->rxdes[priv->rx_index];
251be71a179Srick len = __ftmac100_recv(priv);
252be71a179Srick if (len) {
253be71a179Srick /* pass the packet up to the protocol layers. */
254be71a179Srick net_process_received_packet((void *)curr_des->rxdes2, len);
255be71a179Srick _ftmac100_free_pkt(priv);
256be71a179Srick }
257be71a179Srick return len ? 1 : 0;
258be71a179Srick }
259be71a179Srick
260be71a179Srick /*
261be71a179Srick * Get a data block via Ethernet
262be71a179Srick */
ftmac100_recv(struct eth_device * dev)263be71a179Srick static int ftmac100_recv(struct eth_device *dev)
264be71a179Srick {
265be71a179Srick struct ftmac100_data *priv = dev->priv;
266be71a179Srick return _ftmac100_recv(priv);
267be71a179Srick }
268be71a179Srick
269be71a179Srick /*
270be71a179Srick * Send a data block via Ethernet
271be71a179Srick */
ftmac100_send(struct eth_device * dev,void * packet,int length)272be71a179Srick static int ftmac100_send(struct eth_device *dev, void *packet, int length)
273be71a179Srick {
274be71a179Srick struct ftmac100_data *priv = dev->priv;
275be71a179Srick return _ftmac100_send(priv , packet , length);
276be71a179Srick }
277be71a179Srick
ftmac100_initialize(bd_t * bd)278750326e5SPo-Yu Chuang int ftmac100_initialize (bd_t *bd)
279750326e5SPo-Yu Chuang {
280750326e5SPo-Yu Chuang struct eth_device *dev;
281750326e5SPo-Yu Chuang struct ftmac100_data *priv;
282750326e5SPo-Yu Chuang dev = malloc (sizeof *dev);
283750326e5SPo-Yu Chuang if (!dev) {
284750326e5SPo-Yu Chuang printf ("%s(): failed to allocate dev\n", __func__);
285750326e5SPo-Yu Chuang goto out;
286750326e5SPo-Yu Chuang }
287750326e5SPo-Yu Chuang /* Transmit and receive descriptors should align to 16 bytes */
288750326e5SPo-Yu Chuang priv = memalign (16, sizeof (struct ftmac100_data));
289750326e5SPo-Yu Chuang if (!priv) {
290750326e5SPo-Yu Chuang printf ("%s(): failed to allocate priv\n", __func__);
291750326e5SPo-Yu Chuang goto free_dev;
292750326e5SPo-Yu Chuang }
293750326e5SPo-Yu Chuang memset (dev, 0, sizeof (*dev));
294750326e5SPo-Yu Chuang memset (priv, 0, sizeof (*priv));
295750326e5SPo-Yu Chuang
296192bc694SBen Whitten strcpy(dev->name, "FTMAC100");
297750326e5SPo-Yu Chuang dev->iobase = CONFIG_FTMAC100_BASE;
298750326e5SPo-Yu Chuang dev->init = ftmac100_init;
299750326e5SPo-Yu Chuang dev->halt = ftmac100_halt;
300750326e5SPo-Yu Chuang dev->send = ftmac100_send;
301750326e5SPo-Yu Chuang dev->recv = ftmac100_recv;
302750326e5SPo-Yu Chuang dev->priv = priv;
303be71a179Srick priv->iobase = dev->iobase;
304750326e5SPo-Yu Chuang eth_register (dev);
305750326e5SPo-Yu Chuang
306750326e5SPo-Yu Chuang return 1;
307750326e5SPo-Yu Chuang
308750326e5SPo-Yu Chuang free_dev:
309750326e5SPo-Yu Chuang free (dev);
310750326e5SPo-Yu Chuang out:
311750326e5SPo-Yu Chuang return 0;
312750326e5SPo-Yu Chuang }
313be71a179Srick #endif
314be71a179Srick
315be71a179Srick #ifdef CONFIG_DM_ETH
ftmac100_start(struct udevice * dev)316be71a179Srick static int ftmac100_start(struct udevice *dev)
317be71a179Srick {
318be71a179Srick struct eth_pdata *plat = dev_get_platdata(dev);
319be71a179Srick struct ftmac100_data *priv = dev_get_priv(dev);
320be71a179Srick
321be71a179Srick return _ftmac100_init(priv, plat->enetaddr);
322be71a179Srick }
323be71a179Srick
ftmac100_stop(struct udevice * dev)324be71a179Srick static void ftmac100_stop(struct udevice *dev)
325be71a179Srick {
326be71a179Srick struct ftmac100_data *priv = dev_get_priv(dev);
327be71a179Srick _ftmac100_halt(priv);
328be71a179Srick }
329be71a179Srick
ftmac100_send(struct udevice * dev,void * packet,int length)330be71a179Srick static int ftmac100_send(struct udevice *dev, void *packet, int length)
331be71a179Srick {
332be71a179Srick struct ftmac100_data *priv = dev_get_priv(dev);
333be71a179Srick int ret;
334be71a179Srick ret = _ftmac100_send(priv , packet , length);
335be71a179Srick return ret ? 0 : -ETIMEDOUT;
336be71a179Srick }
337be71a179Srick
ftmac100_recv(struct udevice * dev,int flags,uchar ** packetp)338be71a179Srick static int ftmac100_recv(struct udevice *dev, int flags, uchar **packetp)
339be71a179Srick {
340be71a179Srick struct ftmac100_data *priv = dev_get_priv(dev);
341be71a179Srick struct ftmac100_rxdes *curr_des;
342be71a179Srick curr_des = &priv->rxdes[priv->rx_index];
343be71a179Srick int len;
344be71a179Srick len = __ftmac100_recv(priv);
345be71a179Srick if (len)
346*28b52a6fSRick Chen *packetp = (uchar *)(unsigned long)curr_des->rxdes2;
347be71a179Srick
348be71a179Srick return len ? len : -EAGAIN;
349be71a179Srick }
350be71a179Srick
ftmac100_free_pkt(struct udevice * dev,uchar * packet,int length)351be71a179Srick static int ftmac100_free_pkt(struct udevice *dev, uchar *packet, int length)
352be71a179Srick {
353be71a179Srick struct ftmac100_data *priv = dev_get_priv(dev);
354be71a179Srick _ftmac100_free_pkt(priv);
355be71a179Srick return 0;
356be71a179Srick }
357be71a179Srick
ftmac100_read_rom_hwaddr(struct udevice * dev)358be71a179Srick int ftmac100_read_rom_hwaddr(struct udevice *dev)
359be71a179Srick {
360be71a179Srick struct eth_pdata *pdata = dev_get_platdata(dev);
36135affd7aSSimon Glass eth_env_get_enetaddr("ethaddr", pdata->enetaddr);
362be71a179Srick return 0;
363be71a179Srick }
364be71a179Srick
dtbmacaddr(u32 ifno)365be71a179Srick static const char *dtbmacaddr(u32 ifno)
366be71a179Srick {
367be71a179Srick int node, len;
368be71a179Srick char enet[16];
369be71a179Srick const char *mac;
370be71a179Srick const char *path;
371be71a179Srick if (gd->fdt_blob == NULL) {
372be71a179Srick printf("%s: don't have a valid gd->fdt_blob!\n", __func__);
373be71a179Srick return NULL;
374be71a179Srick }
375be71a179Srick node = fdt_path_offset(gd->fdt_blob, "/aliases");
376be71a179Srick if (node < 0)
377be71a179Srick return NULL;
378be71a179Srick
379be71a179Srick sprintf(enet, "ethernet%d", ifno);
380be71a179Srick path = fdt_getprop(gd->fdt_blob, node, enet, NULL);
381be71a179Srick if (!path) {
382be71a179Srick printf("no alias for %s\n", enet);
383be71a179Srick return NULL;
384be71a179Srick }
385be71a179Srick node = fdt_path_offset(gd->fdt_blob, path);
386be71a179Srick mac = fdt_getprop(gd->fdt_blob, node, "mac-address", &len);
387be71a179Srick if (mac && is_valid_ethaddr((u8 *)mac))
388be71a179Srick return mac;
389be71a179Srick
390be71a179Srick return NULL;
391be71a179Srick }
392be71a179Srick
ftmac100_ofdata_to_platdata(struct udevice * dev)393be71a179Srick static int ftmac100_ofdata_to_platdata(struct udevice *dev)
394be71a179Srick {
395be71a179Srick struct ftmac100_data *priv = dev_get_priv(dev);
396be71a179Srick struct eth_pdata *pdata = dev_get_platdata(dev);
397be71a179Srick const char *mac;
398a821c4afSSimon Glass pdata->iobase = devfdt_get_addr(dev);
399be71a179Srick priv->iobase = pdata->iobase;
400be71a179Srick mac = dtbmacaddr(0);
401be71a179Srick if (mac)
402be71a179Srick memcpy(pdata->enetaddr , mac , 6);
403be71a179Srick
404be71a179Srick return 0;
405be71a179Srick }
406be71a179Srick
ftmac100_probe(struct udevice * dev)407be71a179Srick static int ftmac100_probe(struct udevice *dev)
408be71a179Srick {
409be71a179Srick struct ftmac100_data *priv = dev_get_priv(dev);
410be71a179Srick priv->name = dev->name;
411be71a179Srick return 0;
412be71a179Srick }
413be71a179Srick
ftmac100_bind(struct udevice * dev)414be71a179Srick static int ftmac100_bind(struct udevice *dev)
415be71a179Srick {
416be71a179Srick return device_set_name(dev, dev->name);
417be71a179Srick }
418be71a179Srick
419be71a179Srick static const struct eth_ops ftmac100_ops = {
420be71a179Srick .start = ftmac100_start,
421be71a179Srick .send = ftmac100_send,
422be71a179Srick .recv = ftmac100_recv,
423be71a179Srick .stop = ftmac100_stop,
424be71a179Srick .free_pkt = ftmac100_free_pkt,
425be71a179Srick };
426be71a179Srick
427be71a179Srick static const struct udevice_id ftmac100_ids[] = {
428be71a179Srick { .compatible = "andestech,atmac100" },
429be71a179Srick { }
430be71a179Srick };
431be71a179Srick
432be71a179Srick U_BOOT_DRIVER(ftmac100) = {
433be71a179Srick .name = "nds32_mac",
434be71a179Srick .id = UCLASS_ETH,
435be71a179Srick .of_match = ftmac100_ids,
436be71a179Srick .bind = ftmac100_bind,
437be71a179Srick .ofdata_to_platdata = ftmac100_ofdata_to_platdata,
438be71a179Srick .probe = ftmac100_probe,
439be71a179Srick .ops = &ftmac100_ops,
440be71a179Srick .priv_auto_alloc_size = sizeof(struct ftmac100_data),
441be71a179Srick .platdata_auto_alloc_size = sizeof(struct eth_pdata),
442be71a179Srick .flags = DM_FLAG_ALLOC_PRIV_DMA,
443be71a179Srick };
444be71a179Srick #endif
445