示例#1
0
static void hss_npe_send(struct port *port, struct msg *msg, const char* what)
{
	u32 *val = (u32*)msg;
	if (npe_send_message(port->npe, msg, what)) {
		pr_crit("HSS-%i: unable to send command [%08X:%08X] to %s\n",
			port->id, val[0], val[1], npe_name(port->npe));
		BUG();
	}
}
示例#2
0
static int hss_load_firmware(struct port *port)
{
	struct msg msg;
	int err;

	if (port->initialized)
		return 0;

	if (!npe_running(port->npe) &&
	    (err = npe_load_firmware(port->npe, npe_name(port->npe),
				     port->dev)))
		return err;

	
	memset(&msg, 0, sizeof(msg));
	msg.cmd = PKT_NUM_PIPES_WRITE;
	msg.hss_port = port->id;
	msg.data8a = PKT_NUM_PIPES;
	hss_npe_send(port, &msg, "HSS_SET_PKT_PIPES");

	msg.cmd = PKT_PIPE_FIFO_SIZEW_WRITE;
	msg.data8a = PKT_PIPE_FIFO_SIZEW;
	hss_npe_send(port, &msg, "HSS_SET_PKT_FIFO");

	msg.cmd = PKT_PIPE_MODE_WRITE;
	msg.data8a = NPE_PKT_MODE_HDLC;
	
	
	hss_npe_send(port, &msg, "HSS_SET_PKT_MODE");

	msg.cmd = PKT_PIPE_RX_SIZE_WRITE;
	msg.data16a = HDLC_MAX_MRU; 
	hss_npe_send(port, &msg, "HSS_SET_PKT_RX_SIZE");

	msg.cmd = PKT_PIPE_IDLE_PATTERN_WRITE;
	msg.data32 = 0x7F7F7F7F; 
	hss_npe_send(port, &msg, "HSS_SET_PKT_IDLE");

	port->initialized = 1;
	return 0;
}
示例#3
0
static int eth_open(struct net_device *dev)
{
	struct port *port = netdev_priv(dev);
	struct npe *npe = port->npe;
	struct msg msg;
	int i, err;

	if (!npe_running(npe)) {
		err = npe_load_firmware(npe, npe_name(npe), &dev->dev);
		if (err)
			return err;

		if (npe_recv_message(npe, &msg, "ETH_GET_STATUS")) {
			printk(KERN_ERR "%s: %s not responding\n", dev->name,
			       npe_name(npe));
			return -EIO;
		}
		port->firmware[0] = msg.byte4;
		port->firmware[1] = msg.byte5;
		port->firmware[2] = msg.byte6;
		port->firmware[3] = msg.byte7;
	}

	memset(&msg, 0, sizeof(msg));
	msg.cmd = NPE_VLAN_SETRXQOSENTRY;
	msg.eth_id = port->id;
	msg.byte5 = port->plat->rxq | 0x80;
	msg.byte7 = port->plat->rxq << 4;
	for (i = 0; i < 8; i++) {
		msg.byte3 = i;
		if (npe_send_recv_message(port->npe, &msg, "ETH_SET_RXQ"))
			return -EIO;
	}

	msg.cmd = NPE_EDB_SETPORTADDRESS;
	msg.eth_id = PHYSICAL_ID(port->id);
	msg.byte2 = dev->dev_addr[0];
	msg.byte3 = dev->dev_addr[1];
	msg.byte4 = dev->dev_addr[2];
	msg.byte5 = dev->dev_addr[3];
	msg.byte6 = dev->dev_addr[4];
	msg.byte7 = dev->dev_addr[5];
	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_MAC"))
		return -EIO;

	memset(&msg, 0, sizeof(msg));
	msg.cmd = NPE_FW_SETFIREWALLMODE;
	msg.eth_id = port->id;
	if (npe_send_recv_message(port->npe, &msg, "ETH_SET_FIREWALL_MODE"))
		return -EIO;

	if ((err = request_queues(port)) != 0)
		return err;

	if ((err = init_queues(port)) != 0) {
		destroy_queues(port);
		release_queues(port);
		return err;
	}

	port->speed = 0;	/* force "link up" message */
	phy_start(port->phydev);

	for (i = 0; i < ETH_ALEN; i++)
		__raw_writel(dev->dev_addr[i], &port->regs->hw_addr[i]);
	__raw_writel(0x08, &port->regs->random_seed);
	__raw_writel(0x12, &port->regs->partial_empty_threshold);
	__raw_writel(0x30, &port->regs->partial_full_threshold);
	__raw_writel(0x08, &port->regs->tx_start_bytes);
	__raw_writel(0x15, &port->regs->tx_deferral);
	__raw_writel(0x08, &port->regs->tx_2part_deferral[0]);
	__raw_writel(0x07, &port->regs->tx_2part_deferral[1]);
	__raw_writel(0x80, &port->regs->slot_time);
	__raw_writel(0x01, &port->regs->int_clock_threshold);

	/* Populate queues with buffers, no failure after this point */
	for (i = 0; i < TX_DESCS; i++)
		queue_put_desc(port->plat->txreadyq,
			       tx_desc_phys(port, i), tx_desc_ptr(port, i));

	for (i = 0; i < RX_DESCS; i++)
		queue_put_desc(RXFREE_QUEUE(port->id),
			       rx_desc_phys(port, i), rx_desc_ptr(port, i));

	__raw_writel(TX_CNTRL1_RETRIES, &port->regs->tx_control[1]);
	__raw_writel(DEFAULT_TX_CNTRL0, &port->regs->tx_control[0]);
	__raw_writel(0, &port->regs->rx_control[1]);
	__raw_writel(DEFAULT_RX_CNTRL0, &port->regs->rx_control[0]);

	napi_enable(&port->napi);
	eth_set_mcast_list(dev);
	netif_start_queue(dev);

	qmgr_set_irq(port->plat->rxq, QUEUE_IRQ_SRC_NOT_EMPTY,
		     eth_rx_irq, dev);
	if (!ports_open) {
		qmgr_set_irq(TXDONE_QUEUE, QUEUE_IRQ_SRC_NOT_EMPTY,
			     eth_txdone_irq, NULL);
		qmgr_enable_irq(TXDONE_QUEUE);
	}
	ports_open++;
	/* we may already have RX data, enables IRQ */
	napi_schedule(&port->napi);
	return 0;
}
示例#4
0
static int __devinit eth_init_one(struct platform_device *pdev)
{
	struct port *port;
	struct net_device *dev;
	struct eth_plat_info *plat = pdev->dev.platform_data;
	u32 regs_phys;
	char phy_id[BUS_ID_SIZE];
	int err;

	if (!(dev = alloc_etherdev(sizeof(struct port))))
		return -ENOMEM;

	SET_NETDEV_DEV(dev, &pdev->dev);
	port = netdev_priv(dev);
	port->netdev = dev;
	port->id = pdev->id;

	switch (port->id) {
	case IXP4XX_ETH_NPEA:
		port->regs = (struct eth_regs __iomem *)IXP4XX_EthA_BASE_VIRT;
		regs_phys  = IXP4XX_EthA_BASE_PHYS;
		break;
	case IXP4XX_ETH_NPEB:
		port->regs = (struct eth_regs __iomem *)IXP4XX_EthB_BASE_VIRT;
		regs_phys  = IXP4XX_EthB_BASE_PHYS;
		break;
	case IXP4XX_ETH_NPEC:
		port->regs = (struct eth_regs __iomem *)IXP4XX_EthC_BASE_VIRT;
		regs_phys  = IXP4XX_EthC_BASE_PHYS;
		break;
	default:
		err = -ENOSYS;
		goto err_free;
	}

	dev->netdev_ops = &ixp4xx_netdev_ops;
	dev->ethtool_ops = &ixp4xx_ethtool_ops;
	dev->tx_queue_len = 100;

	netif_napi_add(dev, &port->napi, eth_poll, NAPI_WEIGHT);

	if (!(port->npe = npe_request(NPE_ID(port->id)))) {
		err = -EIO;
		goto err_free;
	}

	if (register_netdev(dev)) {
		err = -EIO;
		goto err_npe_rel;
	}

	port->mem_res = request_mem_region(regs_phys, REGS_SIZE, dev->name);
	if (!port->mem_res) {
		err = -EBUSY;
		goto err_unreg;
	}

	port->plat = plat;
	npe_port_tab[NPE_ID(port->id)] = port;
	memcpy(dev->dev_addr, plat->hwaddr, ETH_ALEN);

	platform_set_drvdata(pdev, dev);

	__raw_writel(DEFAULT_CORE_CNTRL | CORE_RESET,
		     &port->regs->core_control);
	udelay(50);
	__raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
	udelay(50);

	snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
	port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
				   PHY_INTERFACE_MODE_MII);
	if (IS_ERR(port->phydev)) {
		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
		return PTR_ERR(port->phydev);
	}

	port->phydev->irq = PHY_POLL;

	printk(KERN_INFO "%s: MII PHY %i on %s\n", dev->name, plat->phy,
	       npe_name(port->npe));

	return 0;

err_unreg:
	unregister_netdev(dev);
err_npe_rel:
	npe_release(port->npe);
err_free:
	free_netdev(dev);
	return err;
}