Beispiel #1
0
void eth_mdio_enable(void)
{
	davinci_eth_mdio_enable();
}
Beispiel #2
0
/*
 * This function initializes the emac hardware. It does NOT initialize
 * EMAC modules power or pin multiplexors, that is done by board_init()
 * much earlier in bootup process. Returns 1 on success, 0 otherwise.
 */
int davinci_emac_initialize(void)
{
	u_int32_t	phy_id;
	u_int16_t	tmp;
	int		i;
	struct eth_device *dev;

	dev = malloc(sizeof *dev);

	if (dev == NULL)
		return -1;

	memset(dev, 0, sizeof *dev);
	sprintf(dev->name, "DaVinci-EMAC");

	dev->iobase = 0;
	dev->init = davinci_eth_open;
	dev->halt = davinci_eth_close;
	dev->send = davinci_eth_send_packet;
	dev->recv = davinci_eth_rcv_packet;
	dev->write_hwaddr = davinci_eth_set_mac_addr;

	eth_register(dev);

	davinci_eth_mdio_enable();

	for (i = 0; i < 256; i++) {
		if (readl(&adap_mdio->ALIVE))
			break;
		udelay(10);
	}

	if (i >= 256) {
		printf("No ETH PHY detected!!!\n");
		return(0);
	}

	/* Find if a PHY is connected and get it's address */
	if (!davinci_eth_phy_detect())
		return(0);

	/* Get PHY ID and initialize phy_ops for a detected PHY */
	if (!davinci_eth_phy_read(active_phy_addr, PHY_PHYIDR1, &tmp)) {
		active_phy_addr = 0xff;
		return(0);
	}

	phy_id = (tmp << 16) & 0xffff0000;

	if (!davinci_eth_phy_read(active_phy_addr, PHY_PHYIDR2, &tmp)) {
		active_phy_addr = 0xff;
		return(0);
	}

	phy_id |= tmp & 0x0000ffff;

	switch (phy_id) {
		case PHY_LXT972:
			sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr);
			phy.init = lxt972_init_phy;
			phy.is_phy_connected = lxt972_is_phy_connected;
			phy.get_link_speed = lxt972_get_link_speed;
			phy.auto_negotiate = lxt972_auto_negotiate;
			break;
		case PHY_DP83848:
			sprintf(phy.name, "DP83848 @ 0x%02x", active_phy_addr);
			phy.init = dp83848_init_phy;
			phy.is_phy_connected = dp83848_is_phy_connected;
			phy.get_link_speed = dp83848_get_link_speed;
			phy.auto_negotiate = dp83848_auto_negotiate;
			break;
		case PHY_ET1011C:
			sprintf(phy.name, "ET1011C @ 0x%02x", active_phy_addr);
			phy.init = gen_init_phy;
			phy.is_phy_connected = gen_is_phy_connected;
			phy.get_link_speed = et1011c_get_link_speed;
			phy.auto_negotiate = gen_auto_negotiate;
			break;
		default:
			sprintf(phy.name, "GENERIC @ 0x%02x", active_phy_addr);
			phy.init = gen_init_phy;
			phy.is_phy_connected = gen_is_phy_connected;
			phy.get_link_speed = gen_get_link_speed;
			phy.auto_negotiate = gen_auto_negotiate;
	}

	printf("Ethernet PHY: %s\n", phy.name);

	miiphy_register(phy.name, davinci_mii_phy_read, davinci_mii_phy_write);
	return(1);
}
Beispiel #3
0
/*
 * This function initializes the emac hardware. It does NOT initialize
 * EMAC modules power or pin multiplexors, that is done by board_init()
 * much earlier in bootup process. Returns 1 on success, 0 otherwise.
 */
int davinci_emac_initialize(void)
{
	u_int32_t	phy_id;
	u_int16_t	tmp;
	int		i;
	int		ret;
	struct eth_device *dev;

	dev = malloc(sizeof *dev);

	if (dev == NULL)
		return -1;

	memset(dev, 0, sizeof *dev);
	strcpy(dev->name, "DaVinci-EMAC");

	dev->iobase = 0;
	dev->init = davinci_eth_open;
	dev->halt = davinci_eth_close;
	dev->send = davinci_eth_send_packet;
	dev->recv = davinci_eth_rcv_packet;
	dev->write_hwaddr = davinci_eth_set_mac_addr;

	eth_register(dev);

	davinci_eth_mdio_enable();

	/* let the EMAC detect the PHYs */
	udelay(5000);

	for (i = 0; i < 256; i++) {
		if (readl(&adap_mdio->ALIVE))
			break;
		udelay(1000);
	}

	if (i >= 256) {
		printf("No ETH PHY detected!!!\n");
		return(0);
	}

	/* Find if PHY(s) is/are connected */
	ret = davinci_eth_phy_detect();
	if (!ret)
		return(0);
	else
		debug_emac(" %d ETH PHY detected\n", ret);

	/* Get PHY ID and initialize phy_ops for a detected PHY */
	for (i = 0; i < num_phy; i++) {
		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID1,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}

		phy_id = (tmp << 16) & 0xffff0000;

		if (!davinci_eth_phy_read(active_phy_addr[i], MII_PHYSID2,
							&tmp)) {
			active_phy_addr[i] = 0xff;
			continue;
		}

		phy_id |= tmp & 0x0000ffff;

		switch (phy_id) {
#ifdef PHY_KSZ8873
		case PHY_KSZ8873:
			sprintf(phy[i].name, "KSZ8873 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = ksz8873_init_phy;
			phy[i].is_phy_connected = ksz8873_is_phy_connected;
			phy[i].get_link_speed = ksz8873_get_link_speed;
			phy[i].auto_negotiate = ksz8873_auto_negotiate;
			break;
#endif
#ifdef PHY_LXT972
		case PHY_LXT972:
			sprintf(phy[i].name, "LXT972 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = lxt972_init_phy;
			phy[i].is_phy_connected = lxt972_is_phy_connected;
			phy[i].get_link_speed = lxt972_get_link_speed;
			phy[i].auto_negotiate = lxt972_auto_negotiate;
			break;
#endif
#ifdef PHY_DP83848
		case PHY_DP83848:
			sprintf(phy[i].name, "DP83848 @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = dp83848_init_phy;
			phy[i].is_phy_connected = dp83848_is_phy_connected;
			phy[i].get_link_speed = dp83848_get_link_speed;
			phy[i].auto_negotiate = dp83848_auto_negotiate;
			break;
#endif
#ifdef PHY_ET1011C
		case PHY_ET1011C:
			sprintf(phy[i].name, "ET1011C @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = gen_init_phy;
			phy[i].is_phy_connected = gen_is_phy_connected;
			phy[i].get_link_speed = et1011c_get_link_speed;
			phy[i].auto_negotiate = gen_auto_negotiate;
			break;
#endif
		default:
			sprintf(phy[i].name, "GENERIC @ 0x%02x",
						active_phy_addr[i]);
			phy[i].init = gen_init_phy;
			phy[i].is_phy_connected = gen_is_phy_connected;
			phy[i].get_link_speed = gen_get_link_speed;
			phy[i].auto_negotiate = gen_auto_negotiate;
		}

		debug("Ethernet PHY: %s\n", phy[i].name);

		int retval;
		struct mii_dev *mdiodev = mdio_alloc();
		if (!mdiodev)
			return -ENOMEM;
		strncpy(mdiodev->name, phy[i].name, MDIO_NAME_LEN);
		mdiodev->read = davinci_mii_phy_read;
		mdiodev->write = davinci_mii_phy_write;

		retval = mdio_register(mdiodev);
		if (retval < 0)
			return retval;
#ifdef DAVINCI_EMAC_GIG_ENABLE
#define PHY_CONF_REG	22
		/* Enable PHY to clock out TX_CLK */
		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
		tmp |= PHY_CONF_TXCLKEN;
		davinci_eth_phy_write(active_phy_addr[i], PHY_CONF_REG, tmp);
		davinci_eth_phy_read(active_phy_addr[i], PHY_CONF_REG, &tmp);
#endif
	}

#if defined(CONFIG_TI816X) || (defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \
		defined(CONFIG_MACH_DAVINCI_DA850_EVM) && \
			!defined(CONFIG_DRIVER_TI_EMAC_RMII_NO_NEGOTIATE))
	for (i = 0; i < num_phy; i++) {
		if (phy[i].is_phy_connected(i))
			phy[i].auto_negotiate(i);
	}
#endif
	return(1);
}
Beispiel #4
0
static int davinci_emac_probe(struct device_d *dev)
{
	struct davinci_emac_platform_data *pdata;
	struct davinci_emac_priv *priv;
	uint64_t start;
	uint32_t phy_mask;

	dev_dbg(dev, "+ emac_probe\n");

	if (!dev->platform_data) {
		dev_err(dev, "no platform_data\n");
		return -ENODEV;
	}
	pdata = dev->platform_data;

	priv = xzalloc(sizeof(*priv));
	dev->priv = priv;

	priv->dev = dev;

	priv->adap_emac = dev_request_mem_region(dev, 0);
	priv->adap_ewrap = dev_request_mem_region(dev, 1);
	priv->adap_mdio = dev_request_mem_region(dev, 2);
	priv->emac_desc_base = dev_request_mem_region(dev, 3);

	/* EMAC descriptors */
	priv->emac_rx_desc = priv->emac_desc_base + EMAC_RX_DESC_BASE;
	priv->emac_tx_desc = priv->emac_desc_base + EMAC_TX_DESC_BASE;
	priv->emac_rx_active_head = NULL;
	priv->emac_rx_active_tail = NULL;
	priv->emac_rx_queue_active = 0;

	/* Receive packet buffers */
	priv->emac_rx_buffers = xmemalign(4096, EMAC_MAX_RX_BUFFERS * (EMAC_MAX_ETHERNET_PKT_SIZE + EMAC_PKT_ALIGN));

	priv->edev.priv = priv;
	priv->edev.init = davinci_emac_init;
	priv->edev.open = davinci_emac_open;
	priv->edev.halt = davinci_emac_halt;
	priv->edev.send = davinci_emac_send;
	priv->edev.recv = davinci_emac_recv;
	priv->edev.get_ethaddr = davinci_emac_get_ethaddr;
	priv->edev.set_ethaddr = davinci_emac_set_ethaddr;
	priv->edev.parent = dev;

	davinci_eth_mdio_enable(priv);

	start = get_time_ns();
	while (1) {
		phy_mask = readl(priv->adap_mdio + EMAC_MDIO_ALIVE);
		if (phy_mask) {
			dev_info(dev, "detected phy mask 0x%x\n", phy_mask);
			phy_mask = ~phy_mask;
			break;
		}
		if (is_timeout(start, 256 * MSECOND)) {
			dev_err(dev, "no live phy, scanning all\n");
			phy_mask = 0;
			break;
		}
	}

	if (pdata->interface_rmii)
		priv->interface = PHY_INTERFACE_MODE_RMII;
	else
		priv->interface = PHY_INTERFACE_MODE_MII;
	priv->phy_addr = pdata->phy_addr;
	priv->phy_flags = pdata->force_link ? PHYLIB_FORCE_LINK : 0;

	priv->miibus.read = davinci_miibus_read;
	priv->miibus.write = davinci_miibus_write;
	priv->miibus.priv = priv;
	priv->miibus.parent = dev;
	priv->miibus.phy_mask = phy_mask;

	mdiobus_register(&priv->miibus);

	eth_register(&priv->edev);

	dev_dbg(dev, "- emac_probe\n");
	return 0;
}