示例#1
0
static void ks8842_update_link_status(struct net_device *netdev,
	struct ks8842_adapter *adapter)
{
	/*                              */
	if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) {
		netif_carrier_on(netdev);
		netif_wake_queue(netdev);
	} else {
		netif_stop_queue(netdev);
		netif_carrier_off(netdev);
	}
}
示例#2
0
static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest)
{
	int i;
	u16 mac;

	for (i = 0; i < ETH_ALEN; i++)
		dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i);

	if (adapter->conf_flags & MICREL_KS884X) {
		/*
		the sequence of saving mac addr between MAC and Switch is
		different.
		*/

		mac = ks8842_read16(adapter, 2, REG_MARL);
		ks8842_write16(adapter, 39, mac, REG_MACAR3);
		mac = ks8842_read16(adapter, 2, REG_MARM);
		ks8842_write16(adapter, 39, mac, REG_MACAR2);
		mac = ks8842_read16(adapter, 2, REG_MARH);
		ks8842_write16(adapter, 39, mac, REG_MACAR1);
	} else {

		/* make sure the switch port uses the same MAC as the QMU */
		mac = ks8842_read16(adapter, 2, REG_MARL);
		ks8842_write16(adapter, 39, mac, REG_MACAR1);
		mac = ks8842_read16(adapter, 2, REG_MARM);
		ks8842_write16(adapter, 39, mac, REG_MACAR2);
		mac = ks8842_read16(adapter, 2, REG_MARH);
		ks8842_write16(adapter, 39, mac, REG_MACAR3);
	}
}
示例#3
0
static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest)
{
	int i;
	u16 mac;

	for (i = 0; i < ETH_ALEN; i++)
		dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i);

	if (adapter->conf_flags & MICREL_KS884X) {
		/*
                                                           
            
  */

		mac = ks8842_read16(adapter, 2, REG_MARL);
		ks8842_write16(adapter, 39, mac, REG_MACAR3);
		mac = ks8842_read16(adapter, 2, REG_MARM);
		ks8842_write16(adapter, 39, mac, REG_MACAR2);
		mac = ks8842_read16(adapter, 2, REG_MARH);
		ks8842_write16(adapter, 39, mac, REG_MACAR1);
	} else {

		/*                                                        */
		mac = ks8842_read16(adapter, 2, REG_MARL);
		ks8842_write16(adapter, 39, mac, REG_MACAR1);
		mac = ks8842_read16(adapter, 2, REG_MARM);
		ks8842_write16(adapter, 39, mac, REG_MACAR2);
		mac = ks8842_read16(adapter, 2, REG_MARH);
		ks8842_write16(adapter, 39, mac, REG_MACAR3);
	}
}
示例#4
0
void ks8842_tasklet(unsigned long arg)
{
	struct net_device *netdev = (struct net_device *)arg;
	struct ks8842_adapter *adapter = netdev_priv(netdev);
	u16 isr;
	unsigned long flags;
	u16 entry_bank;

	/* read current bank to be able to set it back */
	spin_lock_irqsave(&adapter->lock, flags);
	entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
	spin_unlock_irqrestore(&adapter->lock, flags);

	isr = ks8842_read16(adapter, 18, REG_ISR);
	dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);

	/* Ack */
	ks8842_write16(adapter, 18, isr, REG_ISR);

	if (!netif_running(netdev))
		return;

	if (isr & IRQ_LINK_CHANGE)
		ks8842_update_link_status(netdev, adapter);

	if (isr & (IRQ_RX | IRQ_RX_ERROR))
		ks8842_handle_rx(netdev, adapter);

	if (isr & IRQ_TX)
		ks8842_handle_tx(netdev, adapter);

	if (isr & IRQ_RX_OVERRUN)
		ks8842_handle_rx_overrun(netdev, adapter);

	if (isr & IRQ_TX_STOPPED) {
		ks8842_disable_tx(adapter);
		ks8842_enable_tx(adapter);
	}

	if (isr & IRQ_RX_STOPPED) {
		ks8842_disable_rx(adapter);
		ks8842_enable_rx(adapter);
	}

	/* re-enable interrupts, put back the bank selection register */
	spin_lock_irqsave(&adapter->lock, flags);
	ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
	iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
	spin_unlock_irqrestore(&adapter->lock, flags);
}
示例#5
0
static irqreturn_t ks8842_irq(int irq, void *devid)
{
	struct ks8842_adapter *adapter = devid;
	u16 isr;
	u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
	irqreturn_t ret = IRQ_NONE;

	isr = ks8842_read16(adapter, 18, REG_ISR);
	dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);

	if (isr) {
		/* disable IRQ */
		ks8842_write16(adapter, 18, 0x00, REG_IER);

		/* schedule tasklet */
		tasklet_schedule(&adapter->tasklet);

		ret = IRQ_HANDLED;
	}

	iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);

	return ret;
}
示例#6
0
static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter)
{
	return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff;
}
示例#7
0
static int __devinit ks8842_probe(struct platform_device *pdev)
{
	int err = -ENOMEM;
	struct resource *iomem;
	struct net_device *netdev;
	struct ks8842_adapter *adapter;
	u16 id;

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME))
		goto err_mem_region;

	netdev = alloc_etherdev(sizeof(struct ks8842_adapter));
	if (!netdev)
		goto err_alloc_etherdev;

	SET_NETDEV_DEV(netdev, &pdev->dev);

	adapter = netdev_priv(netdev);
	adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
	if (!adapter->hw_addr)
		goto err_ioremap;

	adapter->irq = platform_get_irq(pdev, 0);
	if (adapter->irq < 0) {
		err = adapter->irq;
		goto err_get_irq;
	}

	adapter->pdev = pdev;

	tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev);
	spin_lock_init(&adapter->lock);

	netdev->netdev_ops = &ks8842_netdev_ops;
	netdev->ethtool_ops = &ks8842_ethtool_ops;

	ks8842_read_mac_addr(adapter, netdev->dev_addr);

	id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE);

	strcpy(netdev->name, "eth%d");
	err = register_netdev(netdev);
	if (err)
		goto err_register;

	platform_set_drvdata(pdev, netdev);

	printk(KERN_INFO DRV_NAME
		" Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n",
		(id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);

	return 0;

err_register:
err_get_irq:
	iounmap(adapter->hw_addr);
err_ioremap:
	free_netdev(netdev);
err_alloc_etherdev:
	release_mem_region(iomem->start, resource_size(iomem));
err_mem_region:
	return err;
}