// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) /* * Copyright (c) 2014-2025, Advanced Micro Devices, Inc. * Copyright (c) 2014, Synopsys, Inc. * All rights reserved
*/
phy_node = of_parse_phandle(dev->of_node, "phy-handle", 0); if (phy_node) { /* Old style device tree: * The XGBE and PHY resources are separate
*/
phy_pdev = of_find_device_by_node(phy_node);
of_node_put(phy_node);
} else { /* New style device tree: * The XGBE and PHY resources are grouped together with * the PHY resources listed last
*/
get_device(dev);
phy_pdev = pdata->platdev;
}
/* Check if we should use ACPI or DT */
pdata->use_acpi = dev->of_node ? 0 : 1;
/* Get the version data */
pdata->vdata = (struct xgbe_version_data *)device_get_match_data(dev);
phy_pdev = xgbe_get_phy_pdev(pdata); if (!phy_pdev) {
dev_err(dev, "unable to obtain phy device\n");
ret = -EINVAL; goto err_phydev;
}
pdata->phy_platdev = phy_pdev;
pdata->phy_dev = &phy_pdev->dev;
if (pdev == phy_pdev) { /* New style device tree or ACPI: * The XGBE and PHY resources are grouped together with * the PHY resources listed last
*/
phy_memnum = xgbe_resource_count(pdev, IORESOURCE_MEM) - 3;
phy_irqnum = platform_irq_count(pdev) - 1;
dma_irqnum = 1;
dma_irqend = phy_irqnum;
} else { /* Old style device tree: * The XGBE and PHY resources are separate
*/
phy_memnum = 0;
phy_irqnum = 0;
dma_irqnum = 1;
dma_irqend = platform_irq_count(pdev);
}
/* Obtain the mmio areas for the device */
pdata->xgmac_regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pdata->xgmac_regs)) {
dev_err(dev, "xgmac ioremap failed\n");
ret = PTR_ERR(pdata->xgmac_regs); goto err_io;
} if (netif_msg_probe(pdata))
dev_dbg(dev, "xgmac_regs = %p\n", pdata->xgmac_regs);
pdata->xpcs_regs = devm_platform_ioremap_resource(pdev, 1); if (IS_ERR(pdata->xpcs_regs)) {
dev_err(dev, "xpcs ioremap failed\n");
ret = PTR_ERR(pdata->xpcs_regs); goto err_io;
} if (netif_msg_probe(pdata))
dev_dbg(dev, "xpcs_regs = %p\n", pdata->xpcs_regs);
pdata->rxtx_regs = devm_platform_ioremap_resource(phy_pdev,
phy_memnum++); if (IS_ERR(pdata->rxtx_regs)) {
dev_err(dev, "rxtx ioremap failed\n");
ret = PTR_ERR(pdata->rxtx_regs); goto err_io;
} if (netif_msg_probe(pdata))
dev_dbg(dev, "rxtx_regs = %p\n", pdata->rxtx_regs);
pdata->sir0_regs = devm_platform_ioremap_resource(phy_pdev,
phy_memnum++); if (IS_ERR(pdata->sir0_regs)) {
dev_err(dev, "sir0 ioremap failed\n");
ret = PTR_ERR(pdata->sir0_regs); goto err_io;
} if (netif_msg_probe(pdata))
dev_dbg(dev, "sir0_regs = %p\n", pdata->sir0_regs);
pdata->sir1_regs = devm_platform_ioremap_resource(phy_pdev,
phy_memnum++); if (IS_ERR(pdata->sir1_regs)) {
dev_err(dev, "sir1 ioremap failed\n");
ret = PTR_ERR(pdata->sir1_regs); goto err_io;
} if (netif_msg_probe(pdata))
dev_dbg(dev, "sir1_regs = %p\n", pdata->sir1_regs);
/* Retrieve the MAC address */
ret = device_property_read_u8_array(dev, XGBE_MAC_ADDR_PROPERTY,
pdata->mac_addr, sizeof(pdata->mac_addr)); if (ret || !is_valid_ether_addr(pdata->mac_addr)) {
dev_err(dev, "invalid %s property\n", XGBE_MAC_ADDR_PROPERTY); if (!ret)
ret = -EINVAL; goto err_io;
}
/* Retrieve the PHY mode - it must be "xgmii" */
ret = device_property_read_string(dev, XGBE_PHY_MODE_PROPERTY,
&phy_mode); if (ret || strcmp(phy_mode, phy_modes(PHY_INTERFACE_MODE_XGMII))) {
dev_err(dev, "invalid %s property\n", XGBE_PHY_MODE_PROPERTY); if (!ret)
ret = -EINVAL; goto err_io;
}
pdata->phy_mode = PHY_INTERFACE_MODE_XGMII;
/* Check for per channel interrupt support */ if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) {
pdata->per_channel_irq = 1;
pdata->channel_irq_mode = XGBE_IRQ_MODE_EDGE;
}
/* Obtain device settings unique to ACPI/OF */ if (pdata->use_acpi)
ret = xgbe_acpi_support(pdata); else
ret = xgbe_of_support(pdata); if (ret) goto err_io;
/* Set the DMA coherency values */
attr = device_get_dma_attr(dev); if (attr == DEV_DMA_NOT_SUPPORTED) {
dev_err(dev, "DMA is not supported");
ret = -ENODEV; goto err_io;
}
pdata->coherent = (attr == DEV_DMA_COHERENT); if (pdata->coherent) {
pdata->arcr = XGBE_DMA_OS_ARCR;
pdata->awcr = XGBE_DMA_OS_AWCR;
} else {
pdata->arcr = XGBE_DMA_SYS_ARCR;
pdata->awcr = XGBE_DMA_SYS_AWCR;
}
/* Set the maximum fifo amounts */
pdata->tx_max_fifo_size = pdata->vdata->tx_max_fifo_size;
pdata->rx_max_fifo_size = pdata->vdata->rx_max_fifo_size;
/* Set the hardware channel and queue counts */
xgbe_set_counts(pdata);
/* Always have XGMAC and XPCS (auto-negotiation) interrupts */
pdata->irq_count = 2;
/* Get the device interrupt */
ret = platform_get_irq(pdev, 0); if (ret < 0) goto err_io;
pdata->dev_irq = ret;
/* Get the per channel DMA interrupts */ if (pdata->per_channel_irq) { unsignedint i, max = ARRAY_SIZE(pdata->channel_irq);
for (i = 0; (i < max) && (dma_irqnum < dma_irqend); i++) {
ret = platform_get_irq(pdata->platdev, dma_irqnum++); if (ret < 0) goto err_io;
pdata->channel_irq[i] = ret;
}
pdata->channel_irq_count = max;
pdata->irq_count += max;
}
/* Get the auto-negotiation interrupt */
ret = platform_get_irq(phy_pdev, phy_irqnum++); if (ret < 0) goto err_io;
pdata->an_irq = ret;
/* Configure the netdev resource */
ret = xgbe_config_netdev(pdata); if (ret) goto err_io;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.