void mt76_eeprom_override(struct mt76_dev *dev) { #ifdef CONFIG_OF struct device_node *np = dev->dev->of_node; const __be32 *val; const u8 *mac; int size; if (!np) return; val = of_get_property(np, "mediatek,2ghz", &size); if (val) dev->cap.has_2ghz = be32_to_cpup(val); val = of_get_property(np, "mediatek,5ghz", &size); if (val) dev->cap.has_5ghz = be32_to_cpup(val); mac = of_get_mac_address(np); if (mac) memcpy(dev->macaddr, mac, ETH_ALEN); #endif if (!is_valid_ether_addr(dev->macaddr)) { eth_random_addr(dev->macaddr); dev_printk(KERN_INFO, dev->dev, "Invalid MAC address, using random address %pM\n", dev->macaddr); } }
static int ath9k_of_init(struct ath_softc *sc) { struct device_node *np = sc->dev->of_node; struct ath_hw *ah = sc->sc_ah; struct ath_common *common = ath9k_hw_common(ah); enum ath_bus_type bus_type = common->bus_ops->ath_bus_type; const char *mac; char eeprom_name[100]; int ret; if (!of_device_is_available(np)) return 0; ath_dbg(common, CONFIG, "parsing configuration from OF node\n"); if (of_property_read_bool(np, "qca,no-eeprom")) { /* ath9k-eeprom-<bus>-<id>.bin */ scnprintf(eeprom_name, sizeof(eeprom_name), "ath9k-eeprom-%s-%s.bin", ath_bus_type_to_string(bus_type), dev_name(ah->dev)); ret = ath9k_eeprom_request(sc, eeprom_name); if (ret) return ret; ah->ah_flags &= ~AH_USE_EEPROM; ah->ah_flags |= AH_NO_EEP_SWAP; } mac = of_get_mac_address(np); if (!IS_ERR(mac)) ether_addr_copy(common->macaddr, mac); return 0; }
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 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 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 void fec_get_mac(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); struct fec_platform_data *pdata = fep->pdev->dev.platform_data; unsigned char *iap, tmpaddr[ETH_ALEN]; /* * try to get mac address in following order: * * 1) module parameter via kernel command line in form * fec.macaddr=0x00,0x04,0x9f,0x01,0x30,0xe0 */ iap = macaddr; #ifdef CONFIG_OF /* * 2) from device tree data */ if (!is_valid_ether_addr(iap)) { struct device_node *np = fep->pdev->dev.of_node; if (np) { const char *mac = of_get_mac_address(np); if (mac) iap = (unsigned char *) mac; } } #endif /* * 3) from flash or fuse (via platform data) */ if (!is_valid_ether_addr(iap)) { #ifdef CONFIG_M5272 if (FEC_FLASHMAC) iap = (unsigned char *)FEC_FLASHMAC; #else if (pdata) iap = (unsigned char *)&pdata->mac; #endif } /* * 4) FEC mac registers set by bootloader */ if (!is_valid_ether_addr(iap)) { *((unsigned long *) &tmpaddr[0]) = be32_to_cpu(readl(fep->hwp + FEC_ADDR_LOW)); *((unsigned short *) &tmpaddr[4]) = be16_to_cpu(readl(fep->hwp + FEC_ADDR_HIGH) >> 16); iap = &tmpaddr[0]; }
static int at91ether_get_hwaddr_dt(struct macb *bp) { struct device_node *np = bp->pdev->dev.of_node; if (np) { const char *mac = of_get_mac_address(np); if (mac) { memcpy(bp->dev->dev_addr, mac, ETH_ALEN); return 0; } } return -ENODEV; }
/** * cvm_oct_common_init - per network device initialization * @dev: Device to initialize * * Returns Zero on success */ int cvm_oct_common_init(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); const u8 *mac = NULL; if (priv->of_node) mac = of_get_mac_address(priv->of_node); if (mac && is_valid_ether_addr(mac)) { memcpy(dev->dev_addr, mac, ETH_ALEN); dev->addr_assign_type &= ~NET_ADDR_RANDOM; } else { eth_hw_addr_random(dev); } /* * Force the interface to use the POW send if always_use_pow * was specified or it is in the pow send list. */ if ((pow_send_group != -1) && (always_use_pow || strstr(pow_send_list, dev->name))) priv->queue = -1; if (priv->queue != -1) { dev->features |= NETIF_F_SG; if (USE_HW_TCPUDP_CHECKSUM) dev->features |= NETIF_F_IP_CSUM; } /* We do our own locking, Linux doesn't need to */ dev->features |= NETIF_F_LLTX; SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); cvm_oct_phy_setup_device(dev); cvm_oct_set_mac_filter(dev); dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); /* * Zero out stats for port so we won't mistakenly show * counters from the bootloader. */ memset(dev->netdev_ops->ndo_get_stats(dev), 0, sizeof(struct net_device_stats)); 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; 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; }
/** * cvm_oct_common_init - per network device initialization * @dev: Device to initialize * * Returns Zero on success */ int cvm_oct_common_init(struct net_device *dev) { struct octeon_ethernet *priv = netdev_priv(dev); const u8 *mac = NULL; if (priv->of_node) mac = of_get_mac_address(priv->of_node); if (mac) ether_addr_copy(dev->dev_addr, mac); else eth_hw_addr_random(dev); /* * Force the interface to use the POW send if always_use_pow * was specified or it is in the pow send list. */ if ((pow_send_group != -1) && (always_use_pow || strstr(pow_send_list, dev->name))) priv->queue = -1; if (priv->queue != -1) dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; /* We do our own locking, Linux doesn't need to */ dev->features |= NETIF_F_LLTX; dev->ethtool_ops = &cvm_oct_ethtool_ops; cvm_oct_set_mac_filter(dev); dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); /* * Zero out stats for port so we won't mistakenly show * counters from the bootloader. */ memset(dev->netdev_ops->ndo_get_stats(dev), 0, sizeof(struct net_device_stats)); if (dev->netdev_ops->ndo_stop) dev->netdev_ops->ndo_stop(dev); return 0; }
int eth_platform_get_mac_address(struct device *dev, u8 *mac_addr) { const unsigned char *addr; struct device_node *dp; if (dev_is_pci(dev)) dp = pci_device_to_OF_node(to_pci_dev(dev)); else dp = dev->of_node; addr = NULL; if (dp) addr = of_get_mac_address(dp); if (!addr) addr = arch_get_platform_mac_address(); if (!addr) return -ENODEV; ether_addr_copy(mac_addr, addr); 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 (!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; }
static int __init gfar_of_init(void) { struct device_node *np; unsigned int i; struct platform_device *gfar_dev; struct resource res; int ret; for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "gianfar")) != NULL; i++) { struct resource r[4]; struct device_node *phy, *mdio; struct gianfar_platform_data gfar_data; const unsigned int *id; const char *model; const void *mac_addr; const phandle *ph; int n_res = 2; memset(r, 0, sizeof(r)); memset(&gfar_data, 0, sizeof(gfar_data)); ret = of_address_to_resource(np, 0, &r[0]); if (ret) goto err; of_irq_to_resource(np, 0, &r[1]); model = of_get_property(np, "model", NULL); /* If we aren't the FEC we have multiple interrupts */ if (model && strcasecmp(model, "FEC")) { r[1].name = gfar_tx_intr; r[2].name = gfar_rx_intr; of_irq_to_resource(np, 1, &r[2]); r[3].name = gfar_err_intr; of_irq_to_resource(np, 2, &r[3]); n_res += 2; } gfar_dev = platform_device_register_simple("fsl-gianfar", i, &r[0], n_res); if (IS_ERR(gfar_dev)) { ret = PTR_ERR(gfar_dev); goto err; } mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(gfar_data.mac_addr, mac_addr, 6); if (model && !strcasecmp(model, "TSEC")) gfar_data.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | FSL_GIANFAR_DEV_HAS_MULTI_INTR; if (model && !strcasecmp(model, "eTSEC")) gfar_data.device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | FSL_GIANFAR_DEV_HAS_COALESCE | FSL_GIANFAR_DEV_HAS_RMON | FSL_GIANFAR_DEV_HAS_MULTI_INTR | FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; ph = of_get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); if (phy == NULL) { ret = -ENODEV; goto unreg; } mdio = of_get_parent(phy); id = of_get_property(phy, "reg", NULL); ret = of_address_to_resource(mdio, 0, &res); if (ret) { of_node_put(phy); of_node_put(mdio); goto unreg; } gfar_data.phy_id = *id; gfar_data.bus_id = res.start; of_node_put(phy); of_node_put(mdio); ret = platform_device_add_data(gfar_dev, &gfar_data, sizeof(struct gianfar_platform_data)); if (ret) goto unreg; } return 0; unreg: platform_device_unregister(gfar_dev); err: return ret; }
/* Search EMAC board, allocate space and register it */ static int emac_probe(struct vmm_device *pdev, const struct vmm_devtree_nodeid *devid) { struct device_node *np = pdev->node; struct emac_board_info *db; struct net_device *ndev; int ret = 0; const char *mac_addr; virtual_addr_t reg_addr; ndev = alloc_etherdev(sizeof(struct emac_board_info)); if (!ndev) { dev_err(pdev, "%s: could not allocate device.\n", __func__); return -ENOMEM; } strlcpy(ndev->name, pdev->name, sizeof(ndev->name)); SET_NETDEV_DEV(ndev, pdev); db = netdev_priv(ndev); memset(db, 0, sizeof(*db)); db->ndev = ndev; db->pdev = pdev; spin_lock_init(&db->lock); if ((ret = vmm_devtree_request_regmap(np, ®_addr, 0, "Sun4i EMAC"))) { vmm_printf("%s: Failed to ioreamp\n", __func__); return -ENOMEM; } db->membase = (void *) reg_addr; /* fill in parameters for net-dev structure */ ndev->base_addr = (unsigned long)db->membase; ret = vmm_devtree_irq_get(np, &ndev->irq, 0); if (ret) { vmm_printf("%s: No irq resource\n", __func__); goto out; } db->clk = clk_get(pdev, NULL); if (IS_ERR(db->clk)) goto out; clk_prepare_enable(db->clk); db->phy_node = vmm_devtree_parse_phandle(np, "phy", 0); if (!db->phy_node) { dev_err(pdev, "%s: no associated PHY\n", __func__); ret = -ENODEV; goto out; } /* Read MAC-address from DT */ mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); /* Check if the MAC address is valid, if not get a random one */ if (!is_valid_ether_addr(ndev->dev_addr)) { eth_hw_addr_random(ndev); dev_info(pdev, "using random MAC address: "); print_mac_address_fmt(ndev->dev_addr); } db->emacrx_completed_flag = 1; emac_powerup(ndev); emac_reset(db); ether_setup(ndev); ndev->netdev_ops = &emac_netdev_ops; ndev->watchdog_timeo = msecs_to_jiffies(watchdog); ndev->ethtool_ops = &emac_ethtool_ops; platform_set_drvdata(pdev, ndev); /* Carrier starts down, phylib will bring it up */ netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) { dev_err(pdev, "%s: Registering netdev failed!\n", __func__); ret = -ENODEV; goto out; } dev_info(pdev, "%s: at %p, IRQ %d MAC: ", ndev->name, db->membase, ndev->irq); print_mac_address_fmt(ndev->dev_addr); return 0; out: dev_err(pdev, "%s: not found (%d).\n", __func__, ret); free_netdev(ndev); return ret; }
/* Search EMAC board, allocate space and register it */ static int emac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct emac_board_info *db; struct net_device *ndev; int ret = 0; const char *mac_addr; ndev = alloc_etherdev(sizeof(struct emac_board_info)); if (!ndev) { dev_err(&pdev->dev, "could not allocate device.\n"); return -ENOMEM; } SET_NETDEV_DEV(ndev, &pdev->dev); db = netdev_priv(ndev); memset(db, 0, sizeof(*db)); db->dev = &pdev->dev; db->ndev = ndev; db->pdev = pdev; db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE); spin_lock_init(&db->lock); db->membase = of_iomap(np, 0); if (!db->membase) { dev_err(&pdev->dev, "failed to remap registers\n"); ret = -ENOMEM; goto out; } /* fill in parameters for net-dev structure */ ndev->base_addr = (unsigned long)db->membase; ndev->irq = irq_of_parse_and_map(np, 0); if (ndev->irq == -ENXIO) { netdev_err(ndev, "No irq resource\n"); ret = ndev->irq; goto out_iounmap; } db->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(db->clk)) { ret = PTR_ERR(db->clk); goto out_iounmap; } ret = clk_prepare_enable(db->clk); if (ret) { dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); goto out_iounmap; } ret = sunxi_sram_claim(&pdev->dev); if (ret) { dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); goto out_clk_disable_unprepare; } db->phy_node = of_parse_phandle(np, "phy", 0); if (!db->phy_node) { dev_err(&pdev->dev, "no associated PHY\n"); ret = -ENODEV; goto out_release_sram; } /* Read MAC-address from DT */ mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); /* Check if the MAC address is valid, if not get a random one */ if (!is_valid_ether_addr(ndev->dev_addr)) { eth_hw_addr_random(ndev); dev_warn(&pdev->dev, "using random MAC address %pM\n", ndev->dev_addr); } db->emacrx_completed_flag = 1; emac_powerup(ndev); emac_reset(db); ndev->netdev_ops = &emac_netdev_ops; ndev->watchdog_timeo = msecs_to_jiffies(watchdog); ndev->ethtool_ops = &emac_ethtool_ops; platform_set_drvdata(pdev, ndev); /* Carrier starts down, phylib will bring it up */ netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) { dev_err(&pdev->dev, "Registering netdev failed!\n"); ret = -ENODEV; goto out_release_sram; } dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n", ndev->name, db->membase, ndev->irq, ndev->dev_addr); return 0; out_release_sram: sunxi_sram_release(&pdev->dev); out_clk_disable_unprepare: clk_disable_unprepare(db->clk); out_iounmap: iounmap(db->membase); out: dev_err(db->dev, "not found (%d).\n", ret); free_netdev(ndev); return ret; }
static int __devinit fs_enet_probe(struct of_device *ofdev, const struct of_device_id *match) { struct net_device *ndev; struct fs_enet_private *fep; struct fs_platform_info *fpi; const u32 *data; const u8 *mac_addr; int privsize, len, ret = -ENODEV; fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; if (!IS_FEC(match)) { data = of_get_property(ofdev->node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; fpi->cp_command = *data; } fpi->rx_ring = 32; fpi->tx_ring = 32; fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; ret = find_phy(ofdev->node, fpi); if (ret) goto out_free_fpi; privsize = sizeof(*fep) + sizeof(struct sk_buff **) * (fpi->rx_ring + fpi->tx_ring); ndev = alloc_etherdev(privsize); if (!ndev) { ret = -ENOMEM; goto out_free_fpi; } dev_set_drvdata(&ofdev->dev, ndev); fep = netdev_priv(ndev); fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; fep->ops = match->data; ret = fep->ops->setup_data(ndev); if (ret) goto out_free_dev; fep->rx_skbuff = (struct sk_buff **)&fep[1]; fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; spin_lock_init(&fep->lock); spin_lock_init(&fep->tx_lock); mac_addr = of_get_mac_address(ofdev->node); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, 6); ret = fep->ops->allocate_bd(ndev); if (ret) goto out_cleanup_data; fep->rx_bd_base = fep->ring_base; fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; fep->tx_ring = fpi->tx_ring; fep->rx_ring = fpi->rx_ring; ndev->open = fs_enet_open; ndev->hard_start_xmit = fs_enet_start_xmit; ndev->tx_timeout = fs_timeout; ndev->watchdog_timeo = 2 * HZ; ndev->stop = fs_enet_close; ndev->get_stats = fs_enet_get_stats; ndev->set_multicast_list = fs_set_multicast_list; if (fpi->use_napi) netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight); ndev->ethtool_ops = &fs_ethtool_ops; ndev->do_ioctl = fs_ioctl; init_timer(&fep->phy_timer_list); netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) goto out_free_bd; printk(KERN_INFO "%s: fs_enet: %02x:%02x:%02x:%02x:%02x:%02x\n", ndev->name, ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2], ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]); return 0; out_free_bd: fep->ops->free_bd(ndev); out_cleanup_data: fep->ops->cleanup_data(ndev); out_free_dev: free_netdev(ndev); dev_set_drvdata(&ofdev->dev, NULL); out_free_fpi: kfree(fpi); return ret; }
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; }
static int fs_enet_probe(struct platform_device *ofdev) { const struct of_device_id *match; struct net_device *ndev; struct fs_enet_private *fep; struct fs_platform_info *fpi; const u32 *data; struct clk *clk; int err; const u8 *mac_addr; const char *phy_connection_type; int privsize, len, ret = -ENODEV; match = of_match_device(fs_enet_match, &ofdev->dev); if (!match) return -EINVAL; fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; if (!IS_FEC(match)) { data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; fpi->cp_command = *data; } fpi->rx_ring = 32; fpi->tx_ring = 32; fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link", NULL))) goto out_free_fpi; if (of_device_is_compatible(ofdev->dev.of_node, "fsl,mpc5125-fec")) { phy_connection_type = of_get_property(ofdev->dev.of_node, "phy-connection-type", NULL); if (phy_connection_type && !strcmp("rmii", phy_connection_type)) fpi->use_rmii = 1; } /* make clock lookup non-fatal (the driver is shared among platforms), * but require enable to succeed when a clock was specified/found, * keep a reference to the clock upon successful acquisition */ clk = devm_clk_get(&ofdev->dev, "per"); if (!IS_ERR(clk)) { err = clk_prepare_enable(clk); if (err) { ret = err; goto out_free_fpi; } fpi->clk_per = clk; } privsize = sizeof(*fep) + sizeof(struct sk_buff **) * (fpi->rx_ring + fpi->tx_ring); ndev = alloc_etherdev(privsize); if (!ndev) { ret = -ENOMEM; goto out_put; } SET_NETDEV_DEV(ndev, &ofdev->dev); platform_set_drvdata(ofdev, ndev); fep = netdev_priv(ndev); fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; fep->ops = match->data; ret = fep->ops->setup_data(ndev); if (ret) goto out_free_dev; fep->rx_skbuff = (struct sk_buff **)&fep[1]; fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; spin_lock_init(&fep->lock); spin_lock_init(&fep->tx_lock); mac_addr = of_get_mac_address(ofdev->dev.of_node); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, ETH_ALEN); ret = fep->ops->allocate_bd(ndev); if (ret) goto out_cleanup_data; fep->rx_bd_base = fep->ring_base; fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; fep->tx_ring = fpi->tx_ring; fep->rx_ring = fpi->rx_ring; ndev->netdev_ops = &fs_enet_netdev_ops; ndev->watchdog_timeo = 2 * HZ; if (fpi->use_napi) netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight); ndev->ethtool_ops = &fs_ethtool_ops; init_timer(&fep->phy_timer_list); netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) goto out_free_bd; pr_info("%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr); return 0; out_free_bd: fep->ops->free_bd(ndev); out_cleanup_data: fep->ops->cleanup_data(ndev); out_free_dev: free_netdev(ndev); out_put: of_node_put(fpi->phy_node); if (fpi->clk_per) clk_disable_unprepare(fpi->clk_per); out_free_fpi: kfree(fpi); return ret; }
static int qca_spi_probe(struct spi_device *spi_device) { struct qcaspi *qca = NULL; struct net_device *qcaspi_devs = NULL; u8 legacy_mode = 0; u16 signature; const char *mac; if (!spi_device->dev.of_node) { dev_err(&spi_device->dev, "Missing device tree\n"); return -EINVAL; } legacy_mode = of_property_read_bool(spi_device->dev.of_node, "qca,legacy-mode"); if (qcaspi_clkspeed == 0) { if (spi_device->max_speed_hz) qcaspi_clkspeed = spi_device->max_speed_hz; else qcaspi_clkspeed = QCASPI_CLK_SPEED; } if ((qcaspi_clkspeed < QCASPI_CLK_SPEED_MIN) || (qcaspi_clkspeed > QCASPI_CLK_SPEED_MAX)) { dev_info(&spi_device->dev, "Invalid clkspeed: %d\n", qcaspi_clkspeed); return -EINVAL; } if ((qcaspi_burst_len < QCASPI_BURST_LEN_MIN) || (qcaspi_burst_len > QCASPI_BURST_LEN_MAX)) { dev_info(&spi_device->dev, "Invalid burst len: %d\n", qcaspi_burst_len); return -EINVAL; } if ((qcaspi_pluggable < QCASPI_PLUGGABLE_MIN) || (qcaspi_pluggable > QCASPI_PLUGGABLE_MAX)) { dev_info(&spi_device->dev, "Invalid pluggable: %d\n", qcaspi_pluggable); return -EINVAL; } dev_info(&spi_device->dev, "ver=%s, clkspeed=%d, burst_len=%d, pluggable=%d\n", QCASPI_DRV_VERSION, qcaspi_clkspeed, qcaspi_burst_len, qcaspi_pluggable); spi_device->mode = SPI_MODE_3; spi_device->max_speed_hz = qcaspi_clkspeed; if (spi_setup(spi_device) < 0) { dev_err(&spi_device->dev, "Unable to setup SPI device\n"); return -EFAULT; } qcaspi_devs = alloc_etherdev(sizeof(struct qcaspi)); if (!qcaspi_devs) return -ENOMEM; qcaspi_netdev_setup(qcaspi_devs); qca = netdev_priv(qcaspi_devs); if (!qca) { free_netdev(qcaspi_devs); dev_err(&spi_device->dev, "Fail to retrieve private structure\n"); return -ENOMEM; } qca->net_dev = qcaspi_devs; qca->spi_dev = spi_device; qca->legacy_mode = legacy_mode; mac = of_get_mac_address(spi_device->dev.of_node); if (mac) ether_addr_copy(qca->net_dev->dev_addr, mac); if (!is_valid_ether_addr(qca->net_dev->dev_addr)) { eth_hw_addr_random(qca->net_dev); dev_info(&spi_device->dev, "Using random MAC address: %pM\n", qca->net_dev->dev_addr); } netif_carrier_off(qca->net_dev); if (!qcaspi_pluggable) { qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); qcaspi_read_register(qca, SPI_REG_SIGNATURE, &signature); if (signature != QCASPI_GOOD_SIGNATURE) { dev_err(&spi_device->dev, "Invalid signature (0x%04X)\n", signature); free_netdev(qcaspi_devs); return -EFAULT; } } if (register_netdev(qcaspi_devs)) { dev_info(&spi_device->dev, "Unable to register net device %s\n", qcaspi_devs->name); free_netdev(qcaspi_devs); return -EFAULT; } spi_set_drvdata(spi_device, qcaspi_devs); qcaspi_init_device_debugfs(qca); return 0; }
static int bgmac_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct bgmac *bgmac; struct resource *regs; const u8 *mac_addr; bgmac = devm_kzalloc(&pdev->dev, sizeof(*bgmac), GFP_KERNEL); if (!bgmac) return -ENOMEM; platform_set_drvdata(pdev, bgmac); /* Set the features of the 4707 family */ bgmac->feature_flags |= BGMAC_FEAT_CLKCTLST; bgmac->feature_flags |= BGMAC_FEAT_NO_RESET; bgmac->feature_flags |= BGMAC_FEAT_CMDCFG_SR_REV4; bgmac->feature_flags |= BGMAC_FEAT_TX_MASK_SETUP; bgmac->feature_flags |= BGMAC_FEAT_RX_MASK_SETUP; bgmac->dev = &pdev->dev; bgmac->dma_dev = &pdev->dev; mac_addr = of_get_mac_address(np); if (mac_addr) ether_addr_copy(bgmac->mac_addr, mac_addr); else dev_warn(&pdev->dev, "MAC address not present in device tree\n"); bgmac->irq = platform_get_irq(pdev, 0); if (bgmac->irq < 0) { dev_err(&pdev->dev, "Unable to obtain IRQ\n"); return bgmac->irq; } regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "amac_base"); if (!regs) { dev_err(&pdev->dev, "Unable to obtain base resource\n"); return -EINVAL; } bgmac->plat.base = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(bgmac->plat.base)) return PTR_ERR(bgmac->plat.base); regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base"); if (!regs) { dev_err(&pdev->dev, "Unable to obtain idm resource\n"); return -EINVAL; } bgmac->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(bgmac->plat.idm_base)) return PTR_ERR(bgmac->plat.idm_base); regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nicpm_base"); if (regs) { bgmac->plat.nicpm_base = devm_ioremap_resource(&pdev->dev, regs); if (IS_ERR(bgmac->plat.nicpm_base)) return PTR_ERR(bgmac->plat.nicpm_base); } bgmac->read = platform_bgmac_read; bgmac->write = platform_bgmac_write; bgmac->idm_read = platform_bgmac_idm_read; bgmac->idm_write = platform_bgmac_idm_write; bgmac->clk_enabled = platform_bgmac_clk_enabled; bgmac->clk_enable = platform_bgmac_clk_enable; bgmac->cco_ctl_maskset = platform_bgmac_cco_ctl_maskset; bgmac->get_bus_clock = platform_bgmac_get_bus_clock; bgmac->cmn_maskset32 = platform_bgmac_cmn_maskset32; if (of_parse_phandle(np, "phy-handle", 0)) { bgmac->phy_connect = platform_phy_connect; } else { bgmac->phy_connect = bgmac_phy_connect_direct; bgmac->feature_flags |= BGMAC_FEAT_FORCE_SPEED_2500; } return bgmac_enet_probe(bgmac); }
static s32 nps_enet_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct net_device *ndev; struct nps_enet_priv *priv; s32 err = 0; const char *mac_addr; struct resource *res_regs; if (!dev->of_node) return -ENODEV; ndev = alloc_etherdev(sizeof(struct nps_enet_priv)); if (!ndev) return -ENOMEM; platform_set_drvdata(pdev, ndev); SET_NETDEV_DEV(ndev, dev); priv = netdev_priv(ndev); /* The EZ NET specific entries in the device structure. */ ndev->netdev_ops = &nps_netdev_ops; ndev->watchdog_timeo = (400 * HZ / 1000); /* FIXME :: no multicast support yet */ ndev->flags &= ~IFF_MULTICAST; res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); priv->regs_base = devm_ioremap_resource(dev, res_regs); if (IS_ERR(priv->regs_base)) { err = PTR_ERR(priv->regs_base); goto out_netdev; } dev_dbg(dev, "Registers base address is 0x%p\n", priv->regs_base); /* set kernel MAC address to dev */ mac_addr = of_get_mac_address(dev->of_node); if (mac_addr) ether_addr_copy(ndev->dev_addr, mac_addr); else eth_hw_addr_random(ndev); /* Get IRQ number */ priv->irq = platform_get_irq(pdev, 0); if (!priv->irq) { dev_err(dev, "failed to retrieve <irq Rx-Tx> value from device tree\n"); err = -ENODEV; goto out_netdev; } netif_napi_add(ndev, &priv->napi, nps_enet_poll, NPS_ENET_NAPI_POLL_WEIGHT); /* Register the driver. Should be the last thing in probe */ err = register_netdev(ndev); if (err) { dev_err(dev, "Failed to register ndev for %s, err = 0x%08x\n", ndev->name, (s32)err); goto out_netif_api; } dev_info(dev, "(rx/tx=%d)\n", priv->irq); return 0; out_netif_api: netif_napi_del(&priv->napi); out_netdev: if (err) free_netdev(ndev); return err; }
static int octeon_mgmt_probe(struct platform_device *pdev) { struct net_device *netdev; struct octeon_mgmt *p; const __be32 *data; const u8 *mac; struct resource *res_mix; struct resource *res_agl; struct resource *res_agl_prt_ctl; int len; int result; netdev = alloc_etherdev(sizeof(struct octeon_mgmt)); if (netdev == NULL) return -ENOMEM; SET_NETDEV_DEV(netdev, &pdev->dev); platform_set_drvdata(pdev, netdev); p = netdev_priv(netdev); netif_napi_add(netdev, &p->napi, octeon_mgmt_napi_poll, OCTEON_MGMT_NAPI_WEIGHT); p->netdev = netdev; p->dev = &pdev->dev; p->has_rx_tstamp = false; data = of_get_property(pdev->dev.of_node, "cell-index", &len); if (data && len == sizeof(*data)) { p->port = be32_to_cpup(data); } else { dev_err(&pdev->dev, "no 'cell-index' property\n"); result = -ENXIO; goto err; } snprintf(netdev->name, IFNAMSIZ, "mgmt%d", p->port); result = platform_get_irq(pdev, 0); if (result < 0) goto err; p->irq = result; res_mix = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res_mix == NULL) { dev_err(&pdev->dev, "no 'reg' resource\n"); result = -ENXIO; goto err; } res_agl = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (res_agl == NULL) { dev_err(&pdev->dev, "no 'reg' resource\n"); result = -ENXIO; goto err; } res_agl_prt_ctl = platform_get_resource(pdev, IORESOURCE_MEM, 3); if (res_agl_prt_ctl == NULL) { dev_err(&pdev->dev, "no 'reg' resource\n"); result = -ENXIO; goto err; } p->mix_phys = res_mix->start; p->mix_size = resource_size(res_mix); p->agl_phys = res_agl->start; p->agl_size = resource_size(res_agl); p->agl_prt_ctl_phys = res_agl_prt_ctl->start; p->agl_prt_ctl_size = resource_size(res_agl_prt_ctl); if (!devm_request_mem_region(&pdev->dev, p->mix_phys, p->mix_size, res_mix->name)) { dev_err(&pdev->dev, "request_mem_region (%s) failed\n", res_mix->name); result = -ENXIO; goto err; } if (!devm_request_mem_region(&pdev->dev, p->agl_phys, p->agl_size, res_agl->name)) { result = -ENXIO; dev_err(&pdev->dev, "request_mem_region (%s) failed\n", res_agl->name); goto err; } if (!devm_request_mem_region(&pdev->dev, p->agl_prt_ctl_phys, p->agl_prt_ctl_size, res_agl_prt_ctl->name)) { result = -ENXIO; dev_err(&pdev->dev, "request_mem_region (%s) failed\n", res_agl_prt_ctl->name); goto err; } p->mix = (u64)devm_ioremap(&pdev->dev, p->mix_phys, p->mix_size); p->agl = (u64)devm_ioremap(&pdev->dev, p->agl_phys, p->agl_size); p->agl_prt_ctl = (u64)devm_ioremap(&pdev->dev, p->agl_prt_ctl_phys, p->agl_prt_ctl_size); spin_lock_init(&p->lock); skb_queue_head_init(&p->tx_list); skb_queue_head_init(&p->rx_list); tasklet_init(&p->tx_clean_tasklet, octeon_mgmt_clean_tx_tasklet, (unsigned long)p); netdev->priv_flags |= IFF_UNICAST_FLT; netdev->netdev_ops = &octeon_mgmt_ops; netdev->ethtool_ops = &octeon_mgmt_ethtool_ops; mac = of_get_mac_address(pdev->dev.of_node); if (mac) memcpy(netdev->dev_addr, mac, ETH_ALEN); else eth_hw_addr_random(netdev); p->phy_np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); result = dma_coerce_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); if (result) goto err; netif_carrier_off(netdev); result = register_netdev(netdev); if (result) goto err; dev_info(&pdev->dev, "Version " DRV_VERSION "\n"); return 0; err: free_netdev(netdev); return result; }
static int __init fs_enet_of_init(void) { struct device_node *np; unsigned int i; struct platform_device *fs_enet_dev = NULL; struct resource res; int ret; for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; i++) { struct resource r[4]; struct device_node *phy = NULL, *mdio = NULL; struct fs_platform_info fs_enet_data; const unsigned int *id; const unsigned int *phy_addr; const void *mac_addr; const phandle *ph; const char *model; memset(r, 0, sizeof(r)); memset(&fs_enet_data, 0, sizeof(fs_enet_data)); model = of_get_property(np, "model", NULL); if (model == NULL) { ret = -ENODEV; goto unreg; } id = of_get_property(np, "device-id", NULL); fs_enet_data.fs_no = *id; if (platform_device_skip(model, *id)) continue; ret = of_address_to_resource(np, 0, &r[0]); if (ret) goto err; r[0].name = enet_regs; mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(fs_enet_data.macaddr, mac_addr, 6); ph = of_get_property(np, "phy-handle", NULL); if (ph != NULL) phy = of_find_node_by_phandle(*ph); if (phy != NULL) { phy_addr = of_get_property(phy, "reg", NULL); fs_enet_data.phy_addr = *phy_addr; fs_enet_data.has_phy = 1; mdio = of_get_parent(phy); ret = of_address_to_resource(mdio, 0, &res); if (ret) { of_node_put(phy); of_node_put(mdio); goto unreg; } } model = of_get_property(np, "model", NULL); strcpy(fs_enet_data.fs_type, model); if (strstr(model, "FEC")) { r[1].start = r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; r[1].name = enet_irq; fs_enet_dev = platform_device_register_simple("fsl-cpm-fec", i, &r[0], 2); if (IS_ERR(fs_enet_dev)) { ret = PTR_ERR(fs_enet_dev); goto err; } fs_enet_data.rx_ring = 128; fs_enet_data.tx_ring = 16; fs_enet_data.rx_copybreak = 240; fs_enet_data.use_napi = 1; fs_enet_data.napi_weight = 17; snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%x:%02x", (u32)res.start, fs_enet_data.phy_addr); fs_enet_data.bus_id = (char*)&bus_id[i]; fs_enet_data.init_ioports = init_fec_ioports; } if (strstr(model, "SCC")) { ret = of_address_to_resource(np, 1, &r[1]); if (ret) goto err; r[1].name = enet_pram; r[2].start = r[2].end = irq_of_parse_and_map(np, 0); r[2].flags = IORESOURCE_IRQ; r[2].name = enet_irq; fs_enet_dev = platform_device_register_simple("fsl-cpm-scc", i, &r[0], 3); if (IS_ERR(fs_enet_dev)) { ret = PTR_ERR(fs_enet_dev); goto err; } fs_enet_data.rx_ring = 64; fs_enet_data.tx_ring = 8; fs_enet_data.rx_copybreak = 240; fs_enet_data.use_napi = 1; fs_enet_data.napi_weight = 17; snprintf((char*)&bus_id[i], BUS_ID_SIZE, "%s", "fixed@10:1"); fs_enet_data.bus_id = (char*)&bus_id[i]; fs_enet_data.init_ioports = init_scc_ioports; } of_node_put(phy); of_node_put(mdio); ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, sizeof(struct fs_platform_info)); if (ret) goto unreg; } return 0; unreg: platform_device_unregister(fs_enet_dev); err: return ret; }
static int __devinit fs_enet_probe(struct platform_device *ofdev, const struct of_device_id *match) { struct net_device *ndev; struct fs_enet_private *fep; struct fs_platform_info *fpi; const u32 *data; const u8 *mac_addr; int privsize, len, ret = -ENODEV; fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); if (!fpi) return -ENOMEM; if (!IS_FEC(match)) { data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); if (!data || len != 4) goto out_free_fpi; fpi->cp_command = *data; } fpi->rx_ring = 32; fpi->tx_ring = 32; fpi->rx_copybreak = 240; fpi->use_napi = 1; fpi->napi_weight = 17; fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0); if ((!fpi->phy_node) && (!of_get_property(ofdev->dev.of_node, "fixed-link", NULL))) goto out_free_fpi; privsize = sizeof(*fep) + sizeof(struct sk_buff **) * (fpi->rx_ring + fpi->tx_ring); ndev = alloc_etherdev(privsize); if (!ndev) { ret = -ENOMEM; goto out_put; } SET_NETDEV_DEV(ndev, &ofdev->dev); dev_set_drvdata(&ofdev->dev, ndev); fep = netdev_priv(ndev); fep->dev = &ofdev->dev; fep->ndev = ndev; fep->fpi = fpi; fep->ops = match->data; ret = fep->ops->setup_data(ndev); if (ret) goto out_free_dev; fep->rx_skbuff = (struct sk_buff **)&fep[1]; fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring; spin_lock_init(&fep->lock); spin_lock_init(&fep->tx_lock); mac_addr = of_get_mac_address(ofdev->dev.of_node); if (mac_addr) memcpy(ndev->dev_addr, mac_addr, 6); ret = fep->ops->allocate_bd(ndev); if (ret) goto out_cleanup_data; fep->rx_bd_base = fep->ring_base; fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring; fep->tx_ring = fpi->tx_ring; fep->rx_ring = fpi->rx_ring; ndev->netdev_ops = &fs_enet_netdev_ops; ndev->watchdog_timeo = 2 * HZ; if (fpi->use_napi) netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight); ndev->ethtool_ops = &fs_ethtool_ops; init_timer(&fep->phy_timer_list); netif_carrier_off(ndev); ret = register_netdev(ndev); if (ret) goto out_free_bd; pr_info("%s: fs_enet: %pM\n", ndev->name, ndev->dev_addr); return 0; out_free_bd: fep->ops->free_bd(ndev); out_cleanup_data: fep->ops->cleanup_data(ndev); out_free_dev: free_netdev(ndev); dev_set_drvdata(&ofdev->dev, NULL); out_put: of_node_put(fpi->phy_node); out_free_fpi: kfree(fpi); return ret; }
static int __init fs_enet_of_init(void) { struct device_node *np; unsigned int i; struct platform_device *fs_enet_dev; struct resource res; int ret; for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "fs_enet")) != NULL; i++) { struct resource r[4]; struct device_node *phy, *mdio; struct fs_platform_info fs_enet_data; const unsigned int *id, *phy_addr, *phy_irq; const void *mac_addr; const phandle *ph; const char *model; memset(r, 0, sizeof(r)); memset(&fs_enet_data, 0, sizeof(fs_enet_data)); ret = of_address_to_resource(np, 0, &r[0]); if (ret) goto err; r[0].name = fcc_regs; ret = of_address_to_resource(np, 1, &r[1]); if (ret) goto err; r[1].name = fcc_pram; ret = of_address_to_resource(np, 2, &r[2]); if (ret) goto err; r[2].name = fcc_regs_c; fs_enet_data.fcc_regs_c = r[2].start; of_irq_to_resource(np, 0, &r[3]); fs_enet_dev = platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); if (IS_ERR(fs_enet_dev)) { ret = PTR_ERR(fs_enet_dev); goto err; } model = of_get_property(np, "model", NULL); if (model == NULL) { ret = -ENODEV; goto unreg; } mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(fs_enet_data.macaddr, mac_addr, 6); ph = of_get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); if (phy == NULL) { ret = -ENODEV; goto unreg; } phy_addr = of_get_property(phy, "reg", NULL); fs_enet_data.phy_addr = *phy_addr; phy_irq = of_get_property(phy, "interrupts", NULL); id = of_get_property(np, "device-id", NULL); fs_enet_data.fs_no = *id; strcpy(fs_enet_data.fs_type, model); mdio = of_get_parent(phy); ret = of_address_to_resource(mdio, 0, &res); if (ret) { of_node_put(phy); of_node_put(mdio); goto unreg; } fs_enet_data.clk_rx = *((u32 *)of_get_property(np, "rx-clock", NULL)); fs_enet_data.clk_tx = *((u32 *)of_get_property(np, "tx-clock", NULL)); if (strstr(model, "FCC")) { int fcc_index = *id - 1; const unsigned char *mdio_bb_prop; fs_enet_data.dpram_offset = (u32)cpm_dpram_addr(0); fs_enet_data.rx_ring = 32; fs_enet_data.tx_ring = 32; fs_enet_data.rx_copybreak = 240; fs_enet_data.use_napi = 0; fs_enet_data.napi_weight = 17; fs_enet_data.mem_offset = FCC_MEM_OFFSET(fcc_index); fs_enet_data.cp_page = CPM_CR_FCC_PAGE(fcc_index); fs_enet_data.cp_block = CPM_CR_FCC_SBLOCK(fcc_index); snprintf((char*)&bus_id[(*id)], BUS_ID_SIZE, "%x:%02x", (u32)res.start, fs_enet_data.phy_addr); fs_enet_data.bus_id = (char*)&bus_id[(*id)]; fs_enet_data.init_ioports = init_fcc_ioports; mdio_bb_prop = of_get_property(phy, "bitbang", NULL); if (mdio_bb_prop) { struct platform_device *fs_enet_mdio_bb_dev; struct fs_mii_bb_platform_info fs_enet_mdio_bb_data; fs_enet_mdio_bb_dev = platform_device_register_simple("fsl-bb-mdio", i, NULL, 0); memset(&fs_enet_mdio_bb_data, 0, sizeof(struct fs_mii_bb_platform_info)); fs_enet_mdio_bb_data.mdio_dat.bit = mdio_bb_prop[0]; fs_enet_mdio_bb_data.mdio_dir.bit = mdio_bb_prop[1]; fs_enet_mdio_bb_data.mdc_dat.bit = mdio_bb_prop[2]; fs_enet_mdio_bb_data.mdio_port = mdio_bb_prop[3]; fs_enet_mdio_bb_data.mdc_port = mdio_bb_prop[4]; fs_enet_mdio_bb_data.delay = mdio_bb_prop[5]; fs_enet_mdio_bb_data.irq[0] = phy_irq[0]; fs_enet_mdio_bb_data.irq[1] = -1; fs_enet_mdio_bb_data.irq[2] = -1; fs_enet_mdio_bb_data.irq[3] = phy_irq[0]; fs_enet_mdio_bb_data.irq[31] = -1; fs_enet_mdio_bb_data.mdio_dat.offset = (u32)&cpm2_immr->im_ioport.iop_pdatc; fs_enet_mdio_bb_data.mdio_dir.offset = (u32)&cpm2_immr->im_ioport.iop_pdirc; fs_enet_mdio_bb_data.mdc_dat.offset = (u32)&cpm2_immr->im_ioport.iop_pdatc; ret = platform_device_add_data( fs_enet_mdio_bb_dev, &fs_enet_mdio_bb_data, sizeof(struct fs_mii_bb_platform_info)); if (ret) goto unreg; } of_node_put(phy); of_node_put(mdio); ret = platform_device_add_data(fs_enet_dev, &fs_enet_data, sizeof(struct fs_platform_info)); if (ret) goto unreg; } } return 0; unreg: platform_device_unregister(fs_enet_dev); err: return ret; }
/* 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 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 __init tsi108_eth_of_init(void) { struct device_node *np; unsigned int i; struct platform_device *tsi_eth_dev; struct resource res; int ret; for (np = NULL, i = 0; (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL; i++) { struct resource r[2]; struct device_node *phy; hw_info tsi_eth_data; const unsigned int *id; const unsigned int *phy_id; const void *mac_addr; const phandle *ph; memset(r, 0, sizeof(r)); memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); ret = of_address_to_resource(np, 0, &r[0]); DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", __FUNCTION__,r[0].name, r[0].start, r[0].end); if (ret) goto err; r[1].name = "tx"; r[1].start = irq_of_parse_and_map(np, 0); r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", __FUNCTION__,r[1].name, r[1].start, r[1].end); tsi_eth_dev = platform_device_register_simple("tsi-ethernet", i, &r[0], 1); if (IS_ERR(tsi_eth_dev)) { ret = PTR_ERR(tsi_eth_dev); goto err; } mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(tsi_eth_data.mac_addr, mac_addr, 6); ph = of_get_property(np, "phy-handle", NULL); phy = of_find_node_by_phandle(*ph); if (phy == NULL) { ret = -ENODEV; goto unreg; } id = of_get_property(phy, "reg", NULL); phy_id = of_get_property(phy, "phy-id", NULL); ret = of_address_to_resource(phy, 0, &res); if (ret) { of_node_put(phy); goto unreg; } tsi_eth_data.regs = r[0].start; tsi_eth_data.phyregs = res.start; tsi_eth_data.phy = *phy_id; tsi_eth_data.irq_num = irq_of_parse_and_map(np, 0); if (of_device_is_compatible(phy, "bcm54xx")) tsi_eth_data.phy_type = TSI108_PHY_BCM54XX; of_node_put(phy); ret = platform_device_add_data(tsi_eth_dev, &tsi_eth_data, sizeof(hw_info)); if (ret) goto unreg; } return 0; unreg: platform_device_unregister(tsi_eth_dev); err: return ret; }
static int __init mv64x60_eth_device_setup(struct device_node *np, int id) { struct resource r[1]; struct mv643xx_eth_platform_data pdata; struct platform_device *pdev; struct device_node *phy; const u8 *mac_addr; const int *prop; const phandle *ph; int err; /* only register the shared platform device the first time through */ if (id == 0 && (err = eth_register_shared_pdev(np))) return err;; memset(r, 0, sizeof(r)); of_irq_to_resource(np, 0, &r[0]); memset(&pdata, 0, sizeof(pdata)); prop = of_get_property(np, "block-index", NULL); if (!prop) return -ENODEV; pdata.port_number = *prop; mac_addr = of_get_mac_address(np); if (mac_addr) memcpy(pdata.mac_addr, mac_addr, 6); prop = of_get_property(np, "speed", NULL); if (prop) pdata.speed = *prop; prop = of_get_property(np, "tx_queue_size", NULL); if (prop) pdata.tx_queue_size = *prop; prop = of_get_property(np, "rx_queue_size", NULL); if (prop) pdata.rx_queue_size = *prop; prop = of_get_property(np, "tx_sram_addr", NULL); if (prop) pdata.tx_sram_addr = *prop; prop = of_get_property(np, "tx_sram_size", NULL); if (prop) pdata.tx_sram_size = *prop; prop = of_get_property(np, "rx_sram_addr", NULL); if (prop) pdata.rx_sram_addr = *prop; prop = of_get_property(np, "rx_sram_size", NULL); if (prop) pdata.rx_sram_size = *prop; ph = of_get_property(np, "phy", NULL); if (!ph) return -ENODEV; phy = of_find_node_by_phandle(*ph); if (phy == NULL) return -ENODEV; prop = of_get_property(phy, "reg", NULL); if (prop) { pdata.force_phy_addr = 1; pdata.phy_addr = *prop; } of_node_put(phy); pdev = platform_device_alloc(MV643XX_ETH_NAME, pdata.port_number); if (!pdev) return -ENOMEM; err = platform_device_add_resources(pdev, r, 1); if (err) goto error; err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); if (err) goto error; err = platform_device_add(pdev); if (err) goto error; return 0; error: platform_device_put(pdev); return err; }