1 /* 2 * (C) Copyright 2010 3 * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 /* 9 * Designware ethernet IP driver for U-Boot 10 */ 11 12 #include <common.h> 13 #include <dm.h> 14 #include <errno.h> 15 #include <miiphy.h> 16 #include <malloc.h> 17 #include <pci.h> 18 #include <linux/compiler.h> 19 #include <linux/err.h> 20 #include <asm/io.h> 21 #include "designware.h" 22 23 DECLARE_GLOBAL_DATA_PTR; 24 25 #if !defined(CONFIG_PHYLIB) 26 # error "DesignWare Ether MAC requires PHYLIB - missing CONFIG_PHYLIB" 27 #endif 28 29 static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) 30 { 31 struct eth_mac_regs *mac_p = bus->priv; 32 ulong start; 33 u16 miiaddr; 34 int timeout = CONFIG_MDIO_TIMEOUT; 35 36 miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | 37 ((reg << MIIREGSHIFT) & MII_REGMSK); 38 39 writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); 40 41 start = get_timer(0); 42 while (get_timer(start) < timeout) { 43 if (!(readl(&mac_p->miiaddr) & MII_BUSY)) 44 return readl(&mac_p->miidata); 45 udelay(10); 46 }; 47 48 return -ETIMEDOUT; 49 } 50 51 static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, 52 u16 val) 53 { 54 struct eth_mac_regs *mac_p = bus->priv; 55 ulong start; 56 u16 miiaddr; 57 int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT; 58 59 writel(val, &mac_p->miidata); 60 miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | 61 ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE; 62 63 writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); 64 65 start = get_timer(0); 66 while (get_timer(start) < timeout) { 67 if (!(readl(&mac_p->miiaddr) & MII_BUSY)) { 68 ret = 0; 69 break; 70 } 71 udelay(10); 72 }; 73 74 return ret; 75 } 76 77 static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p) 78 { 79 struct mii_dev *bus = mdio_alloc(); 80 81 if (!bus) { 82 printf("Failed to allocate MDIO bus\n"); 83 return -ENOMEM; 84 } 85 86 bus->read = dw_mdio_read; 87 bus->write = dw_mdio_write; 88 snprintf(bus->name, sizeof(bus->name), name); 89 90 bus->priv = (void *)mac_regs_p; 91 92 return mdio_register(bus); 93 } 94 95 static void tx_descs_init(struct dw_eth_dev *priv) 96 { 97 struct eth_dma_regs *dma_p = priv->dma_regs_p; 98 struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0]; 99 char *txbuffs = &priv->txbuffs[0]; 100 struct dmamacdescr *desc_p; 101 u32 idx; 102 103 for (idx = 0; idx < CONFIG_TX_DESCR_NUM; idx++) { 104 desc_p = &desc_table_p[idx]; 105 desc_p->dmamac_addr = &txbuffs[idx * CONFIG_ETH_BUFSIZE]; 106 desc_p->dmamac_next = &desc_table_p[idx + 1]; 107 108 #if defined(CONFIG_DW_ALTDESCRIPTOR) 109 desc_p->txrx_status &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST | 110 DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \ 111 DESC_TXSTS_TXCHECKINSCTRL | \ 112 DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS); 113 114 desc_p->txrx_status |= DESC_TXSTS_TXCHAIN; 115 desc_p->dmamac_cntl = 0; 116 desc_p->txrx_status &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA); 117 #else 118 desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN; 119 desc_p->txrx_status = 0; 120 #endif 121 } 122 123 /* Correcting the last pointer of the chain */ 124 desc_p->dmamac_next = &desc_table_p[0]; 125 126 /* Flush all Tx buffer descriptors at once */ 127 flush_dcache_range((unsigned int)priv->tx_mac_descrtable, 128 (unsigned int)priv->tx_mac_descrtable + 129 sizeof(priv->tx_mac_descrtable)); 130 131 writel((ulong)&desc_table_p[0], &dma_p->txdesclistaddr); 132 priv->tx_currdescnum = 0; 133 } 134 135 static void rx_descs_init(struct dw_eth_dev *priv) 136 { 137 struct eth_dma_regs *dma_p = priv->dma_regs_p; 138 struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0]; 139 char *rxbuffs = &priv->rxbuffs[0]; 140 struct dmamacdescr *desc_p; 141 u32 idx; 142 143 /* Before passing buffers to GMAC we need to make sure zeros 144 * written there right after "priv" structure allocation were 145 * flushed into RAM. 146 * Otherwise there's a chance to get some of them flushed in RAM when 147 * GMAC is already pushing data to RAM via DMA. This way incoming from 148 * GMAC data will be corrupted. */ 149 flush_dcache_range((unsigned int)rxbuffs, (unsigned int)rxbuffs + 150 RX_TOTAL_BUFSIZE); 151 152 for (idx = 0; idx < CONFIG_RX_DESCR_NUM; idx++) { 153 desc_p = &desc_table_p[idx]; 154 desc_p->dmamac_addr = &rxbuffs[idx * CONFIG_ETH_BUFSIZE]; 155 desc_p->dmamac_next = &desc_table_p[idx + 1]; 156 157 desc_p->dmamac_cntl = 158 (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | \ 159 DESC_RXCTRL_RXCHAIN; 160 161 desc_p->txrx_status = DESC_RXSTS_OWNBYDMA; 162 } 163 164 /* Correcting the last pointer of the chain */ 165 desc_p->dmamac_next = &desc_table_p[0]; 166 167 /* Flush all Rx buffer descriptors at once */ 168 flush_dcache_range((unsigned int)priv->rx_mac_descrtable, 169 (unsigned int)priv->rx_mac_descrtable + 170 sizeof(priv->rx_mac_descrtable)); 171 172 writel((ulong)&desc_table_p[0], &dma_p->rxdesclistaddr); 173 priv->rx_currdescnum = 0; 174 } 175 176 static int _dw_write_hwaddr(struct dw_eth_dev *priv, u8 *mac_id) 177 { 178 struct eth_mac_regs *mac_p = priv->mac_regs_p; 179 u32 macid_lo, macid_hi; 180 181 macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) + 182 (mac_id[3] << 24); 183 macid_hi = mac_id[4] + (mac_id[5] << 8); 184 185 writel(macid_hi, &mac_p->macaddr0hi); 186 writel(macid_lo, &mac_p->macaddr0lo); 187 188 return 0; 189 } 190 191 static void dw_adjust_link(struct eth_mac_regs *mac_p, 192 struct phy_device *phydev) 193 { 194 u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN; 195 196 if (!phydev->link) { 197 printf("%s: No link.\n", phydev->dev->name); 198 return; 199 } 200 201 if (phydev->speed != 1000) 202 conf |= MII_PORTSELECT; 203 204 if (phydev->speed == 100) 205 conf |= FES_100; 206 207 if (phydev->duplex) 208 conf |= FULLDPLXMODE; 209 210 writel(conf, &mac_p->conf); 211 212 printf("Speed: %d, %s duplex%s\n", phydev->speed, 213 (phydev->duplex) ? "full" : "half", 214 (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); 215 } 216 217 static void _dw_eth_halt(struct dw_eth_dev *priv) 218 { 219 struct eth_mac_regs *mac_p = priv->mac_regs_p; 220 struct eth_dma_regs *dma_p = priv->dma_regs_p; 221 222 writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf); 223 writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode); 224 225 phy_shutdown(priv->phydev); 226 } 227 228 static int _dw_eth_init(struct dw_eth_dev *priv, u8 *enetaddr) 229 { 230 struct eth_mac_regs *mac_p = priv->mac_regs_p; 231 struct eth_dma_regs *dma_p = priv->dma_regs_p; 232 unsigned int start; 233 int ret; 234 235 writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); 236 237 start = get_timer(0); 238 while (readl(&dma_p->busmode) & DMAMAC_SRST) { 239 if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) { 240 printf("DMA reset timeout\n"); 241 return -ETIMEDOUT; 242 } 243 244 mdelay(100); 245 }; 246 247 /* 248 * Soft reset above clears HW address registers. 249 * So we have to set it here once again. 250 */ 251 _dw_write_hwaddr(priv, enetaddr); 252 253 rx_descs_init(priv); 254 tx_descs_init(priv); 255 256 writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode); 257 258 #ifndef CONFIG_DW_MAC_FORCE_THRESHOLD_MODE 259 writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, 260 &dma_p->opmode); 261 #else 262 writel(readl(&dma_p->opmode) | FLUSHTXFIFO, 263 &dma_p->opmode); 264 #endif 265 266 writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode); 267 268 #ifdef CONFIG_DW_AXI_BURST_LEN 269 writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus); 270 #endif 271 272 /* Start up the PHY */ 273 ret = phy_startup(priv->phydev); 274 if (ret) { 275 printf("Could not initialize PHY %s\n", 276 priv->phydev->dev->name); 277 return ret; 278 } 279 280 dw_adjust_link(mac_p, priv->phydev); 281 282 if (!priv->phydev->link) 283 return -EIO; 284 285 writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf); 286 287 return 0; 288 } 289 290 static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length) 291 { 292 struct eth_dma_regs *dma_p = priv->dma_regs_p; 293 u32 desc_num = priv->tx_currdescnum; 294 struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num]; 295 uint32_t desc_start = (uint32_t)desc_p; 296 uint32_t desc_end = desc_start + 297 roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); 298 uint32_t data_start = (uint32_t)desc_p->dmamac_addr; 299 uint32_t data_end = data_start + 300 roundup(length, ARCH_DMA_MINALIGN); 301 /* 302 * Strictly we only need to invalidate the "txrx_status" field 303 * for the following check, but on some platforms we cannot 304 * invalidate only 4 bytes, so we flush the entire descriptor, 305 * which is 16 bytes in total. This is safe because the 306 * individual descriptors in the array are each aligned to 307 * ARCH_DMA_MINALIGN and padded appropriately. 308 */ 309 invalidate_dcache_range(desc_start, desc_end); 310 311 /* Check if the descriptor is owned by CPU */ 312 if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) { 313 printf("CPU not owner of tx frame\n"); 314 return -EPERM; 315 } 316 317 memcpy(desc_p->dmamac_addr, packet, length); 318 319 /* Flush data to be sent */ 320 flush_dcache_range(data_start, data_end); 321 322 #if defined(CONFIG_DW_ALTDESCRIPTOR) 323 desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST; 324 desc_p->dmamac_cntl |= (length << DESC_TXCTRL_SIZE1SHFT) & \ 325 DESC_TXCTRL_SIZE1MASK; 326 327 desc_p->txrx_status &= ~(DESC_TXSTS_MSK); 328 desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA; 329 #else 330 desc_p->dmamac_cntl |= ((length << DESC_TXCTRL_SIZE1SHFT) & \ 331 DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \ 332 DESC_TXCTRL_TXFIRST; 333 334 desc_p->txrx_status = DESC_TXSTS_OWNBYDMA; 335 #endif 336 337 /* Flush modified buffer descriptor */ 338 flush_dcache_range(desc_start, desc_end); 339 340 /* Test the wrap-around condition. */ 341 if (++desc_num >= CONFIG_TX_DESCR_NUM) 342 desc_num = 0; 343 344 priv->tx_currdescnum = desc_num; 345 346 /* Start the transmission */ 347 writel(POLL_DATA, &dma_p->txpolldemand); 348 349 return 0; 350 } 351 352 static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp) 353 { 354 u32 status, desc_num = priv->rx_currdescnum; 355 struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; 356 int length = -EAGAIN; 357 uint32_t desc_start = (uint32_t)desc_p; 358 uint32_t desc_end = desc_start + 359 roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); 360 uint32_t data_start = (uint32_t)desc_p->dmamac_addr; 361 uint32_t data_end; 362 363 /* Invalidate entire buffer descriptor */ 364 invalidate_dcache_range(desc_start, desc_end); 365 366 status = desc_p->txrx_status; 367 368 /* Check if the owner is the CPU */ 369 if (!(status & DESC_RXSTS_OWNBYDMA)) { 370 371 length = (status & DESC_RXSTS_FRMLENMSK) >> \ 372 DESC_RXSTS_FRMLENSHFT; 373 374 /* Invalidate received data */ 375 data_end = data_start + roundup(length, ARCH_DMA_MINALIGN); 376 invalidate_dcache_range(data_start, data_end); 377 *packetp = desc_p->dmamac_addr; 378 } 379 380 return length; 381 } 382 383 static int _dw_free_pkt(struct dw_eth_dev *priv) 384 { 385 u32 desc_num = priv->rx_currdescnum; 386 struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num]; 387 uint32_t desc_start = (uint32_t)desc_p; 388 uint32_t desc_end = desc_start + 389 roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN); 390 391 /* 392 * Make the current descriptor valid again and go to 393 * the next one 394 */ 395 desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA; 396 397 /* Flush only status field - others weren't changed */ 398 flush_dcache_range(desc_start, desc_end); 399 400 /* Test the wrap-around condition. */ 401 if (++desc_num >= CONFIG_RX_DESCR_NUM) 402 desc_num = 0; 403 priv->rx_currdescnum = desc_num; 404 405 return 0; 406 } 407 408 static int dw_phy_init(struct dw_eth_dev *priv, void *dev) 409 { 410 struct phy_device *phydev; 411 int mask = 0xffffffff; 412 413 #ifdef CONFIG_PHY_ADDR 414 mask = 1 << CONFIG_PHY_ADDR; 415 #endif 416 417 phydev = phy_find_by_mask(priv->bus, mask, priv->interface); 418 if (!phydev) 419 return -ENODEV; 420 421 phy_connect_dev(phydev, dev); 422 423 phydev->supported &= PHY_GBIT_FEATURES; 424 phydev->advertising = phydev->supported; 425 426 priv->phydev = phydev; 427 phy_config(phydev); 428 429 return 0; 430 } 431 432 #ifndef CONFIG_DM_ETH 433 static int dw_eth_init(struct eth_device *dev, bd_t *bis) 434 { 435 return _dw_eth_init(dev->priv, dev->enetaddr); 436 } 437 438 static int dw_eth_send(struct eth_device *dev, void *packet, int length) 439 { 440 return _dw_eth_send(dev->priv, packet, length); 441 } 442 443 static int dw_eth_recv(struct eth_device *dev) 444 { 445 uchar *packet; 446 int length; 447 448 length = _dw_eth_recv(dev->priv, &packet); 449 if (length == -EAGAIN) 450 return 0; 451 net_process_received_packet(packet, length); 452 453 _dw_free_pkt(dev->priv); 454 455 return 0; 456 } 457 458 static void dw_eth_halt(struct eth_device *dev) 459 { 460 return _dw_eth_halt(dev->priv); 461 } 462 463 static int dw_write_hwaddr(struct eth_device *dev) 464 { 465 return _dw_write_hwaddr(dev->priv, dev->enetaddr); 466 } 467 468 int designware_initialize(ulong base_addr, u32 interface) 469 { 470 struct eth_device *dev; 471 struct dw_eth_dev *priv; 472 473 dev = (struct eth_device *) malloc(sizeof(struct eth_device)); 474 if (!dev) 475 return -ENOMEM; 476 477 /* 478 * Since the priv structure contains the descriptors which need a strict 479 * buswidth alignment, memalign is used to allocate memory 480 */ 481 priv = (struct dw_eth_dev *) memalign(ARCH_DMA_MINALIGN, 482 sizeof(struct dw_eth_dev)); 483 if (!priv) { 484 free(dev); 485 return -ENOMEM; 486 } 487 488 memset(dev, 0, sizeof(struct eth_device)); 489 memset(priv, 0, sizeof(struct dw_eth_dev)); 490 491 sprintf(dev->name, "dwmac.%lx", base_addr); 492 dev->iobase = (int)base_addr; 493 dev->priv = priv; 494 495 priv->dev = dev; 496 priv->mac_regs_p = (struct eth_mac_regs *)base_addr; 497 priv->dma_regs_p = (struct eth_dma_regs *)(base_addr + 498 DW_DMA_BASE_OFFSET); 499 500 dev->init = dw_eth_init; 501 dev->send = dw_eth_send; 502 dev->recv = dw_eth_recv; 503 dev->halt = dw_eth_halt; 504 dev->write_hwaddr = dw_write_hwaddr; 505 506 eth_register(dev); 507 508 priv->interface = interface; 509 510 dw_mdio_init(dev->name, priv->mac_regs_p); 511 priv->bus = miiphy_get_dev_by_name(dev->name); 512 513 return dw_phy_init(priv, dev); 514 } 515 #endif 516 517 #ifdef CONFIG_DM_ETH 518 static int designware_eth_start(struct udevice *dev) 519 { 520 struct eth_pdata *pdata = dev_get_platdata(dev); 521 522 return _dw_eth_init(dev->priv, pdata->enetaddr); 523 } 524 525 static int designware_eth_send(struct udevice *dev, void *packet, int length) 526 { 527 struct dw_eth_dev *priv = dev_get_priv(dev); 528 529 return _dw_eth_send(priv, packet, length); 530 } 531 532 static int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp) 533 { 534 struct dw_eth_dev *priv = dev_get_priv(dev); 535 536 return _dw_eth_recv(priv, packetp); 537 } 538 539 static int designware_eth_free_pkt(struct udevice *dev, uchar *packet, 540 int length) 541 { 542 struct dw_eth_dev *priv = dev_get_priv(dev); 543 544 return _dw_free_pkt(priv); 545 } 546 547 static void designware_eth_stop(struct udevice *dev) 548 { 549 struct dw_eth_dev *priv = dev_get_priv(dev); 550 551 return _dw_eth_halt(priv); 552 } 553 554 static int designware_eth_write_hwaddr(struct udevice *dev) 555 { 556 struct eth_pdata *pdata = dev_get_platdata(dev); 557 struct dw_eth_dev *priv = dev_get_priv(dev); 558 559 return _dw_write_hwaddr(priv, pdata->enetaddr); 560 } 561 562 static int designware_eth_bind(struct udevice *dev) 563 { 564 #ifdef CONFIG_DM_PCI 565 static int num_cards; 566 char name[20]; 567 568 /* Create a unique device name for PCI type devices */ 569 if (device_is_on_pci_bus(dev)) { 570 sprintf(name, "eth_designware#%u", num_cards++); 571 device_set_name(dev, name); 572 } 573 #endif 574 575 return 0; 576 } 577 578 static int designware_eth_probe(struct udevice *dev) 579 { 580 struct eth_pdata *pdata = dev_get_platdata(dev); 581 struct dw_eth_dev *priv = dev_get_priv(dev); 582 u32 iobase = pdata->iobase; 583 int ret; 584 585 #ifdef CONFIG_DM_PCI 586 /* 587 * If we are on PCI bus, either directly attached to a PCI root port, 588 * or via a PCI bridge, fill in platdata before we probe the hardware. 589 */ 590 if (device_is_on_pci_bus(dev)) { 591 pci_dev_t bdf = pci_get_bdf(dev); 592 593 dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase); 594 iobase &= PCI_BASE_ADDRESS_MEM_MASK; 595 iobase = pci_mem_to_phys(bdf, iobase); 596 597 pdata->iobase = iobase; 598 pdata->phy_interface = PHY_INTERFACE_MODE_RMII; 599 } 600 #endif 601 602 debug("%s, iobase=%x, priv=%p\n", __func__, iobase, priv); 603 priv->mac_regs_p = (struct eth_mac_regs *)iobase; 604 priv->dma_regs_p = (struct eth_dma_regs *)(iobase + DW_DMA_BASE_OFFSET); 605 priv->interface = pdata->phy_interface; 606 607 dw_mdio_init(dev->name, priv->mac_regs_p); 608 priv->bus = miiphy_get_dev_by_name(dev->name); 609 610 ret = dw_phy_init(priv, dev); 611 debug("%s, ret=%d\n", __func__, ret); 612 613 return ret; 614 } 615 616 static int designware_eth_remove(struct udevice *dev) 617 { 618 struct dw_eth_dev *priv = dev_get_priv(dev); 619 620 free(priv->phydev); 621 mdio_unregister(priv->bus); 622 mdio_free(priv->bus); 623 624 return 0; 625 } 626 627 static const struct eth_ops designware_eth_ops = { 628 .start = designware_eth_start, 629 .send = designware_eth_send, 630 .recv = designware_eth_recv, 631 .free_pkt = designware_eth_free_pkt, 632 .stop = designware_eth_stop, 633 .write_hwaddr = designware_eth_write_hwaddr, 634 }; 635 636 static int designware_eth_ofdata_to_platdata(struct udevice *dev) 637 { 638 struct eth_pdata *pdata = dev_get_platdata(dev); 639 const char *phy_mode; 640 641 pdata->iobase = dev_get_addr(dev); 642 pdata->phy_interface = -1; 643 phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL); 644 if (phy_mode) 645 pdata->phy_interface = phy_get_interface_by_name(phy_mode); 646 if (pdata->phy_interface == -1) { 647 debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); 648 return -EINVAL; 649 } 650 651 return 0; 652 } 653 654 static const struct udevice_id designware_eth_ids[] = { 655 { .compatible = "allwinner,sun7i-a20-gmac" }, 656 { .compatible = "altr,socfpga-stmmac" }, 657 { } 658 }; 659 660 U_BOOT_DRIVER(eth_designware) = { 661 .name = "eth_designware", 662 .id = UCLASS_ETH, 663 .of_match = designware_eth_ids, 664 .ofdata_to_platdata = designware_eth_ofdata_to_platdata, 665 .bind = designware_eth_bind, 666 .probe = designware_eth_probe, 667 .remove = designware_eth_remove, 668 .ops = &designware_eth_ops, 669 .priv_auto_alloc_size = sizeof(struct dw_eth_dev), 670 .platdata_auto_alloc_size = sizeof(struct eth_pdata), 671 .flags = DM_FLAG_ALLOC_PRIV_DMA, 672 }; 673 674 static struct pci_device_id supported[] = { 675 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_QRK_EMAC) }, 676 { } 677 }; 678 679 U_BOOT_PCI_DEVICE(eth_designware, supported); 680 #endif 681