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