Exemple #1
0
static int freq_info_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
{
	int ret = 0;
	int i;
	for (i = 0; i < 4; i++) {
		ret += sprintf(page + off + ret, "PLL%d: %ldHz\n", i, tangox_get_pllclock(i));
	}
	ret += sprintf(page + off + ret, "SYS: %ldHz\n", tangox_get_sysclock());
	ret += sprintf(page + off + ret, "CPU: %ldHz\n", tangox_get_cpuclock());
	ret += sprintf(page + off + ret, "DSP: %ldHz\n", tangox_get_dspclock());
	*eof = 1;
	return ret;
}
Exemple #2
0
static int enet_probe(int idx)
{
	struct tangox_enet_priv *priv;
	struct net_device *dev;
	int ret;
	struct sockaddr sock;
	char pad_mode;
	short clk_div;
	unsigned long enet_mac_base;
	const char *name;

	enet_mac_base = eth_mac_cores[idx].enet_mac_base;
	name = eth_mac_cores[idx].name;

#if 1 /* this part may be moved to boot loader */
	/* set pad_mode*/
	pad_mode = enet_readb(enet_mac_base + 0x400);
	enet_writeb(enet_mac_base + 0x400, pad_mode & 0xf0);
	pad_mode = enet_readb(enet_mac_base + 0x400);

	/* set MDIO clock divider */
	clk_div = enet_readw(enet_mac_base + 0x420);
	//DBG("default clk_div =%d\n", clk_div);
	//enet_writew(enet_mac_base + 0x420, 50);
	enet_writew(enet_mac_base + 0x420, tangox_get_sysclock() / (2500000 * 2));
	clk_div = enet_readw(enet_mac_base + 0x420);
	//DBG("clk_div =%d: set MDIO clock=200/%d=%dMHz\n", clk_div, clk_div, 200/(clk_div*2));
#endif

	/* allocate  netdevice structure  with enough  length  for our
	 * context data */
	dev = alloc_etherdev(sizeof (*priv));
	if (!dev)
		return -ENOMEM;

	/* initialize private data */
	priv = netdev_priv(dev);
	memset(priv, 0, sizeof (*priv));
	priv->enet_mac_base = enet_mac_base;
	priv->name = name;
	priv->pending_tx = -1;
	priv->pending_tx_cnt = 0;
	priv->reclaim_limit = -1;
	spin_lock_init(&priv->tx_lock);
	spin_lock_init(&priv->ier_lock);
	spin_lock_init(&priv->maccr_lock);

	/* init tx done tasklet */
	tasklet_init(&priv->tx_reclaim_tasklet, enet_tx_reclaim,
		     (unsigned long)dev);
#if 0
	/* init tx reclaim timer */
	init_timer(&priv->tx_reclaim_timer);
	priv->tx_reclaim_timer.data = (unsigned long )dev;
	priv->tx_reclaim_timer.function = enet_tx_reclaim_timer;
#endif
	/* init link check timer and mii lock */
	init_timer(&priv->link_check_timer);
	priv->link_check_timer.data = (unsigned long)dev;
	priv->link_check_timer.function = enet_link_check;
	spin_lock_init(&priv->mii_lock);

	/* fill mii info */
	priv->mii.dev = dev;
	priv->mii.phy_id_mask  = 0x1f;
	priv->mii.reg_num_mask = 0x1f;
	priv->mii.mdio_read = enet_mdio_read;
	priv->mii.mdio_write = enet_mdio_write;
	
	if (eth_mac_cores[idx].phy_id != -1) {
		/* phy id forced, just check for sanity */
		if (eth_mac_cores[idx].phy_id < 0 || eth_mac_cores[idx].phy_id > 31) {
			ret = -EINVAL;
			goto err_free;
		}
		priv->mii.phy_id = eth_mac_cores[idx].phy_id;

	} else {
		int i;

		/* try to probe phy if not given */
		for (i = 0; i <32; i++) {
			uint32_t id;
			int val;

			val = enet_mdio_read(dev, i, MII_PHYSID1);
			id = (val << 16);
			val = enet_mdio_read(dev, i, MII_PHYSID2);
			id |= val;
			if (id != 0xffffffff && id != 0x00000000) {
				/* check vsc8061 */
				if(id == 0x00070421)
					priv->rgmii = 1;
				break;
			}
		}
		if (i == 32) {
			printk(KERN_ERR "%s: unable to autodetect phy\n", priv->name);
			ret = -EIO;
			goto err_free;
		}
		printk(KERN_ERR "%s: detected phy %s at address 0x%02x\n", name,(priv->rgmii? "vsc8601":""), i);
		priv->mii.phy_id = i;
	}

	printk(KERN_INFO "%s: Ethernet driver for SMP864x/SMP865x internal MAC core %d: %s Base at 0x%lx\n",
				 name, idx, priv->rgmii?"1000Mbps":"100Mbps",  enet_mac_base);

	/* initialize hardware */
	if ((ret = enet_hw_init(dev)))
		goto err_free;

	/* initialize dma descriptors */
	if ((ret = enet_dma_init(priv)))
		goto err_free;

	ret = request_irq(eth_mac_cores[idx].irq, enet_isr, IRQF_DISABLED,
			  eth_mac_cores[idx].name, dev);
	dev->irq = eth_mac_cores[idx].irq;

	if (ret)
		goto err_free;

	/* install driver callbacks and register netdevice */
	dev->open = enet_open;
	dev->stop = enet_stop;
	dev->hard_start_xmit = enet_xmit;
	dev->get_stats = enet_get_stats;
	dev->set_mac_address = enet_set_mac_address;
	dev->set_multicast_list = enet_set_multicast_list;
	dev->poll = enet_poll;
	dev->ethtool_ops = &enet_ethtool_ops;
	dev->do_ioctl = enet_ioctl;
	dev->weight = RX_DESC_COUNT;
	dev->tx_queue_len = TX_DESC_COUNT;
#ifdef ENABLE_MULTICAST
	dev->flags |= IFF_MULTICAST;
#else	
	dev->flags &= ~IFF_MULTICAST;
#endif

	/* set default mac address */
	tangox_ethernet_getmac(idx, dev->dev_addr);
	memcpy(&(sock.sa_data), dev->dev_addr, ETH_ALEN);

	enet_set_mac_address(dev, &sock);

	if ((ret = register_netdev(dev))) {
		printk(KERN_ERR "%s: unable to register netdevice\n", priv->name);
		goto err_free;
	}

	printk(KERN_INFO "%s: mac address %02x:%02x:%02x:%02x:%02x:%02x\n", priv->name,
	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);

	eth_mac_cores[idx].gdev = dev;
	return 0;

err_free:
	if (dev->irq)
		free_irq(dev->irq, dev);
	enet_dma_free(priv);
	free_netdev(dev);
	return ret;
}