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 */
ftgmac100_mdio_read(struct mii_dev * bus,int phy_addr,int dev_addr,int reg_addr)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 bus->name, phy_addr, reg_addr);
121 return ret;
122 }
123
124 data = readl(&ftgmac100->phydata);
125
126 return FTGMAC100_PHYDATA_MIIRDATA(data);
127 }
128
ftgmac100_mdio_write(struct mii_dev * bus,int phy_addr,int dev_addr,int reg_addr,u16 value)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 bus->name, phy_addr, reg_addr);
153 }
154
155 return ret;
156 }
157
ftgmac100_mdio_init(struct udevice * dev)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
ftgmac100_phy_adjust_link(struct ftgmac100_data * priv)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
ftgmac100_phy_init(struct udevice * dev)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 */
ftgmac100_reset(struct ftgmac100_data * priv)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 */
ftgmac100_set_mac(struct ftgmac100_data * priv,const unsigned char * mac)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 */
ftgmac100_stop(struct udevice * dev)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
ftgmac100_start(struct udevice * dev)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
ftgmac100_free_pkt(struct udevice * dev,uchar * packet,int length)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 */
ftgmac100_recv(struct udevice * dev,int flags,uchar ** packetp)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
ftgmac100_read_txdesc(const void * desc)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
BUILD_WAIT_FOR_BIT(ftgmac100_txdone,u32,ftgmac100_read_txdesc)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(%p, %x)\n", __func__, 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
ftgmac100_write_hwaddr(struct udevice * dev)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
ftgmac100_ofdata_to_platdata(struct udevice * dev)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
ftgmac100_probe(struct udevice * dev)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 if (!IS_ENABLED(CONFIG_PHY_NCSI)) {
601 dev_err(dev,
602 "ftgmac100: NCSI in dts but CONFIG_PHY_NCSI missing. Please fix config\n");
603 return -EINVAL;
604 }
605
606 printf("%s - NCSI detected\n", __func__);
607 } else {
608 ret = ftgmac100_mdio_init(dev);
609 if (ret) {
610 dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
611 goto out;
612 }
613
614 }
615
616 ret = ftgmac100_phy_init(dev);
617 if (ret) {
618 dev_err(dev, "Failed to initialize PHY: %d\n", ret);
619 goto out;
620 }
621
622 out:
623 if (ret)
624 clk_release_bulk(&priv->clks);
625
626 return ret;
627 }
628
ftgmac100_remove(struct udevice * dev)629 static int ftgmac100_remove(struct udevice *dev)
630 {
631 struct ftgmac100_data *priv = dev_get_priv(dev);
632
633 if (!priv->ncsi_mode) {
634 free(priv->phydev);
635 mdio_unregister(priv->bus);
636 mdio_free(priv->bus);
637 } else {
638 free(priv->phydev);
639 }
640 clk_release_bulk(&priv->clks);
641
642 return 0;
643 }
644
645 static const struct eth_ops ftgmac100_ops = {
646 .start = ftgmac100_start,
647 .send = ftgmac100_send,
648 .recv = ftgmac100_recv,
649 .stop = ftgmac100_stop,
650 .free_pkt = ftgmac100_free_pkt,
651 .write_hwaddr = ftgmac100_write_hwaddr,
652 };
653
654 static const struct udevice_id ftgmac100_ids[] = {
655 { .compatible = "faraday,ftgmac100", .data = FTGMAC100_MODEL_FARADAY },
656 { .compatible = "aspeed,ast2400-mac", .data = FTGMAC100_MODEL_ASPEED },
657 { .compatible = "aspeed,ast2500-mac", .data = FTGMAC100_MODEL_ASPEED },
658 { .compatible = "aspeed,ast2600-mac", .data = FTGMAC100_MODEL_NEW_ASPEED },
659 { }
660 };
661
662 U_BOOT_DRIVER(ftgmac100) = {
663 .name = "ftgmac100",
664 .id = UCLASS_ETH,
665 .of_match = ftgmac100_ids,
666 .ofdata_to_platdata = ftgmac100_ofdata_to_platdata,
667 .probe = ftgmac100_probe,
668 .remove = ftgmac100_remove,
669 .ops = &ftgmac100_ops,
670 .priv_auto_alloc_size = sizeof(struct ftgmac100_data),
671 .platdata_auto_alloc_size = sizeof(struct eth_pdata),
672 .flags = DM_FLAG_ALLOC_PRIV_DMA,
673 };
674