xref: /openbmc/u-boot/drivers/net/ftgmac100.c (revision 15cbe029)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Faraday FTGMAC100 Ethernet
4  *
5  * (C) Copyright 2009 Faraday Technology
6  * Po-Yu Chuang <ratbert@faraday-tech.com>
7  *
8  * (C) Copyright 2010 Andes Technology
9  * Macpaul Lin <macpaul@andestech.com>
10  *
11  * Copyright (C) 2018, IBM Corporation.
12  */
13 
14 #include <clk.h>
15 #include <dm.h>
16 #include <miiphy.h>
17 #include <net.h>
18 #include <wait_bit.h>
19 #include <linux/io.h>
20 #include <linux/iopoll.h>
21 #include <net/ncsi.h>
22 
23 #include "ftgmac100.h"
24 #include "aspeed_mdio.h"
25 
26 /* Min frame ethernet frame size without FCS */
27 #define ETH_ZLEN			60
28 
29 /* Receive Buffer Size Register - HW default is 0x640 */
30 #define FTGMAC100_RBSR_DEFAULT		0x640
31 
32 /* PKTBUFSTX/PKTBUFSRX must both be power of 2 */
33 #define PKTBUFSTX	4	/* must be power of 2 */
34 
35 /* Timeout for transmit */
36 #define FTGMAC100_TX_TIMEOUT_MS		1000
37 
38 /* Timeout for a mdio read/write operation */
39 #define FTGMAC100_MDIO_TIMEOUT_USEC	10000
40 
41 /*
42  * MDC clock cycle threshold
43  *
44  * 20us * 100 = 2ms > (1 / 2.5Mhz) * 0x34
45  */
46 #define MDC_CYCTHR			0x34
47 
48 /*
49  * ftgmac100 model variants
50  */
51 enum ftgmac100_model {
52 	FTGMAC100_MODEL_FARADAY,
53 	FTGMAC100_MODEL_ASPEED,
54 	FTGMAC100_MODEL_NEW_ASPEED,
55 };
56 
57 /**
58  * struct ftgmac100_data - private data for the FTGMAC100 driver
59  *
60  * @iobase: The base address of the hardware registers
61  * @txdes: The array of transmit descriptors
62  * @rxdes: The array of receive descriptors
63  * @tx_index: Transmit descriptor index in @txdes
64  * @rx_index: Receive descriptor index in @rxdes
65  * @phy_addr: The PHY interface address to use
66  * @phydev: The PHY device backing the MAC
67  * @bus: The mdio bus
68  * @phy_mode: The mode of the PHY interface (rgmii, rmii, ...)
69  * @max_speed: Maximum speed of Ethernet connection supported by MAC
70  * @clks: The bulk of clocks assigned to the device in the DT
71  * @rxdes0_edorr_mask: The bit number identifying the end of the RX ring buffer
72  * @txdes0_edotr_mask: The bit number identifying the end of the TX ring buffer
73  */
74 struct ftgmac100_data {
75 	struct ftgmac100 *iobase;
76 	fdt_addr_t mdio_addr;	//for aspeed ast2600 new mdio
77 
78 	struct ftgmac100_txdes txdes[PKTBUFSTX];
79 	struct ftgmac100_rxdes rxdes[PKTBUFSRX];
80 	int tx_index;
81 	int rx_index;
82 
83 	u32 phy_addr;
84 	struct phy_device *phydev;
85 	struct mii_dev *bus;
86 	u32 phy_mode;
87 	u32 max_speed;
88 	bool ncsi_mode;
89 
90 	struct clk_bulk clks;
91 
92 	/* End of RX/TX ring buffer bits. Depend on model */
93 	u32 rxdes0_edorr_mask;
94 	u32 txdes0_edotr_mask;
95 };
96 
97 /*
98  * struct mii_bus functions
99  */
100 static int ftgmac100_mdio_read(struct mii_dev *bus, int phy_addr, int dev_addr,
101 			       int reg_addr)
102 {
103 	struct ftgmac100_data *priv = bus->priv;
104 	struct ftgmac100 *ftgmac100 = priv->iobase;
105 	int phycr;
106 	int data;
107 	int ret;
108 
109 	phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
110 		FTGMAC100_PHYCR_PHYAD(phy_addr) |
111 		FTGMAC100_PHYCR_REGAD(reg_addr) |
112 		FTGMAC100_PHYCR_MIIRD;
113 	writel(phycr, &ftgmac100->phycr);
114 
115 	ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
116 				 !(phycr & FTGMAC100_PHYCR_MIIRD),
117 				 FTGMAC100_MDIO_TIMEOUT_USEC);
118 	if (ret) {
119 		pr_err("%s: mdio read failed (phy:%d reg:%x)\n",
120 		       priv->phydev->dev->name, phy_addr, reg_addr);
121 		return ret;
122 	}
123 
124 	data = readl(&ftgmac100->phydata);
125 
126 	return FTGMAC100_PHYDATA_MIIRDATA(data);
127 }
128 
129 static int ftgmac100_mdio_write(struct mii_dev *bus, int phy_addr, int dev_addr,
130 				int reg_addr, u16 value)
131 {
132 	struct ftgmac100_data *priv = bus->priv;
133 	struct ftgmac100 *ftgmac100 = priv->iobase;
134 	int phycr;
135 	int data;
136 	int ret;
137 
138 	phycr = FTGMAC100_PHYCR_MDC_CYCTHR(MDC_CYCTHR) |
139 		FTGMAC100_PHYCR_PHYAD(phy_addr) |
140 		FTGMAC100_PHYCR_REGAD(reg_addr) |
141 		FTGMAC100_PHYCR_MIIWR;
142 	data = FTGMAC100_PHYDATA_MIIWDATA(value);
143 
144 	writel(data, &ftgmac100->phydata);
145 	writel(phycr, &ftgmac100->phycr);
146 
147 	ret = readl_poll_timeout(&ftgmac100->phycr, phycr,
148 				 !(phycr & FTGMAC100_PHYCR_MIIWR),
149 				 FTGMAC100_MDIO_TIMEOUT_USEC);
150 	if (ret) {
151 		pr_err("%s: mdio write failed (phy:%d reg:%x)\n",
152 		       priv->phydev->dev->name, phy_addr, reg_addr);
153 	}
154 
155 	return ret;
156 }
157 
158 static int ftgmac100_mdio_init(struct udevice *dev)
159 {
160 	struct ftgmac100_data *priv = dev_get_priv(dev);
161 	struct mii_dev *bus;
162 	int ret;
163 
164 	bus = mdio_alloc();
165 	if (!bus)
166 		return -ENOMEM;
167 
168 	if(priv->mdio_addr) {
169 		bus->read  = aspeed_mdio_read;
170 		bus->write = aspeed_mdio_write;
171 		bus->priv  = (void *)priv->mdio_addr;
172 	} else {
173 		bus->read  = ftgmac100_mdio_read;
174 		bus->write = ftgmac100_mdio_write;
175 		bus->priv  = priv;
176 	}
177 
178 	ret = mdio_register_seq(bus, dev->seq);
179 	if (ret) {
180 		free(bus);
181 		return ret;
182 	}
183 
184 	priv->bus = bus;
185 
186 	return 0;
187 }
188 
189 static int ftgmac100_phy_adjust_link(struct ftgmac100_data *priv)
190 {
191 	struct ftgmac100 *ftgmac100 = priv->iobase;
192 	struct phy_device *phydev = priv->phydev;
193 	u32 maccr;
194 
195 	if (!phydev->link && !priv->ncsi_mode) {
196 		dev_err(phydev->dev, "No link\n");
197 		return -EREMOTEIO;
198 	}
199 
200 	/* read MAC control register and clear related bits */
201 	maccr = readl(&ftgmac100->maccr) &
202 		~(FTGMAC100_MACCR_GIGA_MODE |
203 		  FTGMAC100_MACCR_FAST_MODE |
204 		  FTGMAC100_MACCR_FULLDUP);
205 
206 	if (phy_interface_is_rgmii(phydev) && phydev->speed == 1000)
207 		maccr |= FTGMAC100_MACCR_GIGA_MODE;
208 
209 	if (phydev->speed == 100)
210 		maccr |= FTGMAC100_MACCR_FAST_MODE;
211 
212 	if (phydev->duplex)
213 		maccr |= FTGMAC100_MACCR_FULLDUP;
214 
215 	/* update MII config into maccr */
216 	writel(maccr, &ftgmac100->maccr);
217 
218 	return 0;
219 }
220 
221 static int ftgmac100_phy_init(struct udevice *dev)
222 {
223 	struct ftgmac100_data *priv = dev_get_priv(dev);
224 	struct phy_device *phydev;
225 	int ret;
226 
227 	phydev = phy_connect(priv->bus, priv->phy_addr, dev, priv->phy_mode);
228 	if (!phydev)
229 		return -ENODEV;
230 
231 	if (!priv->ncsi_mode)
232 		phydev->supported &= PHY_GBIT_FEATURES;
233 	if (priv->max_speed) {
234 		ret = phy_set_supported(phydev, priv->max_speed);
235 		if (ret)
236 			return ret;
237 	}
238 	phydev->advertising = phydev->supported;
239 	priv->phydev = phydev;
240 	phy_config(phydev);
241 
242 	return 0;
243 }
244 
245 /*
246  * Reset MAC
247  */
248 static void ftgmac100_reset(struct ftgmac100_data *priv)
249 {
250 	struct ftgmac100 *ftgmac100 = priv->iobase;
251 
252 	debug("%s()\n", __func__);
253 
254 	setbits_le32(&ftgmac100->maccr, FTGMAC100_MACCR_SW_RST);
255 
256 	while (readl(&ftgmac100->maccr) & FTGMAC100_MACCR_SW_RST)
257 		;
258 }
259 
260 /*
261  * Set MAC address
262  */
263 static int ftgmac100_set_mac(struct ftgmac100_data *priv,
264 			     const unsigned char *mac)
265 {
266 	struct ftgmac100 *ftgmac100 = priv->iobase;
267 	unsigned int maddr = mac[0] << 8 | mac[1];
268 	unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];
269 
270 	debug("%s(%x %x)\n", __func__, maddr, laddr);
271 
272 	writel(maddr, &ftgmac100->mac_madr);
273 	writel(laddr, &ftgmac100->mac_ladr);
274 
275 	return 0;
276 }
277 
278 /*
279  * disable transmitter, receiver
280  */
281 static void ftgmac100_stop(struct udevice *dev)
282 {
283 	struct ftgmac100_data *priv = dev_get_priv(dev);
284 	struct ftgmac100 *ftgmac100 = priv->iobase;
285 
286 	debug("%s()\n", __func__);
287 
288 	writel(0, &ftgmac100->maccr);
289 
290 	if (!priv->ncsi_mode)
291 		phy_shutdown(priv->phydev);
292 }
293 
294 static int ftgmac100_start(struct udevice *dev)
295 {
296 	struct eth_pdata *plat = dev_get_platdata(dev);
297 	struct ftgmac100_data *priv = dev_get_priv(dev);
298 	struct ftgmac100 *ftgmac100 = priv->iobase;
299 	struct phy_device *phydev = priv->phydev;
300 	unsigned int maccr;
301 	unsigned int dblac;
302 	ulong start, end;
303 	size_t sz_txdes, sz_rxdes;
304 	int ret;
305 	int i;
306 
307 	debug("%s()\n", __func__);
308 
309 	ftgmac100_reset(priv);
310 
311 	/* set the ethernet address */
312 	ftgmac100_set_mac(priv, plat->enetaddr);
313 
314 	/* disable all interrupts */
315 	writel(0, &ftgmac100->ier);
316 
317 	/* initialize descriptors */
318 	priv->tx_index = 0;
319 	priv->rx_index = 0;
320 
321 	for (i = 0; i < PKTBUFSTX; i++) {
322 		priv->txdes[i].txdes3 = 0;
323 		priv->txdes[i].txdes0 = 0;
324 	}
325 	priv->txdes[PKTBUFSTX - 1].txdes0 = priv->txdes0_edotr_mask;
326 
327 	start = (ulong)&priv->txdes[0];
328 	end = start + roundup(sizeof(priv->txdes), ARCH_DMA_MINALIGN);
329 	flush_dcache_range(start, end);
330 
331 	for (i = 0; i < PKTBUFSRX; i++) {
332 		priv->rxdes[i].rxdes3 = (unsigned int)net_rx_packets[i];
333 		priv->rxdes[i].rxdes0 = 0;
334 	}
335 	priv->rxdes[PKTBUFSRX - 1].rxdes0 = priv->rxdes0_edorr_mask;
336 
337 	start = (ulong)&priv->rxdes[0];
338 	end = start + roundup(sizeof(priv->rxdes), ARCH_DMA_MINALIGN);
339 	flush_dcache_range(start, end);
340 
341 	/* transmit ring */
342 	writel((u32)priv->txdes, &ftgmac100->txr_badr);
343 
344 	/* receive ring */
345 	writel((u32)priv->rxdes, &ftgmac100->rxr_badr);
346 
347 	/* poll receive descriptor automatically */
348 	writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc);
349 
350 	/* config receive buffer size register */
351 	writel(FTGMAC100_RBSR_SIZE(FTGMAC100_RBSR_DEFAULT), &ftgmac100->rbsr);
352 
353 	/* config TX/RX descriptor size */
354 	sz_txdes = sizeof(struct ftgmac100_txdes);
355 	sz_rxdes = sizeof(struct ftgmac100_rxdes);
356 	if ((sz_txdes & 0xF) || (sz_rxdes & 0xF)) {
357 		dev_err(phydev->dev, "Descriptor size must be 16 bytes aligned\n");
358 		return -1;
359 	}
360 	dblac = ftgmac100->dblac;
361 	dblac &= ~(0xFF << 12);
362 	dblac |= ((sz_txdes >> 3) << 16);
363 	dblac |= ((sz_txdes >> 3) << 12);
364 	writel(dblac, &ftgmac100->dblac);
365 
366 	/* enable transmitter, receiver */
367 	maccr = FTGMAC100_MACCR_TXMAC_EN |
368 		FTGMAC100_MACCR_RXMAC_EN |
369 		FTGMAC100_MACCR_TXDMA_EN |
370 		FTGMAC100_MACCR_RXDMA_EN |
371 		FTGMAC100_MACCR_CRC_APD |
372 		FTGMAC100_MACCR_FULLDUP |
373 		FTGMAC100_MACCR_RX_RUNT |
374 		FTGMAC100_MACCR_RX_BROADPKT;
375 
376 	writel(maccr, &ftgmac100->maccr);
377 
378 	ret = phy_startup(phydev);
379 	if (ret) {
380 		dev_err(phydev->dev, "Could not start PHY\n");
381 		return ret;
382 	}
383 
384 	ret = ftgmac100_phy_adjust_link(priv);
385 	if (ret) {
386 		dev_err(phydev->dev,  "Could not adjust link\n");
387 		return ret;
388 	}
389 
390 	printf("%s: link up, %d Mbps %s-duplex mac:%pM\n", phydev->dev->name,
391 	       phydev->speed, phydev->duplex ? "full" : "half", plat->enetaddr);
392 
393 	return 0;
394 }
395 
396 static int ftgmac100_free_pkt(struct udevice *dev, uchar *packet, int length)
397 {
398 	struct ftgmac100_data *priv = dev_get_priv(dev);
399 	struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
400 	ulong des_start = (ulong)curr_des;
401 	ulong des_end = des_start +
402 		roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
403 
404 	/* Release buffer to DMA and flush descriptor */
405 	curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
406 	flush_dcache_range(des_start, des_end);
407 
408 	/* Move to next descriptor */
409 	priv->rx_index = (priv->rx_index + 1) % PKTBUFSRX;
410 
411 	return 0;
412 }
413 
414 /*
415  * Get a data block via Ethernet
416  */
417 static int ftgmac100_recv(struct udevice *dev, int flags, uchar **packetp)
418 {
419 	struct ftgmac100_data *priv = dev_get_priv(dev);
420 	struct ftgmac100_rxdes *curr_des = &priv->rxdes[priv->rx_index];
421 	unsigned short rxlen;
422 	ulong des_start = (ulong)curr_des;
423 	ulong des_end = des_start +
424 		roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
425 	ulong data_start = curr_des->rxdes3;
426 	ulong data_end;
427 
428 	invalidate_dcache_range(des_start, des_end);
429 
430 	if (!(curr_des->rxdes0 & FTGMAC100_RXDES0_RXPKT_RDY))
431 		return -EAGAIN;
432 
433 	if (curr_des->rxdes0 & (FTGMAC100_RXDES0_RX_ERR |
434 				FTGMAC100_RXDES0_CRC_ERR |
435 				FTGMAC100_RXDES0_FTL |
436 				FTGMAC100_RXDES0_RUNT |
437 				FTGMAC100_RXDES0_RX_ODD_NB)) {
438 		return -EAGAIN;
439 	}
440 
441 	rxlen = FTGMAC100_RXDES0_VDBC(curr_des->rxdes0);
442 
443 	debug("%s(): RX buffer %d, %x received\n",
444 	       __func__, priv->rx_index, rxlen);
445 
446 	/* Invalidate received data */
447 	data_end = data_start + roundup(rxlen, ARCH_DMA_MINALIGN);
448 	invalidate_dcache_range(data_start, data_end);
449 	*packetp = (uchar *)data_start;
450 
451 	return rxlen;
452 }
453 
454 static u32 ftgmac100_read_txdesc(const void *desc)
455 {
456 	const struct ftgmac100_txdes *txdes = desc;
457 	ulong des_start = (ulong)txdes;
458 	ulong des_end = des_start + roundup(sizeof(*txdes), ARCH_DMA_MINALIGN);
459 
460 	invalidate_dcache_range(des_start, des_end);
461 
462 	return txdes->txdes0;
463 }
464 
465 BUILD_WAIT_FOR_BIT(ftgmac100_txdone, u32, ftgmac100_read_txdesc)
466 
467 /*
468  * Send a data block via Ethernet
469  */
470 static int ftgmac100_send(struct udevice *dev, void *packet, int length)
471 {
472 	struct ftgmac100_data *priv = dev_get_priv(dev);
473 	struct ftgmac100 *ftgmac100 = priv->iobase;
474 	struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index];
475 	ulong des_start = (ulong)curr_des;
476 	ulong des_end = des_start +
477 		roundup(sizeof(*curr_des), ARCH_DMA_MINALIGN);
478 	ulong data_start;
479 	ulong data_end;
480 	int rc;
481 
482 	invalidate_dcache_range(des_start, des_end);
483 
484 	if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) {
485 		dev_err(dev, "no TX descriptor available\n");
486 		return -EPERM;
487 	}
488 
489 	debug("%s(%x, %x)\n", __func__, (int)packet, length);
490 
491 	length = (length < ETH_ZLEN) ? ETH_ZLEN : length;
492 
493 	curr_des->txdes3 = (unsigned int)packet;
494 
495 	/* Flush data to be sent */
496 	data_start = curr_des->txdes3;
497 	data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
498 	flush_dcache_range(data_start, data_end);
499 
500 	/* Only one segment on TXBUF */
501 	curr_des->txdes0 &= priv->txdes0_edotr_mask;
502 	curr_des->txdes0 |= FTGMAC100_TXDES0_FTS |
503 			    FTGMAC100_TXDES0_LTS |
504 			    FTGMAC100_TXDES0_TXBUF_SIZE(length) |
505 			    FTGMAC100_TXDES0_TXDMA_OWN ;
506 
507 	/* Flush modified buffer descriptor */
508 	flush_dcache_range(des_start, des_end);
509 
510 	/* Start transmit */
511 	writel(1, &ftgmac100->txpd);
512 
513 	rc = wait_for_bit_ftgmac100_txdone(curr_des,
514 					   FTGMAC100_TXDES0_TXDMA_OWN, false,
515 					   FTGMAC100_TX_TIMEOUT_MS, true);
516 	if (rc)
517 		return rc;
518 
519 	debug("%s(): packet sent\n", __func__);
520 
521 	/* Move to next descriptor */
522 	priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;
523 
524 	return 0;
525 }
526 
527 static int ftgmac100_write_hwaddr(struct udevice *dev)
528 {
529 	struct eth_pdata *pdata = dev_get_platdata(dev);
530 	struct ftgmac100_data *priv = dev_get_priv(dev);
531 
532 	return ftgmac100_set_mac(priv, pdata->enetaddr);
533 }
534 
535 static int ftgmac100_ofdata_to_platdata(struct udevice *dev)
536 {
537 	struct eth_pdata *pdata = dev_get_platdata(dev);
538 	struct ftgmac100_data *priv = dev_get_priv(dev);
539 	const char *phy_mode;
540 	int offset = 0;
541 
542 	pdata->iobase = devfdt_get_addr(dev);
543 	pdata->phy_interface = -1;
544 	phy_mode = dev_read_string(dev, "phy-mode");
545 
546 	if (phy_mode)
547 		pdata->phy_interface = phy_get_interface_by_name(phy_mode);
548 	if (pdata->phy_interface == -1) {
549 		dev_err(dev, "Invalid PHY interface '%s'\n", phy_mode);
550 		return -EINVAL;
551 	}
552 
553 	offset = fdtdec_lookup_phandle(gd->fdt_blob, dev_of_offset(dev),
554 				       "phy-handle");
555 	if (offset > 0) {
556 		priv->phy_addr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
557 	} else {
558 		priv->phy_addr = 0;
559 	}
560 
561 	pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
562 
563 	if (dev_get_driver_data(dev) == FTGMAC100_MODEL_NEW_ASPEED) {
564 		priv->mdio_addr =  devfdt_get_addr_index(dev, 1);
565 		debug("priv->mdio_addr %x \n", (u32)priv->mdio_addr);
566 
567 	}
568 	if ((dev_get_driver_data(dev) == FTGMAC100_MODEL_ASPEED) ||
569 		(dev_get_driver_data(dev) == FTGMAC100_MODEL_NEW_ASPEED)){
570 		priv->rxdes0_edorr_mask = BIT(30);
571 		priv->txdes0_edotr_mask = BIT(30);
572 	} else {
573 		priv->rxdes0_edorr_mask = BIT(15);
574 		priv->txdes0_edotr_mask = BIT(15);
575 	}
576 
577 	return clk_get_bulk(dev, &priv->clks);
578 }
579 
580 static int ftgmac100_probe(struct udevice *dev)
581 {
582 	struct eth_pdata *pdata = dev_get_platdata(dev);
583 	struct ftgmac100_data *priv = dev_get_priv(dev);
584 	const char *phy_mode;
585 	int ret;
586 
587 	phy_mode = dev_read_string(dev, "phy-mode");
588 	priv->ncsi_mode = dev_read_bool(dev, "use-ncsi") ||
589 		(phy_mode && strcmp(phy_mode, "NC-SI") == 0);
590 
591 	priv->iobase = (struct ftgmac100 *)pdata->iobase;
592 	priv->phy_mode = pdata->phy_interface;
593 	priv->max_speed = pdata->max_speed;
594 
595 	ret = clk_enable_bulk(&priv->clks);
596 	if (ret)
597 		goto out;
598 
599 	if (priv->ncsi_mode) {
600 		printf("%s - NCSI detected\n", __func__);
601 	} else {
602 		ret = ftgmac100_mdio_init(dev);
603 		if (ret) {
604 			dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
605 			goto out;
606 		}
607 
608 	}
609 
610 	ret = ftgmac100_phy_init(dev);
611 	if (ret) {
612 		dev_err(dev, "Failed to initialize PHY: %d\n", ret);
613 		goto out;
614 	}
615 
616 out:
617 	if (ret)
618 		clk_release_bulk(&priv->clks);
619 
620 	return ret;
621 }
622 
623 static int ftgmac100_remove(struct udevice *dev)
624 {
625 	struct ftgmac100_data *priv = dev_get_priv(dev);
626 
627 	if (!priv->ncsi_mode) {
628 		free(priv->phydev);
629 		mdio_unregister(priv->bus);
630 		mdio_free(priv->bus);
631 	} else {
632 		free(priv->phydev);
633 	}
634 	clk_release_bulk(&priv->clks);
635 
636 	return 0;
637 }
638 
639 static const struct eth_ops ftgmac100_ops = {
640 	.start	= ftgmac100_start,
641 	.send	= ftgmac100_send,
642 	.recv	= ftgmac100_recv,
643 	.stop	= ftgmac100_stop,
644 	.free_pkt = ftgmac100_free_pkt,
645 	.write_hwaddr = ftgmac100_write_hwaddr,
646 };
647 
648 static const struct udevice_id ftgmac100_ids[] = {
649 	{ .compatible = "faraday,ftgmac100",  .data = FTGMAC100_MODEL_FARADAY },
650 	{ .compatible = "aspeed,ast2400-mac", .data = FTGMAC100_MODEL_ASPEED  },
651 	{ .compatible = "aspeed,ast2500-mac", .data = FTGMAC100_MODEL_ASPEED  },
652 	{ .compatible = "aspeed,ast2600-mac", .data = FTGMAC100_MODEL_NEW_ASPEED  },
653 	{ }
654 };
655 
656 U_BOOT_DRIVER(ftgmac100) = {
657 	.name	= "ftgmac100",
658 	.id	= UCLASS_ETH,
659 	.of_match = ftgmac100_ids,
660 	.ofdata_to_platdata = ftgmac100_ofdata_to_platdata,
661 	.probe	= ftgmac100_probe,
662 	.remove = ftgmac100_remove,
663 	.ops	= &ftgmac100_ops,
664 	.priv_auto_alloc_size = sizeof(struct ftgmac100_data),
665 	.platdata_auto_alloc_size = sizeof(struct eth_pdata),
666 	.flags	= DM_FLAG_ALLOC_PRIV_DMA,
667 };
668