static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv, struct device_node *dn) { struct device_node *port; const char *phy_mode_str; int mode; unsigned int port_num; int ret; priv->moca_port = -1; for_each_available_child_of_node(dn, port) { if (of_property_read_u32(port, "reg", &port_num)) continue; /* Internal PHYs get assigned a specific 'phy-mode' property * value: "internal" to help flag them before MDIO probing * has completed, since they might be turned off at that * time */ mode = of_get_phy_mode(port); if (mode < 0) { ret = of_property_read_string(port, "phy-mode", &phy_mode_str); if (ret < 0) continue; if (!strcasecmp(phy_mode_str, "internal")) priv->int_phy_mask |= 1 << port_num; } if (mode == PHY_INTERFACE_MODE_MOCA) priv->moca_port = port_num; } }
static int __devinit stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; if (!np) return -ENODEV; *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac")) { plat->has_gmac = 1; plat->pmt = 1; } return 0; }
static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv) { struct device_node *dn = priv->pdev->dev.of_node; struct device *kdev = &priv->pdev->dev; struct device_node *mdio_dn; char *compat; int ret; compat = kasprintf(GFP_KERNEL, "brcm,genet-mdio-v%d", priv->version); if (!compat) return -ENOMEM; mdio_dn = of_find_compatible_node(dn, NULL, compat); kfree(compat); if (!mdio_dn) { dev_err(kdev, "unable to find MDIO bus node\n"); return -ENODEV; } ret = of_mdiobus_register(priv->mii_bus, mdio_dn); if (ret) { dev_err(kdev, "failed to register MDIO bus\n"); return ret; } /* Fetch the PHY phandle */ priv->phy_dn = of_parse_phandle(dn, "phy-handle", 0); /* Get the link mode */ priv->phy_interface = of_get_phy_mode(dn); return 0; }
/* slave device setup *******************************************************/ static int dsa_slave_phy_setup(struct dsa_slave_priv *p, struct net_device *slave_dev) { struct dsa_switch *ds = p->parent; struct dsa_chip_data *cd = ds->pd; struct device_node *phy_dn, *port_dn; bool phy_is_fixed = false; u32 phy_flags = 0; int mode, ret; port_dn = cd->port_dn[p->port]; mode = of_get_phy_mode(port_dn); if (mode < 0) mode = PHY_INTERFACE_MODE_NA; p->phy_interface = mode; phy_dn = of_parse_phandle(port_dn, "phy-handle", 0); if (of_phy_is_fixed_link(port_dn)) { /* In the case of a fixed PHY, the DT node associated * to the fixed PHY is the Port DT node */ ret = of_phy_register_fixed_link(port_dn); if (ret) { netdev_err(slave_dev, "failed to register fixed PHY\n"); return ret; } phy_is_fixed = true; phy_dn = port_dn; } if (ds->drv->get_phy_flags) phy_flags = ds->drv->get_phy_flags(ds, p->port); if (phy_dn) p->phy = of_phy_connect(slave_dev, phy_dn, dsa_slave_adjust_link, phy_flags, p->phy_interface); if (p->phy && phy_is_fixed) fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update); /* We could not connect to a designated PHY, so use the switch internal * MDIO bus instead */ if (!p->phy) { p->phy = ds->slave_mii_bus->phy_map[p->port]; if (!p->phy) return -ENODEV; /* Use already configured phy mode */ p->phy_interface = p->phy->interface; phy_connect_direct(slave_dev, p->phy, dsa_slave_adjust_link, p->phy_interface); } else { netdev_info(slave_dev, "attached PHY at address %d [%s]\n", p->phy->addr, p->phy->drv->name); } return 0; }
static void bcm_sf2_identify_ports(struct bcm_sf2_priv *priv, struct device_node *dn) { struct device_node *port; int mode; unsigned int port_num; priv->moca_port = -1; for_each_available_child_of_node(dn, port) { if (of_property_read_u32(port, "reg", &port_num)) continue; /* Internal PHYs get assigned a specific 'phy-mode' property * value: "internal" to help flag them before MDIO probing * has completed, since they might be turned off at that * time */ mode = of_get_phy_mode(port); if (mode < 0) continue; if (mode == PHY_INTERFACE_MODE_INTERNAL) priv->int_phy_mask |= 1 << port_num; if (mode == PHY_INTERFACE_MODE_MOCA) priv->moca_port = port_num; if (of_property_read_bool(port, "brcm,use-bcm-hdr")) priv->brcm_tag_mask |= 1 << port_num; } }
static int sxgbe_probe_config_dt(struct platform_device *pdev, struct sxgbe_plat_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; struct sxgbe_dma_cfg *dma_cfg; if (!np) return -ENODEV; *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); plat->bus_id = of_alias_get_id(np, "ethernet"); if (plat->bus_id < 0) plat->bus_id = 0; plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(*plat->mdio_bus_data), GFP_KERNEL); dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL); if (!dma_cfg) return -ENOMEM; plat->dma_cfg = dma_cfg; of_property_read_u32(np, "samsung,pbl", &dma_cfg->pbl); if (of_property_read_u32(np, "samsung,burst-map", &dma_cfg->burst_map) == 0) dma_cfg->fixed_burst = true; return 0; }
static int at91ether_get_phy_mode_dt(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; if (np) return of_get_phy_mode(np); return -ENODEV; }
static int stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; struct stmmac_dma_cfg *dma_cfg; if (!np) return -ENODEV; *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); plat->bus_id = of_alias_get_id(np, "ethernet"); if (plat->bus_id < 0) plat->bus_id = 0; of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr); plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { plat->has_gmac = 1; plat->pmt = 1; } if (of_device_is_compatible(np, "snps,dwmac-3.610") || of_device_is_compatible(np, "snps,dwmac-3.710")) { plat->enh_desc = 1; plat->bugged_jumbo = 1; plat->force_sf_dma_mode = 1; } dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL); if (!dma_cfg) return -ENOMEM; plat->dma_cfg = dma_cfg; of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst"); dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst"); return 0; }
static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) { struct device_node *np = dev->of_node; struct regmap *sys_mgr_base_addr; u32 reg_offset, reg_shift; int ret; struct device_node *np_splitter; struct resource res_splitter; dwmac->interface = of_get_phy_mode(np); sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); if (IS_ERR(sys_mgr_base_addr)) { dev_info(dev, "No sysmgr-syscon node found\n"); return PTR_ERR(sys_mgr_base_addr); } ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, ®_offset); if (ret) { dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n"); return -EINVAL; } ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, ®_shift); if (ret) { dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n"); return -EINVAL; } dwmac->f2h_ptp_ref_clk = of_property_read_bool(np, "altr,f2h_ptp_ref_clk"); np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0); if (np_splitter) { if (of_address_to_resource(np_splitter, 0, &res_splitter)) { dev_info(dev, "Missing emac splitter address\n"); return -EINVAL; } dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter); if (IS_ERR(dwmac->splitter_base)) { dev_info(dev, "Failed to mapping emac splitter\n"); return PTR_ERR(dwmac->splitter_base); } } dwmac->reg_offset = reg_offset; dwmac->reg_shift = reg_shift; dwmac->sys_mgr_base_addr = sys_mgr_base_addr; dwmac->dev = dev; return 0; }
static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv) { struct device_node *dn = priv->pdev->dev.of_node; struct device *kdev = &priv->pdev->dev; struct phy_device *phydev; int phy_mode; int ret; /* Fetch the PHY phandle */ priv->phy_dn = of_parse_phandle(dn, "phy-handle", 0); /* In the case of a fixed PHY, the DT node associated * to the PHY is the Ethernet MAC DT node. */ if (!priv->phy_dn && of_phy_is_fixed_link(dn)) { ret = of_phy_register_fixed_link(dn); if (ret) return ret; priv->phy_dn = of_node_get(dn); } /* Get the link mode */ phy_mode = of_get_phy_mode(dn); if (phy_mode < 0) { dev_err(kdev, "invalid PHY mode property\n"); return phy_mode; } priv->phy_interface = phy_mode; /* We need to specifically look up whether this PHY interface is internal * or not *before* we even try to probe the PHY driver over MDIO as we * may have shut down the internal PHY for power saving purposes. */ if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL) priv->internal_phy = true; /* Make sure we initialize MoCA PHYs with a link down */ if (phy_mode == PHY_INTERFACE_MODE_MOCA) { phydev = of_phy_find_device(dn); if (phydev) { phydev->link = 0; put_device(&phydev->mdio.dev); } } return 0; }
static void *ipq806x_gmac_of_parse(struct ipq806x_gmac *gmac) { struct device *dev = &gmac->pdev->dev; gmac->phy_mode = of_get_phy_mode(dev->of_node); if (gmac->phy_mode < 0) { dev_err(dev, "missing phy mode property\n"); return ERR_PTR(-EINVAL); } if (of_property_read_u32(dev->of_node, "qcom,id", &gmac->id) < 0) { dev_err(dev, "missing qcom id property\n"); return ERR_PTR(-EINVAL); } /* The GMACs are called 1 to 4 in the documentation, but to simplify the * code and keep it consistent with the Linux convention, we'll number * them from 0 to 3 here. */ if (gmac->id < 0 || gmac->id > 3) { dev_err(dev, "invalid gmac id\n"); return ERR_PTR(-EINVAL); } gmac->core_clk = devm_clk_get(dev, "stmmaceth"); if (IS_ERR(gmac->core_clk)) { dev_err(dev, "missing stmmaceth clk property\n"); return gmac->core_clk; } clk_set_rate(gmac->core_clk, 266000000); /* Setup the register map for the nss common registers */ gmac->nss_common = syscon_regmap_lookup_by_phandle(dev->of_node, "qcom,nss-common"); if (IS_ERR(gmac->nss_common)) { dev_err(dev, "missing nss-common node\n"); return gmac->nss_common; } /* Setup the register map for the qsgmii csr registers */ gmac->qsgmii_csr = syscon_regmap_lookup_by_phandle(dev->of_node, "qcom,qsgmii-csr"); if (IS_ERR(gmac->qsgmii_csr)) { dev_err(dev, "missing qsgmii-csr node\n"); return gmac->qsgmii_csr; } return NULL; }
static int stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; enum of_gpio_flags flags; if (!np) return -ENODEV; *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); plat->init = stmmc_pltfr_init; plat->fix_mac_speed = stmmc_pltfr_fix_mac_speed; g_bsp_priv.reset_io = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); g_bsp_priv.reset_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; g_bsp_priv.power_io = of_get_named_gpio_flags(np, "power-gpio", 0, &flags); g_bsp_priv.power_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; g_bsp_priv.phy_iface = plat->interface; g_bsp_priv.phy_power_on = phy_power_on; plat->bsp_priv = &g_bsp_priv; /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ if (of_device_is_compatible(np, "rockchip,gmac")) { plat->has_gmac = 1; plat->pmt = 1; } return 0; }
int mtk_connect_phy_node(struct mtk_eth *eth, struct mtk_mac *mac, struct device_node *phy_node) { const __be32 *_port = NULL; struct phy_device *phydev; int phy_mode, port; _port = of_get_property(phy_node, "reg", NULL); if (!_port || (be32_to_cpu(*_port) >= 0x20)) { pr_err("%s: invalid port id\n", phy_node->name); return -EINVAL; } port = be32_to_cpu(*_port); phy_mode = of_get_phy_mode(phy_node); if (phy_mode < 0) { dev_err(eth->dev, "incorrect phy-mode %d\n", phy_mode); eth->phy->phy_node[port] = NULL; return -EINVAL; } phydev = of_phy_connect(eth->netdev[mac->id], phy_node, mtk_phy_link_adjust, 0, phy_mode); if (!phydev) { dev_err(eth->dev, "could not connect to PHY\n"); eth->phy->phy_node[port] = NULL; return -ENODEV; } phydev->supported &= PHY_GBIT_FEATURES; phydev->advertising = phydev->supported; dev_info(eth->dev, "connected port %d to PHY at %s [uid=%08x, driver=%s]\n", port, phydev_name(phydev), phydev->phy_id, phydev->drv->name); eth->phy->phy[port] = phydev; eth->link[port] = 0; return 0; }
static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) { struct device_node *np = dev->of_node; struct regmap *sys_mgr_base_addr; u32 reg_offset, reg_shift; int ret; dwmac->stmmac_rst = devm_reset_control_get(dev, STMMAC_RESOURCE_NAME); if (IS_ERR(dwmac->stmmac_rst)) { dev_info(dev, "Could not get reset control!\n"); return -EINVAL; } dwmac->interface = of_get_phy_mode(np); sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); if (IS_ERR(sys_mgr_base_addr)) { dev_info(dev, "No sysmgr-syscon node found\n"); return PTR_ERR(sys_mgr_base_addr); } ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, ®_offset); if (ret) { dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n"); return -EINVAL; } ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, ®_shift); if (ret) { dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n"); return -EINVAL; } dwmac->reg_offset = reg_offset; dwmac->reg_shift = reg_shift; dwmac->sys_mgr_base_addr = sys_mgr_base_addr; dwmac->dev = dev; return 0; }
static int stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; enum of_gpio_flags flags; int ret; const char * strings = NULL; int value; if (!np) return -ENODEV; *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); plat->init = stmmc_pltfr_init; plat->fix_mac_speed = stmmc_pltfr_fix_mac_speed; ret = of_property_read_string(np, "pmu_regulator", &strings); if (ret) { pr_err("%s: Can not read property: pmu_regulator.\n", __func__); g_bsp_priv.power_ctrl_by_pmu = false; } else { pr_info("%s: ethernet phy power controled by pmu(%s).\n", __func__, strings); g_bsp_priv.power_ctrl_by_pmu = true; strcpy(g_bsp_priv.pmu_regulator, strings); } ret = of_property_read_u32(np, "pmu_enable_level", &value); if (ret) { pr_err("%s: Can not read property: pmu_enable_level.\n", __func__); g_bsp_priv.power_ctrl_by_pmu = false; } else { pr_info("%s: ethernet phy power controled by pmu(level = %s).\n", __func__, (value == 1)?"HIGH":"LOW"); g_bsp_priv.power_ctrl_by_pmu = true; g_bsp_priv.pmu_enable_level = value; } ret = of_property_read_string(np, "clock_in_out", &strings); if (ret) { pr_err("%s: Can not read property: clock_in_out.\n", __func__); g_bsp_priv.clock_input = true; } else { pr_info("%s: clock input or output? (%s).\n", __func__, strings); if (!strcmp(strings, "input")) { g_bsp_priv.clock_input = true; } else { g_bsp_priv.clock_input = false; } } ret = of_property_read_u32(np, "tx_delay", &value); if (ret) { g_bsp_priv.tx_delay = 0x30; pr_err("%s: Can not read property: tx_delay. set tx_delay to 0x%x\n", __func__, g_bsp_priv.tx_delay); } else { pr_info("%s: TX delay(0x%x).\n", __func__, value); g_bsp_priv.tx_delay = value; } ret = of_property_read_u32(np, "rx_delay", &value); if (ret) { g_bsp_priv.rx_delay = 0x10; pr_err("%s: Can not read property: rx_delay. set rx_delay to 0x%x\n", __func__, g_bsp_priv.rx_delay); } else { pr_info("%s: RX delay(0x%x).\n", __func__, value); g_bsp_priv.rx_delay = value; } g_bsp_priv.reset_io = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); g_bsp_priv.reset_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; g_bsp_priv.power_io = of_get_named_gpio_flags(np, "power-gpio", 0, &flags); g_bsp_priv.power_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0; g_bsp_priv.phy_iface = plat->interface; g_bsp_priv.phy_power_on = phy_power_on; g_bsp_priv.gmac_clk_enable = gmac_clk_enable; plat->bsp_priv = &g_bsp_priv; /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ if (of_device_is_compatible(np, "rockchip,rk3288-gmac") || of_device_is_compatible(np, "rockchip,rk312x-gmac")) { plat->has_gmac = 1; plat->pmt = 1; } if (of_device_is_compatible(np, "rockchip,rk3288-gmac")) { g_bsp_priv.chip = RK3288_GMAC; printk("%s: is rockchip,rk3288-gmac", __func__); } if (of_device_is_compatible(np, "rockchip,rk312x-gmac")) { g_bsp_priv.chip = RK312X_GMAC; printk("%s: is rockchip,rk312x-gmac", __func__); } return 0; }
/** * stmmac_probe_config_dt - parse device-tree driver parameters * @pdev: platform_device structure * @plat: driver data platform structure * @mac: MAC address to use * Description: * this function is to read the driver parameters from device-tree and * set some private fields that will be used by the main at runtime. */ struct plat_stmmacenet_data * stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) { struct device_node *np = pdev->dev.of_node; struct plat_stmmacenet_data *plat; struct stmmac_dma_cfg *dma_cfg; plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); if (!plat) return ERR_PTR(-ENOMEM); *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); /* Get max speed of operation from device tree */ if (of_property_read_u32(np, "max-speed", &plat->max_speed)) plat->max_speed = -1; plat->bus_id = of_alias_get_id(np, "ethernet"); if (plat->bus_id < 0) plat->bus_id = 0; /* Default to phy auto-detection */ plat->phy_addr = -1; /* If we find a phy-handle property, use it as the PHY */ plat->phy_node = of_parse_phandle(np, "phy-handle", 0); /* If phy-handle is not specified, check if we have a fixed-phy */ if (!plat->phy_node && of_phy_is_fixed_link(np)) { if ((of_phy_register_fixed_link(np) < 0)) return ERR_PTR(-ENODEV); plat->phy_node = of_node_get(np); } /* "snps,phy-addr" is not a standard property. Mark it as deprecated * and warn of its use. Remove this when phy node support is added. */ if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); if ((plat->phy_node && !of_phy_is_fixed_link(np)) || plat->phy_bus_name) plat->mdio_bus_data = NULL; else plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size); plat->force_sf_dma_mode = of_property_read_bool(np, "snps,force_sf_dma_mode"); /* Set the maxmtu to a default of JUMBO_LEN in case the * parameter is not present in the device tree. */ plat->maxmtu = JUMBO_LEN; /* Set default value for multicast hash bins */ plat->multicast_filter_bins = HASH_TABLE_SIZE; /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the * ePAPR v1.1 spec is defined as max-frame-size, it's * actually used as the IEEE definition of MAC Client * data, or MTU. The ePAPR specification is confusing as * the definition is max-frame-size, but usage examples * are clearly MTUs */ of_property_read_u32(np, "max-frame-size", &plat->maxmtu); of_property_read_u32(np, "snps,multicast-filter-bins", &plat->multicast_filter_bins); of_property_read_u32(np, "snps,perfect-filter-entries", &plat->unicast_filter_entries); plat->unicast_filter_entries = dwmac1000_validate_ucast_entries( plat->unicast_filter_entries); plat->multicast_filter_bins = dwmac1000_validate_mcast_bins( plat->multicast_filter_bins); plat->has_gmac = 1; plat->pmt = 1; } if (of_device_is_compatible(np, "snps,dwmac-3.610") || of_device_is_compatible(np, "snps,dwmac-3.710")) { plat->enh_desc = 1; plat->bugged_jumbo = 1; plat->force_sf_dma_mode = 1; } if (of_find_property(np, "snps,pbl", NULL)) { dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL); if (!dma_cfg) { of_node_put(np); return ERR_PTR(-ENOMEM); } plat->dma_cfg = dma_cfg; of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst"); dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst"); of_property_read_u32(np, "snps,burst_len", &dma_cfg->burst_len); if (dma_cfg->burst_len < 0 || dma_cfg->burst_len > 256) dma_cfg->burst_len = 0; } plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode"); if (plat->force_thresh_dma_mode) { plat->force_sf_dma_mode = 0; pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set."); } return plat; }
int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br) { struct dsa_notifier_bridge_info info = { .sw_index = dp->ds->index, .port = dp->index, .br = br, }; int err; /* Here the port is already bridged. Reflect the current configuration * so that drivers can program their chips accordingly. */ dp->bridge_dev = br; err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_JOIN, &info); /* The bridging is rolled back on error */ if (err) dp->bridge_dev = NULL; return err; } void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) { struct dsa_notifier_bridge_info info = { .sw_index = dp->ds->index, .port = dp->index, .br = br, }; int err; /* Here the port is already unbridged. Reflect the current configuration * so that drivers can program their chips accordingly. */ dp->bridge_dev = NULL; err = dsa_port_notify(dp, DSA_NOTIFIER_BRIDGE_LEAVE, &info); if (err) pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n"); /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, * so allow it to be in BR_STATE_FORWARDING to be kept functional */ dsa_port_set_state_now(dp, BR_STATE_FORWARDING); } int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering, struct switchdev_trans *trans) { struct dsa_switch *ds = dp->ds; /* bridge skips -EOPNOTSUPP, so skip the prepare phase */ if (switchdev_trans_ph_prepare(trans)) return 0; if (ds->ops->port_vlan_filtering) return ds->ops->port_vlan_filtering(ds, dp->index, vlan_filtering); return 0; } int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock, struct switchdev_trans *trans) { unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock); unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies); struct dsa_notifier_ageing_time_info info = { .ageing_time = ageing_time, .trans = trans, }; if (switchdev_trans_ph_prepare(trans)) return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info); dp->ageing_time = ageing_time; return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info); } int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr, u16 vid) { struct dsa_notifier_fdb_info info = { .sw_index = dp->ds->index, .port = dp->index, .addr = addr, .vid = vid, }; return dsa_port_notify(dp, DSA_NOTIFIER_FDB_ADD, &info); } int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr, u16 vid) { struct dsa_notifier_fdb_info info = { .sw_index = dp->ds->index, .port = dp->index, .addr = addr, .vid = vid, }; return dsa_port_notify(dp, DSA_NOTIFIER_FDB_DEL, &info); } int dsa_port_fdb_dump(struct dsa_port *dp, dsa_fdb_dump_cb_t *cb, void *data) { struct dsa_switch *ds = dp->ds; int port = dp->index; if (!ds->ops->port_fdb_dump) return -EOPNOTSUPP; return ds->ops->port_fdb_dump(ds, port, cb, data); } int dsa_port_mdb_add(const struct dsa_port *dp, const struct switchdev_obj_port_mdb *mdb, struct switchdev_trans *trans) { struct dsa_notifier_mdb_info info = { .sw_index = dp->ds->index, .port = dp->index, .trans = trans, .mdb = mdb, }; return dsa_port_notify(dp, DSA_NOTIFIER_MDB_ADD, &info); } int dsa_port_mdb_del(const struct dsa_port *dp, const struct switchdev_obj_port_mdb *mdb) { struct dsa_notifier_mdb_info info = { .sw_index = dp->ds->index, .port = dp->index, .mdb = mdb, }; return dsa_port_notify(dp, DSA_NOTIFIER_MDB_DEL, &info); } int dsa_port_vlan_add(struct dsa_port *dp, const struct switchdev_obj_port_vlan *vlan, struct switchdev_trans *trans) { struct dsa_notifier_vlan_info info = { .sw_index = dp->ds->index, .port = dp->index, .trans = trans, .vlan = vlan, }; if (netif_is_bridge_master(vlan->obj.orig_dev)) return -EOPNOTSUPP; if (br_vlan_enabled(dp->bridge_dev)) return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); return 0; } int dsa_port_vlan_del(struct dsa_port *dp, const struct switchdev_obj_port_vlan *vlan) { struct dsa_notifier_vlan_info info = { .sw_index = dp->ds->index, .port = dp->index, .vlan = vlan, }; if (netif_is_bridge_master(vlan->obj.orig_dev)) return -EOPNOTSUPP; if (br_vlan_enabled(dp->bridge_dev)) return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); return 0; } static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp) { struct device_node *phy_dn; struct phy_device *phydev; phy_dn = of_parse_phandle(dp->dn, "phy-handle", 0); if (!phy_dn) return NULL; phydev = of_phy_find_device(phy_dn); if (!phydev) { of_node_put(phy_dn); return ERR_PTR(-EPROBE_DEFER); } return phydev; } static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable) { struct dsa_switch *ds = dp->ds; struct phy_device *phydev; int port = dp->index; int err = 0; phydev = dsa_port_get_phy_device(dp); if (!phydev) return 0; if (IS_ERR(phydev)) return PTR_ERR(phydev); if (enable) { err = genphy_config_init(phydev); if (err < 0) goto err_put_dev; err = genphy_resume(phydev); if (err < 0) goto err_put_dev; err = genphy_read_status(phydev); if (err < 0) goto err_put_dev; } else { err = genphy_suspend(phydev); if (err < 0) goto err_put_dev; } if (ds->ops->adjust_link) ds->ops->adjust_link(ds, port, phydev); dev_dbg(ds->dev, "enabled port's phy: %s", phydev_name(phydev)); err_put_dev: put_device(&phydev->mdio.dev); return err; } static int dsa_port_fixed_link_register_of(struct dsa_port *dp) { struct device_node *dn = dp->dn; struct dsa_switch *ds = dp->ds; struct phy_device *phydev; int port = dp->index; int mode; int err; err = of_phy_register_fixed_link(dn); if (err) { dev_err(ds->dev, "failed to register the fixed PHY of port %d\n", port); return err; } phydev = of_phy_find_device(dn); mode = of_get_phy_mode(dn); if (mode < 0) mode = PHY_INTERFACE_MODE_NA; phydev->interface = mode; genphy_config_init(phydev); genphy_read_status(phydev); if (ds->ops->adjust_link) ds->ops->adjust_link(ds, port, phydev); put_device(&phydev->mdio.dev); return 0; } int dsa_port_link_register_of(struct dsa_port *dp) { if (of_phy_is_fixed_link(dp->dn)) return dsa_port_fixed_link_register_of(dp); else return dsa_port_setup_phy_of(dp, true); } void dsa_port_link_unregister_of(struct dsa_port *dp) { if (of_phy_is_fixed_link(dp->dn)) of_phy_deregister_fixed_link(dp->dn); else dsa_port_setup_phy_of(dp, false); } int dsa_port_get_phy_strings(struct dsa_port *dp, uint8_t *data) { struct phy_device *phydev; int ret = -EOPNOTSUPP; if (of_phy_is_fixed_link(dp->dn)) return ret; phydev = dsa_port_get_phy_device(dp); if (IS_ERR_OR_NULL(phydev)) return ret; ret = phy_ethtool_get_strings(phydev, data); put_device(&phydev->mdio.dev); return ret; } EXPORT_SYMBOL_GPL(dsa_port_get_phy_strings); int dsa_port_get_ethtool_phy_stats(struct dsa_port *dp, uint64_t *data) { struct phy_device *phydev; int ret = -EOPNOTSUPP; if (of_phy_is_fixed_link(dp->dn)) return ret; phydev = dsa_port_get_phy_device(dp); if (IS_ERR_OR_NULL(phydev)) return ret; ret = phy_ethtool_get_stats(phydev, NULL, data); put_device(&phydev->mdio.dev); return ret; } EXPORT_SYMBOL_GPL(dsa_port_get_ethtool_phy_stats); int dsa_port_get_phy_sset_count(struct dsa_port *dp) { struct phy_device *phydev; int ret = -EOPNOTSUPP; if (of_phy_is_fixed_link(dp->dn)) return ret; phydev = dsa_port_get_phy_device(dp); if (IS_ERR_OR_NULL(phydev)) return ret; ret = phy_ethtool_get_sset_count(phydev); put_device(&phydev->mdio.dev); return ret; } EXPORT_SYMBOL_GPL(dsa_port_get_phy_sset_count);
static int xgbe_probe(struct platform_device *pdev) { struct xgbe_prv_data *pdata; struct xgbe_hw_if *hw_if; struct xgbe_desc_if *desc_if; struct net_device *netdev; struct device *dev = &pdev->dev; struct resource *res; const u8 *mac_addr; int ret; DBGPR("--> xgbe_probe\n"); netdev = alloc_etherdev_mq(sizeof(struct xgbe_prv_data), XGBE_MAX_DMA_CHANNELS); if (!netdev) { dev_err(dev, "alloc_etherdev failed\n"); ret = -ENOMEM; goto err_alloc; } SET_NETDEV_DEV(netdev, dev); pdata = netdev_priv(netdev); pdata->netdev = netdev; pdata->pdev = pdev; pdata->dev = dev; platform_set_drvdata(pdev, netdev); spin_lock_init(&pdata->lock); mutex_init(&pdata->xpcs_mutex); spin_lock_init(&pdata->tstamp_lock); /* Set and validate the number of descriptors for a ring */ BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_TX_DESC_CNT); pdata->tx_desc_count = XGBE_TX_DESC_CNT; if (pdata->tx_desc_count & (pdata->tx_desc_count - 1)) { dev_err(dev, "tx descriptor count (%d) is not valid\n", pdata->tx_desc_count); ret = -EINVAL; goto err_io; } BUILD_BUG_ON_NOT_POWER_OF_2(XGBE_RX_DESC_CNT); pdata->rx_desc_count = XGBE_RX_DESC_CNT; if (pdata->rx_desc_count & (pdata->rx_desc_count - 1)) { dev_err(dev, "rx descriptor count (%d) is not valid\n", pdata->rx_desc_count); ret = -EINVAL; goto err_io; } /* Obtain the system clock setting */ pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK); if (IS_ERR(pdata->sysclk)) { dev_err(dev, "dma devm_clk_get failed\n"); ret = PTR_ERR(pdata->sysclk); goto err_io; } /* Obtain the PTP clock setting */ pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK); if (IS_ERR(pdata->ptpclk)) { dev_err(dev, "ptp devm_clk_get failed\n"); ret = PTR_ERR(pdata->ptpclk); goto err_io; } /* Obtain the mmio areas for the device */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pdata->xgmac_regs = devm_ioremap_resource(dev, res); if (IS_ERR(pdata->xgmac_regs)) { dev_err(dev, "xgmac ioremap failed\n"); ret = PTR_ERR(pdata->xgmac_regs); goto err_io; } DBGPR(" xgmac_regs = %p\n", pdata->xgmac_regs); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); pdata->xpcs_regs = devm_ioremap_resource(dev, res); if (IS_ERR(pdata->xpcs_regs)) { dev_err(dev, "xpcs ioremap failed\n"); ret = PTR_ERR(pdata->xpcs_regs); goto err_io; } DBGPR(" xpcs_regs = %p\n", pdata->xpcs_regs); /* Set the DMA mask */ if (!dev->dma_mask) dev->dma_mask = &dev->coherent_dma_mask; ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40)); if (ret) { dev_err(dev, "dma_set_mask_and_coherent failed\n"); goto err_io; } if (of_property_read_bool(dev->of_node, "dma-coherent")) { pdata->axdomain = XGBE_DMA_OS_AXDOMAIN; pdata->arcache = XGBE_DMA_OS_ARCACHE; pdata->awcache = XGBE_DMA_OS_AWCACHE; } else { pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN; pdata->arcache = XGBE_DMA_SYS_ARCACHE; pdata->awcache = XGBE_DMA_SYS_AWCACHE; } ret = platform_get_irq(pdev, 0); if (ret < 0) { dev_err(dev, "platform_get_irq failed\n"); goto err_io; } netdev->irq = ret; netdev->base_addr = (unsigned long)pdata->xgmac_regs; /* Set all the function pointers */ xgbe_init_all_fptrs(pdata); hw_if = &pdata->hw_if; desc_if = &pdata->desc_if; /* Issue software reset to device */ hw_if->exit(pdata); /* Populate the hardware features */ xgbe_get_all_hw_features(pdata); /* Retrieve the MAC address */ mac_addr = of_get_mac_address(dev->of_node); if (!mac_addr) { dev_err(dev, "invalid mac address for this device\n"); ret = -EINVAL; goto err_io; } memcpy(netdev->dev_addr, mac_addr, netdev->addr_len); /* Retrieve the PHY mode - it must be "xgmii" */ pdata->phy_mode = of_get_phy_mode(dev->of_node); if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII) { dev_err(dev, "invalid phy-mode specified for this device\n"); ret = -EINVAL; goto err_io; } /* Set default configuration data */ xgbe_default_config(pdata); /* Calculate the number of Tx and Rx rings to be created * -Tx (DMA) Channels map 1-to-1 to Tx Queues so set * the number of Tx queues to the number of Tx channels * enabled * -Rx (DMA) Channels do not map 1-to-1 so use the actual * number of Rx queues */ pdata->tx_ring_count = min_t(unsigned int, num_online_cpus(), pdata->hw_feat.tx_ch_cnt); pdata->tx_q_count = pdata->tx_ring_count; ret = netif_set_real_num_tx_queues(netdev, pdata->tx_ring_count); if (ret) { dev_err(dev, "error setting real tx queue count\n"); goto err_io; } pdata->rx_ring_count = min_t(unsigned int, netif_get_num_default_rss_queues(), pdata->hw_feat.rx_ch_cnt); pdata->rx_q_count = pdata->hw_feat.rx_q_cnt; ret = netif_set_real_num_rx_queues(netdev, pdata->rx_ring_count); if (ret) { dev_err(dev, "error setting real rx queue count\n"); goto err_io; } /* Allocate the rings for the DMA channels */ pdata->channel = xgbe_alloc_rings(pdata); if (!pdata->channel) { dev_err(dev, "ring allocation failed\n"); ret = -ENOMEM; goto err_io; } /* Prepare to regsiter with MDIO */ pdata->mii_bus_id = kasprintf(GFP_KERNEL, "%s", pdev->name); if (!pdata->mii_bus_id) { dev_err(dev, "failed to allocate mii bus id\n"); ret = -ENOMEM; goto err_io; } ret = xgbe_mdio_register(pdata); if (ret) goto err_bus_id; /* Set device operations */ netdev->netdev_ops = xgbe_get_netdev_ops(); netdev->ethtool_ops = xgbe_get_ethtool_ops(); #ifdef CONFIG_AMD_XGBE_DCB netdev->dcbnl_ops = xgbe_get_dcbnl_ops(); #endif /* Set device features */ netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_FILTER; netdev->vlan_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_TSO | NETIF_F_TSO6; netdev->features |= netdev->hw_features; pdata->netdev_features = netdev->features; netdev->priv_flags |= IFF_UNICAST_FLT; xgbe_init_rx_coalesce(pdata); xgbe_init_tx_coalesce(pdata); netif_carrier_off(netdev); ret = register_netdev(netdev); if (ret) { dev_err(dev, "net device registration failed\n"); goto err_reg_netdev; } xgbe_ptp_register(pdata); xgbe_debugfs_init(pdata); netdev_notice(netdev, "net device enabled\n"); DBGPR("<-- xgbe_probe\n"); return 0; err_reg_netdev: xgbe_mdio_unregister(pdata); err_bus_id: kfree(pdata->mii_bus_id); err_io: free_netdev(netdev); err_alloc: dev_notice(dev, "net device not enabled\n"); return ret; }
static int hip04_mac_probe(struct platform_device *pdev) { struct device *d = &pdev->dev; struct device_node *node = d->of_node; struct of_phandle_args arg; struct net_device *ndev; struct hip04_priv *priv; struct resource *res; int irq; int ret; ndev = alloc_etherdev(sizeof(struct hip04_priv)); if (!ndev) return -ENOMEM; priv = netdev_priv(ndev); priv->ndev = ndev; platform_set_drvdata(pdev, ndev); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->base = devm_ioremap_resource(d, res); if (IS_ERR(priv->base)) { ret = PTR_ERR(priv->base); goto init_fail; } ret = of_parse_phandle_with_fixed_args(node, "port-handle", 2, 0, &arg); if (ret < 0) { dev_warn(d, "no port-handle\n"); goto init_fail; } priv->port = arg.args[0]; priv->chan = arg.args[1] * RX_DESC_NUM; hrtimer_init(&priv->tx_coalesce_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); /* BQL will try to keep the TX queue as short as possible, but it can't * be faster than tx_coalesce_usecs, so we need a fast timeout here, * but also long enough to gather up enough frames to ensure we don't * get more interrupts than necessary. * 200us is enough for 16 frames of 1500 bytes at gigabit ethernet rate */ priv->tx_coalesce_frames = TX_DESC_NUM * 3 / 4; priv->tx_coalesce_usecs = 200; priv->tx_coalesce_timer.function = tx_done; priv->map = syscon_node_to_regmap(arg.np); if (IS_ERR(priv->map)) { dev_warn(d, "no syscon hisilicon,hip04-ppe\n"); ret = PTR_ERR(priv->map); goto init_fail; } priv->phy_mode = of_get_phy_mode(node); if (priv->phy_mode < 0) { dev_warn(d, "not find phy-mode\n"); ret = -EINVAL; goto init_fail; } irq = platform_get_irq(pdev, 0); if (irq <= 0) { ret = -EINVAL; goto init_fail; } ret = devm_request_irq(d, irq, hip04_mac_interrupt, 0, pdev->name, ndev); if (ret) { netdev_err(ndev, "devm_request_irq failed\n"); goto init_fail; } priv->phy_node = of_parse_phandle(node, "phy-handle", 0); if (priv->phy_node) { priv->phy = of_phy_connect(ndev, priv->phy_node, &hip04_adjust_link, 0, priv->phy_mode); if (!priv->phy) { ret = -EPROBE_DEFER; goto init_fail; } } INIT_WORK(&priv->tx_timeout_task, hip04_tx_timeout_task); ether_setup(ndev); ndev->netdev_ops = &hip04_netdev_ops; ndev->ethtool_ops = &hip04_ethtool_ops; ndev->watchdog_timeo = TX_TIMEOUT; ndev->priv_flags |= IFF_UNICAST_FLT; ndev->irq = irq; netif_napi_add(ndev, &priv->napi, hip04_rx_poll, NAPI_POLL_WEIGHT); SET_NETDEV_DEV(ndev, &pdev->dev); hip04_reset_ppe(priv); if (priv->phy_mode == PHY_INTERFACE_MODE_MII) hip04_config_port(ndev, SPEED_100, DUPLEX_FULL); hip04_config_fifo(priv); random_ether_addr(ndev->dev_addr); hip04_update_mac_address(ndev); ret = hip04_alloc_ring(ndev, d); if (ret) { netdev_err(ndev, "alloc ring fail\n"); goto alloc_fail; } ret = register_netdev(ndev); if (ret) { free_netdev(ndev); goto alloc_fail; } return 0; alloc_fail: hip04_free_ring(ndev, d); init_fail: of_node_put(priv->phy_node); free_netdev(ndev); return ret; }
static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, const struct rk_gmac_ops *ops) { struct rk_priv_data *bsp_priv; struct device *dev = &pdev->dev; int ret; const char *strings = NULL; int value; bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); if (!bsp_priv) return ERR_PTR(-ENOMEM); bsp_priv->phy_iface = of_get_phy_mode(dev->of_node); bsp_priv->ops = ops; bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); if (IS_ERR(bsp_priv->regulator)) { if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { dev_err(dev, "phy regulator is not available yet, deferred probing\n"); return ERR_PTR(-EPROBE_DEFER); } dev_err(dev, "no regulator found\n"); bsp_priv->regulator = NULL; } ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); if (ret) { dev_err(dev, "Can not read property: clock_in_out.\n"); bsp_priv->clock_input = true; } else { dev_info(dev, "clock input or output? (%s).\n", strings); if (!strcmp(strings, "input")) bsp_priv->clock_input = true; else bsp_priv->clock_input = false; } ret = of_property_read_u32(dev->of_node, "tx_delay", &value); if (ret) { bsp_priv->tx_delay = 0x30; dev_err(dev, "Can not read property: tx_delay."); dev_err(dev, "set tx_delay to 0x%x\n", bsp_priv->tx_delay); } else { dev_info(dev, "TX delay(0x%x).\n", value); bsp_priv->tx_delay = value; } ret = of_property_read_u32(dev->of_node, "rx_delay", &value); if (ret) { bsp_priv->rx_delay = 0x10; dev_err(dev, "Can not read property: rx_delay."); dev_err(dev, "set rx_delay to 0x%x\n", bsp_priv->rx_delay); } else { dev_info(dev, "RX delay(0x%x).\n", value); bsp_priv->rx_delay = value; } bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); bsp_priv->pdev = pdev; gmac_clk_init(bsp_priv); return bsp_priv; }
static int stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; struct stmmac_dma_cfg *dma_cfg; const struct of_device_id *device; if (!np) return -ENODEV; device = of_match_device(stmmac_dt_ids, &pdev->dev); if (!device) return -ENODEV; if (device->data) { const struct stmmac_of_data *data = device->data; plat->has_gmac = data->has_gmac; plat->enh_desc = data->enh_desc; plat->tx_coe = data->tx_coe; plat->rx_coe = data->rx_coe; plat->bugged_jumbo = data->bugged_jumbo; plat->pmt = data->pmt; plat->riwt_off = data->riwt_off; plat->fix_mac_speed = data->fix_mac_speed; plat->bus_setup = data->bus_setup; plat->setup = data->setup; plat->free = data->free; plat->init = data->init; plat->exit = data->exit; } *mac = of_get_mac_address(np); plat->interface = of_get_phy_mode(np); /* Get max speed of operation from device tree */ if (of_property_read_u32(np, "max-speed", &plat->max_speed)) plat->max_speed = -1; plat->bus_id = of_alias_get_id(np, "ethernet"); if (plat->bus_id < 0) plat->bus_id = 0; /* Default to phy auto-detection */ plat->phy_addr = -1; /* "snps,phy-addr" is not a standard property. Mark it as deprecated * and warn of its use. Remove this when phy node support is added. */ if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); plat->force_sf_dma_mode = of_property_read_bool(np, "snps,force_sf_dma_mode"); /* Set the maxmtu to a default of JUMBO_LEN in case the * parameter is not present in the device tree. */ plat->maxmtu = JUMBO_LEN; /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ if (of_device_is_compatible(np, "st,spear600-gmac") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np, "snps,dwmac")) { /* Note that the max-frame-size parameter as defined in the * ePAPR v1.1 spec is defined as max-frame-size, it's * actually used as the IEEE definition of MAC Client * data, or MTU. The ePAPR specification is confusing as * the definition is max-frame-size, but usage examples * are clearly MTUs */ of_property_read_u32(np, "max-frame-size", &plat->maxmtu); plat->has_gmac = 1; plat->pmt = 1; } if (of_device_is_compatible(np, "snps,dwmac-3.610") || of_device_is_compatible(np, "snps,dwmac-3.710")) { plat->enh_desc = 1; plat->bugged_jumbo = 1; plat->force_sf_dma_mode = 1; } if (of_find_property(np, "snps,pbl", NULL)) { dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL); if (!dma_cfg) return -ENOMEM; plat->dma_cfg = dma_cfg; of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst"); dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst"); } plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode"); if (plat->force_thresh_dma_mode) { plat->force_sf_dma_mode = 0; pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set."); } return 0; }
static int stmmac_probe_config_dt(struct platform_device *pdev, struct plat_stmmacenet_data *plat, const char **mac) { struct device_node *np = pdev->dev.of_node; struct stmmac_dma_cfg *dma_cfg; const struct of_device_id *device; #if defined (CONFIG_AML_NAND_KEY) || defined (CONFIG_SECURITYKEY) int ret; char *addr =NULL; #endif if (!np) return -ENODEV; device = of_match_device(stmmac_dt_ids, &pdev->dev); if (!device) return -ENODEV; if (device->data) { const struct stmmac_of_data *data = device->data; plat->has_gmac = data->has_gmac; plat->enh_desc = data->enh_desc; plat->tx_coe = data->tx_coe; plat->rx_coe = data->rx_coe; plat->bugged_jumbo = data->bugged_jumbo; plat->pmt = data->pmt; plat->riwt_off = data->riwt_off; plat->fix_mac_speed = data->fix_mac_speed; plat->bus_setup = data->bus_setup; plat->setup = data->setup; plat->free = data->free; plat->init = data->init; plat->exit = data->exit; } #if defined (CONFIG_AML_NAND_KEY) || defined (CONFIG_SECURITYKEY) ret = get_aml_key_kernel("mac", print_buff, 0); extenal_api_key_set_version("auto"); printk("ret = %d\nprint_buff=%s\n", ret, print_buff); if (ret >= 0) { strcpy(addr, print_buff); *mac = addr; } else { if(g_mac_addr_setup){ *mac = DEFMAC; } else{ *mac = of_get_mac_address(np); } } #else *mac = of_get_mac_address(np); #endif plat->interface = of_get_phy_mode(np); /* Get max speed of operation from device tree */ if (of_property_read_u32(np, "max-speed", &plat->max_speed)) plat->max_speed = -1; plat->bus_id = of_alias_get_id(np, "ethernet"); if (plat->bus_id < 0) plat->bus_id = 0; /* Default to phy auto-detection */ plat->phy_addr = -1; /* "snps,phy-addr" is not a standard property. Mark it as deprecated * and warn of its use. Remove this when phy node support is added. */ if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0) dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n"); if (plat->phy_bus_name){ plat->mdio_bus_data = NULL; } else plat->mdio_bus_data = devm_kzalloc(&pdev->dev, sizeof(struct stmmac_mdio_bus_data), GFP_KERNEL); plat->force_sf_dma_mode = of_property_read_bool(np, "snps,force_sf_dma_mode"); /* Set the maxmtu to a default of JUMBO_LEN in case the * parameter is not present in the device tree. */ /* Set default value for multicast hash bins */ plat->multicast_filter_bins = HASH_TABLE_SIZE; /* Set default value for unicast filter entries */ plat->unicast_filter_entries = 1; /* * Currently only the properties needed on SPEAr600 * are provided. All other properties should be added * once needed on other platforms. */ #ifdef CONFIG_DWMAC_MESON #if 0 if(of_device_is_compatible(np,"amlogic,meson8m2-dwmac")){ aml_write_reg32(P_PERIPHS_PIN_MUX_6,0xffff); aml_write_reg32(P_PREG_ETH_REG0,0x7d21); aml_set_reg32_mask(P_HHI_MPLL_CNTL6,1<<27); aml_set_reg32_mask(P_HHI_GEN_CLK_CNTL,0xb803); aml_set_reg32_mask(P_HHI_MPLL_CNTL9,(1638<<0)| (0<<14)|(1<<15) | (1<<14) | (5<<16) | (0<<25) | (0<<26) |(0<<30) | (0<<31)); /* setup ethernet mode */ aml_clr_reg32_mask(P_HHI_MEM_PD_REG0, (1 << 3) | (1<<2)); /* hardware reset ethernet phy : gpioz14 connect phyreset pin*/ aml_clr_reg32_mask(P_PREG_PAD_GPIO2_EN_N, 1 << 28); aml_clr_reg32_mask(P_PREG_PAD_GPIO2_O, 1 << 28); mdelay(10); aml_set_reg32_mask(P_PREG_PAD_GPIO2_O, 1 << 28); } #endif #endif if (of_device_is_compatible(np, "st,spear600-gmac") || of_device_is_compatible(np, "snps,dwmac-3.70a") || of_device_is_compatible(np,"amlogic,meson8b-rgmii-dwmac")|| of_device_is_compatible(np,"amlogic,meson8m2-rgmii-dwmac")) { /* Note that the max-frame-size parameter as defined in the * ePAPR v1.1 spec is defined as max-frame-size, it's * actually used as the IEEE definition of MAC Client * data, or MTU. The ePAPR specification is confusing as * the definition is max-frame-size, but usage examples * are clearly MTUs */ of_property_read_u32(np, "max-frame-size", &plat->maxmtu); of_property_read_u32(np, "snps,multicast-filter-bins", &plat->multicast_filter_bins); of_property_read_u32(np, "snps,perfect-filter-entries", &plat->unicast_filter_entries); plat->unicast_filter_entries = dwmac1000_validate_ucast_entries( plat->unicast_filter_entries); plat->multicast_filter_bins = dwmac1000_validate_mcast_bins( plat->multicast_filter_bins); plat->has_gmac = 1; plat->pmt = 1; } if (of_device_is_compatible(np, "snps,dwmac-3.610") || of_device_is_compatible(np,"amlogic,meson6-dwmac")|| of_device_is_compatible(np, "snps,dwmac-3.710")) { plat->enh_desc = 1; plat->bugged_jumbo = 1; plat->force_sf_dma_mode = 1; } if (of_find_property(np, "snps,pbl", NULL)) { dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), GFP_KERNEL); if (!dma_cfg) return -ENOMEM; plat->dma_cfg = dma_cfg; of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl); dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst"); dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst"); } plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode"); if (plat->force_thresh_dma_mode) { plat->force_sf_dma_mode = 0; pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set."); } return 0; }
/* Detect MAC & PHY and perform ethernet interface initialization */ static int __init at91ether_probe(struct platform_device *pdev) { struct macb_platform_data *board_data = dev_get_platdata(&pdev->dev); struct resource *regs; struct net_device *dev; struct phy_device *phydev; struct macb *lp; int res; u32 reg; const char *mac; regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!regs) return -ENOENT; dev = alloc_etherdev(sizeof(struct macb)); if (!dev) return -ENOMEM; lp = netdev_priv(dev); lp->pdev = pdev; lp->dev = dev; spin_lock_init(&lp->lock); /* physical base address */ dev->base_addr = regs->start; lp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); if (!lp->regs) { res = -ENOMEM; goto err_free_dev; } /* Clock */ lp->pclk = devm_clk_get(&pdev->dev, "ether_clk"); if (IS_ERR(lp->pclk)) { res = PTR_ERR(lp->pclk); goto err_free_dev; } clk_enable(lp->pclk); lp->hclk = ERR_PTR(-ENOENT); lp->tx_clk = ERR_PTR(-ENOENT); /* Install the interrupt handler */ dev->irq = platform_get_irq(pdev, 0); res = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt, 0, dev->name, dev); if (res) goto err_disable_clock; ether_setup(dev); dev->netdev_ops = &at91ether_netdev_ops; dev->ethtool_ops = &macb_ethtool_ops; platform_set_drvdata(pdev, dev); SET_NETDEV_DEV(dev, &pdev->dev); mac = of_get_mac_address(pdev->dev.of_node); if (mac) memcpy(lp->dev->dev_addr, mac, ETH_ALEN); else macb_get_hwaddr(lp); res = of_get_phy_mode(pdev->dev.of_node); if (res < 0) { if (board_data && board_data->is_rmii) lp->phy_interface = PHY_INTERFACE_MODE_RMII; else lp->phy_interface = PHY_INTERFACE_MODE_MII; } else { lp->phy_interface = res; } macb_writel(lp, NCR, 0); reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); if (lp->phy_interface == PHY_INTERFACE_MODE_RMII) reg |= MACB_BIT(RM9200_RMII); macb_writel(lp, NCFGR, reg); /* Register the network interface */ res = register_netdev(dev); if (res) goto err_disable_clock; res = macb_mii_init(lp); if (res) goto err_out_unregister_netdev; /* will be enabled in open() */ netif_carrier_off(dev); phydev = lp->phy_dev; netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", phydev->drv->name, dev_name(&phydev->dev), phydev->irq); /* Display ethernet banner */ netdev_info(dev, "AT91 ethernet at 0x%08lx int=%d (%pM)\n", dev->base_addr, dev->irq, dev->dev_addr); return 0; err_out_unregister_netdev: unregister_netdev(dev); err_disable_clock: clk_disable(lp->pclk); err_free_dev: free_netdev(dev); return res; }
static int sun7i_gmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; struct stmmac_resources stmmac_res; struct sunxi_priv_data *gmac; struct device *dev = &pdev->dev; int ret; ret = stmmac_get_platform_resources(pdev, &stmmac_res); if (ret) return ret; plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); if (IS_ERR(plat_dat)) return PTR_ERR(plat_dat); gmac = devm_kzalloc(dev, sizeof(*gmac), GFP_KERNEL); if (!gmac) { ret = -ENOMEM; goto err_remove_config_dt; } gmac->interface = of_get_phy_mode(dev->of_node); gmac->tx_clk = devm_clk_get(dev, "allwinner_gmac_tx"); if (IS_ERR(gmac->tx_clk)) { dev_err(dev, "could not get tx clock\n"); ret = PTR_ERR(gmac->tx_clk); goto err_remove_config_dt; } /* Optional regulator for PHY */ gmac->regulator = devm_regulator_get_optional(dev, "phy"); if (IS_ERR(gmac->regulator)) { if (PTR_ERR(gmac->regulator) == -EPROBE_DEFER) { ret = -EPROBE_DEFER; goto err_remove_config_dt; } dev_info(dev, "no regulator found\n"); gmac->regulator = NULL; } /* platform data specifying hardware features and callbacks. * hardware features were copied from Allwinner drivers. */ plat_dat->tx_coe = 1; plat_dat->has_gmac = true; plat_dat->bsp_priv = gmac; plat_dat->init = sun7i_gmac_init; plat_dat->exit = sun7i_gmac_exit; plat_dat->fix_mac_speed = sun7i_fix_speed; ret = sun7i_gmac_init(pdev, plat_dat->bsp_priv); if (ret) goto err_remove_config_dt; ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) goto err_gmac_exit; return 0; err_gmac_exit: sun7i_gmac_exit(pdev, plat_dat->bsp_priv); err_remove_config_dt: stmmac_remove_config_dt(pdev, plat_dat); return ret; }
static void *rk_gmac_setup(struct platform_device *pdev) { struct rk_priv_data *bsp_priv; struct device *dev = &pdev->dev; int ret; const char *strings = NULL; int value; bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL); if (!bsp_priv) return ERR_PTR(-ENOMEM); bsp_priv->phy_iface = of_get_phy_mode(dev->of_node); bsp_priv->regulator = devm_regulator_get_optional(dev, "phy"); if (IS_ERR(bsp_priv->regulator)) { if (PTR_ERR(bsp_priv->regulator) == -EPROBE_DEFER) { dev_err(dev, "phy regulator is not available yet, deferred probing\n"); return ERR_PTR(-EPROBE_DEFER); } dev_err(dev, "no regulator found\n"); bsp_priv->regulator = NULL; } ret = of_property_read_string(dev->of_node, "clock_in_out", &strings); if (ret) { dev_err(dev, "%s: Can not read property: clock_in_out.\n", __func__); bsp_priv->clock_input = true; } else { dev_info(dev, "%s: clock input or output? (%s).\n", __func__, strings); if (!strcmp(strings, "input")) bsp_priv->clock_input = true; else bsp_priv->clock_input = false; } ret = of_property_read_u32(dev->of_node, "tx_delay", &value); if (ret) { bsp_priv->tx_delay = 0x30; dev_err(dev, "%s: Can not read property: tx_delay.", __func__); dev_err(dev, "%s: set tx_delay to 0x%x\n", __func__, bsp_priv->tx_delay); } else { dev_info(dev, "%s: TX delay(0x%x).\n", __func__, value); bsp_priv->tx_delay = value; } ret = of_property_read_u32(dev->of_node, "rx_delay", &value); if (ret) { bsp_priv->rx_delay = 0x10; dev_err(dev, "%s: Can not read property: rx_delay.", __func__); dev_err(dev, "%s: set rx_delay to 0x%x\n", __func__, bsp_priv->rx_delay); } else { dev_info(dev, "%s: RX delay(0x%x).\n", __func__, value); bsp_priv->rx_delay = value; } bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); bsp_priv->pdev = pdev; /*rmii or rgmii*/ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RGMII) { dev_info(dev, "%s: init for RGMII\n", __func__); set_to_rgmii(bsp_priv, bsp_priv->tx_delay, bsp_priv->rx_delay); } else if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) { dev_info(dev, "%s: init for RMII\n", __func__); set_to_rmii(bsp_priv); } else { dev_err(dev, "%s: NO interface defined!\n", __func__); } gmac_clk_init(bsp_priv); return bsp_priv; }
static int emac_rockchip_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct net_device *ndev; struct rockchip_priv_data *priv; const struct of_device_id *match; u32 data; int err, interface; if (!pdev->dev.of_node) return -ENODEV; ndev = alloc_etherdev(sizeof(struct rockchip_priv_data)); if (!ndev) return -ENOMEM; platform_set_drvdata(pdev, ndev); SET_NETDEV_DEV(ndev, dev); priv = netdev_priv(ndev); priv->emac.drv_name = DRV_NAME; priv->emac.drv_version = DRV_VERSION; priv->emac.set_mac_speed = emac_rockchip_set_mac_speed; interface = of_get_phy_mode(dev->of_node); /* RK3036/RK3066/RK3188 SoCs only support RMII */ if (interface != PHY_INTERFACE_MODE_RMII) { dev_err(dev, "unsupported phy interface mode %d\n", interface); err = -ENOTSUPP; goto out_netdev; } priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf"); if (IS_ERR(priv->grf)) { dev_err(dev, "failed to retrieve global register file (%ld)\n", PTR_ERR(priv->grf)); err = PTR_ERR(priv->grf); goto out_netdev; } match = of_match_node(emac_rockchip_dt_ids, dev->of_node); priv->soc_data = match->data; priv->emac.clk = devm_clk_get(dev, "hclk"); if (IS_ERR(priv->emac.clk)) { dev_err(dev, "failed to retrieve host clock (%ld)\n", PTR_ERR(priv->emac.clk)); err = PTR_ERR(priv->emac.clk); goto out_netdev; } priv->refclk = devm_clk_get(dev, "macref"); if (IS_ERR(priv->refclk)) { dev_err(dev, "failed to retrieve reference clock (%ld)\n", PTR_ERR(priv->refclk)); err = PTR_ERR(priv->refclk); goto out_netdev; } err = clk_prepare_enable(priv->refclk); if (err) { dev_err(dev, "failed to enable reference clock (%d)\n", err); goto out_netdev; } /* Optional regulator for PHY */ priv->regulator = devm_regulator_get_optional(dev, "phy"); if (IS_ERR(priv->regulator)) { if (PTR_ERR(priv->regulator) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_err(dev, "no regulator found\n"); priv->regulator = NULL; } if (priv->regulator) { err = regulator_enable(priv->regulator); if (err) { dev_err(dev, "failed to enable phy-supply (%d)\n", err); goto out_clk_disable; } } /* Set speed 100M */ data = (1 << (priv->soc_data->grf_speed_offset + 16)) | (1 << priv->soc_data->grf_speed_offset); /* Set RMII mode */ data |= (1 << (priv->soc_data->grf_mode_offset + 16)) | (0 << priv->soc_data->grf_mode_offset); err = regmap_write(priv->grf, priv->soc_data->grf_offset, data); if (err) { dev_err(dev, "unable to apply initial settings to grf (%d)\n", err); goto out_regulator_disable; } /* RMII interface needs always a rate of 50MHz */ err = clk_set_rate(priv->refclk, 50000000); if (err) dev_err(dev, "failed to change reference clock rate (%d)\n", err); if (priv->soc_data->need_div_macclk) { priv->macclk = devm_clk_get(dev, "macclk"); if (IS_ERR(priv->macclk)) { dev_err(dev, "failed to retrieve mac clock (%ld)\n", PTR_ERR(priv->macclk)); err = PTR_ERR(priv->macclk); goto out_regulator_disable; } err = clk_prepare_enable(priv->macclk); if (err) { dev_err(dev, "failed to enable mac clock (%d)\n", err); goto out_regulator_disable; } /* RMII TX/RX needs always a rate of 25MHz */ err = clk_set_rate(priv->macclk, 25000000); if (err) dev_err(dev, "failed to change mac clock rate (%d)\n", err); } err = arc_emac_probe(ndev, interface); if (err) { dev_err(dev, "failed to probe arc emac (%d)\n", err); goto out_regulator_disable; } return 0; out_regulator_disable: if (priv->regulator) regulator_disable(priv->regulator); out_clk_disable: clk_disable_unprepare(priv->refclk); out_netdev: free_netdev(ndev); return err; }
static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *dev) { struct device_node *np = dev->of_node; struct regmap *sys_mgr_base_addr; u32 reg_offset, reg_shift; int ret, index; struct device_node *np_splitter = NULL; struct device_node *np_sgmii_adapter = NULL; struct resource res_splitter; struct resource res_tse_pcs; struct resource res_sgmii_adapter; dwmac->interface = of_get_phy_mode(np); sys_mgr_base_addr = syscon_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon"); if (IS_ERR(sys_mgr_base_addr)) { dev_info(dev, "No sysmgr-syscon node found\n"); return PTR_ERR(sys_mgr_base_addr); } ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 1, ®_offset); if (ret) { dev_info(dev, "Could not read reg_offset from sysmgr-syscon!\n"); return -EINVAL; } ret = of_property_read_u32_index(np, "altr,sysmgr-syscon", 2, ®_shift); if (ret) { dev_info(dev, "Could not read reg_shift from sysmgr-syscon!\n"); return -EINVAL; } dwmac->f2h_ptp_ref_clk = of_property_read_bool(np, "altr,f2h_ptp_ref_clk"); np_splitter = of_parse_phandle(np, "altr,emac-splitter", 0); if (np_splitter) { ret = of_address_to_resource(np_splitter, 0, &res_splitter); of_node_put(np_splitter); if (ret) { dev_info(dev, "Missing emac splitter address\n"); return -EINVAL; } dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter); if (IS_ERR(dwmac->splitter_base)) { dev_info(dev, "Failed to mapping emac splitter\n"); return PTR_ERR(dwmac->splitter_base); } } np_sgmii_adapter = of_parse_phandle(np, "altr,gmii-to-sgmii-converter", 0); if (np_sgmii_adapter) { index = of_property_match_string(np_sgmii_adapter, "reg-names", "hps_emac_interface_splitter_avalon_slave"); if (index >= 0) { if (of_address_to_resource(np_sgmii_adapter, index, &res_splitter)) { dev_err(dev, "%s: ERROR: missing emac splitter address\n", __func__); ret = -EINVAL; goto err_node_put; } dwmac->splitter_base = devm_ioremap_resource(dev, &res_splitter); if (IS_ERR(dwmac->splitter_base)) { ret = PTR_ERR(dwmac->splitter_base); goto err_node_put; } } index = of_property_match_string(np_sgmii_adapter, "reg-names", "gmii_to_sgmii_adapter_avalon_slave"); if (index >= 0) { if (of_address_to_resource(np_sgmii_adapter, index, &res_sgmii_adapter)) { dev_err(dev, "%s: ERROR: failed mapping adapter\n", __func__); ret = -EINVAL; goto err_node_put; } dwmac->pcs.sgmii_adapter_base = devm_ioremap_resource(dev, &res_sgmii_adapter); if (IS_ERR(dwmac->pcs.sgmii_adapter_base)) { ret = PTR_ERR(dwmac->pcs.sgmii_adapter_base); goto err_node_put; } } index = of_property_match_string(np_sgmii_adapter, "reg-names", "eth_tse_control_port"); if (index >= 0) { if (of_address_to_resource(np_sgmii_adapter, index, &res_tse_pcs)) { dev_err(dev, "%s: ERROR: failed mapping tse control port\n", __func__); ret = -EINVAL; goto err_node_put; } dwmac->pcs.tse_pcs_base = devm_ioremap_resource(dev, &res_tse_pcs); if (IS_ERR(dwmac->pcs.tse_pcs_base)) { ret = PTR_ERR(dwmac->pcs.tse_pcs_base); goto err_node_put; } } } dwmac->reg_offset = reg_offset; dwmac->reg_shift = reg_shift; dwmac->sys_mgr_base_addr = sys_mgr_base_addr; dwmac->dev = dev; of_node_put(np_sgmii_adapter); return 0; err_node_put: of_node_put(np_sgmii_adapter); return ret; }
static int dsa_slave_phy_setup(struct dsa_slave_priv *p, struct net_device *slave_dev) { struct dsa_switch *ds = p->parent; struct dsa_chip_data *cd = ds->pd; struct device_node *phy_dn, *port_dn; bool phy_is_fixed = false; u32 phy_flags = 0; int mode, ret; port_dn = cd->port_dn[p->port]; mode = of_get_phy_mode(port_dn); if (mode < 0) mode = PHY_INTERFACE_MODE_NA; p->phy_interface = mode; phy_dn = of_parse_phandle(port_dn, "phy-handle", 0); if (of_phy_is_fixed_link(port_dn)) { /* In the case of a fixed PHY, the DT node associated * to the fixed PHY is the Port DT node */ ret = of_phy_register_fixed_link(port_dn); if (ret) { netdev_err(slave_dev, "failed to register fixed PHY: %d\n", ret); return ret; } phy_is_fixed = true; phy_dn = port_dn; } if (ds->drv->get_phy_flags) phy_flags = ds->drv->get_phy_flags(ds, p->port); if (phy_dn) { int phy_id = of_mdio_parse_addr(&slave_dev->dev, phy_dn); /* If this PHY address is part of phys_mii_mask, which means * that we need to divert reads and writes to/from it, then we * want to bind this device using the slave MII bus created by * DSA to make that happen. */ if (!phy_is_fixed && phy_id >= 0 && (ds->phys_mii_mask & (1 << phy_id))) { ret = dsa_slave_phy_connect(p, slave_dev, phy_id); if (ret) { netdev_err(slave_dev, "failed to connect to phy%d: %d\n", phy_id, ret); return ret; } } else { p->phy = of_phy_connect(slave_dev, phy_dn, dsa_slave_adjust_link, phy_flags, p->phy_interface); } } if (p->phy && phy_is_fixed) fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update); /* We could not connect to a designated PHY, so use the switch internal * MDIO bus instead */ if (!p->phy) { ret = dsa_slave_phy_connect(p, slave_dev, p->port); if (ret) { netdev_err(slave_dev, "failed to connect to port %d: %d\n", p->port, ret); return ret; } } phy_attached_info(p->phy); return 0; }
static int meson8b_dwmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; struct stmmac_resources stmmac_res; struct resource *res; struct meson8b_dwmac *dwmac; int ret; ret = stmmac_get_platform_resources(pdev, &stmmac_res); if (ret) return ret; plat_dat = stmmac_probe_config_dt(pdev, &stmmac_res.mac); if (IS_ERR(plat_dat)) return PTR_ERR(plat_dat); dwmac = devm_kzalloc(&pdev->dev, sizeof(*dwmac), GFP_KERNEL); if (!dwmac) { ret = -ENOMEM; goto err_remove_config_dt; } res = platform_get_resource(pdev, IORESOURCE_MEM, 1); dwmac->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dwmac->regs)) { ret = PTR_ERR(dwmac->regs); goto err_remove_config_dt; } dwmac->pdev = pdev; dwmac->phy_mode = of_get_phy_mode(pdev->dev.of_node); if (dwmac->phy_mode < 0) { dev_err(&pdev->dev, "missing phy-mode property\n"); ret = -EINVAL; goto err_remove_config_dt; } /* use 2ns as fallback since this value was previously hardcoded */ if (of_property_read_u32(pdev->dev.of_node, "amlogic,tx-delay-ns", &dwmac->tx_delay_ns)) dwmac->tx_delay_ns = 2; ret = meson8b_init_rgmii_tx_clk(dwmac); if (ret) goto err_remove_config_dt; ret = meson8b_init_prg_eth(dwmac); if (ret) goto err_remove_config_dt; plat_dat->bsp_priv = dwmac; ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); if (ret) goto err_clk_disable; return 0; err_clk_disable: if (phy_interface_mode_is_rgmii(dwmac->phy_mode)) clk_disable_unprepare(dwmac->rgmii_tx_en_clk); err_remove_config_dt: stmmac_remove_config_dt(pdev, plat_dat); return ret; }