static void au1k_tx_ack(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	volatile struct ring_dest *ptxd;

	ptxd = aup->tx_ring[aup->tx_tail];
	while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
		update_tx_stats(dev, ptxd->flags,
				(ptxd->count_1 << 8) | ptxd->count_0);
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
		wmb();
		aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
		ptxd = aup->tx_ring[aup->tx_tail];

		if (aup->tx_full) {
			aup->tx_full = 0;
			netif_wake_queue(dev);
		}
	}

	if (aup->tx_tail == aup->tx_head) {
		if (aup->newspeed) {
			au1k_irda_set_speed(dev, aup->newspeed);
			aup->newspeed = 0;
		} else {
			irda_write(aup, IR_CONFIG_1,
			    irda_read(aup, IR_CONFIG_1) & ~IR_TX_ENABLE);
			irda_write(aup, IR_CONFIG_1,
			    irda_read(aup, IR_CONFIG_1) | IR_RX_ENABLE);
			irda_write(aup, IR_RING_PROMPT, 0);
		}
	}
}
/*
 * Au1000 transmit routine.
 */
static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	int speed = irda_get_next_speed(skb);
	volatile struct ring_dest *ptxd;
	struct db_dest *pDB;
	u32 len, flags;

	if (speed != aup->speed && speed != -1)
		aup->newspeed = speed;

	if ((skb->len == 0) && (aup->newspeed)) {
		if (aup->tx_tail == aup->tx_head) {
			au1k_irda_set_speed(dev, speed);
			aup->newspeed = 0;
		}
		dev_kfree_skb(skb);
		return NETDEV_TX_OK;
	}

	ptxd = aup->tx_ring[aup->tx_head];
	flags = ptxd->flags;

	if (flags & AU_OWN) {
		printk(KERN_DEBUG "%s: tx_full\n", dev->name);
		netif_stop_queue(dev);
		aup->tx_full = 1;
		return 1;
	} else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
		printk(KERN_DEBUG "%s: tx_full\n", dev->name);
		netif_stop_queue(dev);
		aup->tx_full = 1;
		return 1;
	}

	pDB = aup->tx_db_inuse[aup->tx_head];

#if 0
	if (irda_read(aup, IR_RX_BYTE_CNT) != 0) {
		printk(KERN_DEBUG "tx warning: rx byte cnt %x\n",
				irda_read(aup, IR_RX_BYTE_CNT));
	}
#endif

	if (aup->speed == 4000000) {
		/* FIR */
		skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
		ptxd->count_0 = skb->len & 0xff;
		ptxd->count_1 = (skb->len >> 8) & 0xff;
	} else {
static int au1k_irda_stop(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);

	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);

	/* disable interrupts */
	irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) & ~IR_IEN);
	irda_write(aup, IR_CONFIG_1, 0);
	irda_write(aup, IR_ENABLE, 0); /* disable clock */

	if (aup->irlap) {
		irlap_close(aup->irlap);
		aup->irlap = NULL;
	}

	netif_stop_queue(dev);
	del_timer(&aup->timer);

	/* disable the interrupt */
	free_irq(aup->irq_tx, dev);
	free_irq(aup->irq_rx, dev);

	return 0;
}
static int au1k_irda_start(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	char hwname[32];
	int retval;

	retval = au1k_init(dev);
	if (retval) {
		printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
		return retval;
	}

	retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0,
			     dev->name, dev);
	if (retval) {
		printk(KERN_ERR "%s: unable to get IRQ %d\n",
				dev->name, dev->irq);
		return retval;
	}
	retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0,
			     dev->name, dev);
	if (retval) {
		free_irq(aup->irq_tx, dev);
		printk(KERN_ERR "%s: unable to get IRQ %d\n",
				dev->name, dev->irq);
		return retval;
	}

	/* Give self a hardware name */
	sprintf(hwname, "Au1000 SIR/FIR");
	aup->irlap = irlap_open(dev, &aup->qos, hwname);
	netif_start_queue(dev);

	/* int enable */
	irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) | IR_IEN);

	/* power up */
	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);

	aup->timer.expires = RUN_AT((3 * HZ));
	aup->timer.data = (unsigned long)dev;
	return 0;
}
static int au1k_init(struct net_device *dev)
{
	struct au1k_private *aup = netdev_priv(dev);
	u32 enable, ring_address;
	int i;

	enable = IR_HC | IR_CE | IR_C;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
	enable |= IR_BE;
#endif
	aup->tx_head = 0;
	aup->tx_tail = 0;
	aup->rx_head = 0;

	for (i = 0; i < NUM_IR_DESC; i++)
		aup->rx_ring[i]->flags = AU_OWN;

	irda_write(aup, IR_ENABLE, enable);
	msleep(20);

	/* disable PHY */
	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
	irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
	msleep(20);

	irda_write(aup, IR_MAX_PKT_LEN, MAX_BUF_SIZE);

	ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
	irda_write(aup, IR_RING_BASE_ADDR_H, ring_address >> 26);
	irda_write(aup, IR_RING_BASE_ADDR_L, (ring_address >> 10) & 0xffff);

	irda_write(aup, IR_RING_SIZE,
				(RING_SIZE_64 << 8) | (RING_SIZE_64 << 12));

	irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN);
	irda_write(aup, IR_RING_ADDR_CMPR, 0);

	au1k_irda_set_speed(dev, 9600);
	return 0;
}
Exemple #6
0
size_t device_read(__ptr_t buf, size_t nbytes, struct gn_statemachine *state)
{
	switch (state->device.type) {
	case GN_CT_DKU2:
	case GN_CT_Serial:
	case GN_CT_Infrared:
		return serial_read(state->device.fd, buf, nbytes, state);
	case GN_CT_Irda:
		return irda_read(state->device.fd, buf, nbytes, state);
	case GN_CT_Bluetooth:
		return bluetooth_read(state->device.fd, buf, nbytes, state);
	case GN_CT_Tekram:
		return tekram_read(state->device.fd, buf, nbytes, state);
	case GN_CT_TCP:
		return tcp_read(state->device.fd, buf, nbytes, state);
	case GN_CT_DKU2LIBUSB:
		return fbusdku2usb_read(buf, nbytes, state);
	case GN_CT_SOCKETPHONET:
		return socketphonet_read(state->device.fd, buf, nbytes, state);
	default:
		break;
	}
	return 0;
}
/*
 * Set the IrDA communications speed.
 */
static int au1k_irda_set_speed(struct net_device *dev, int speed)
{
	struct au1k_private *aup = netdev_priv(dev);
	volatile struct ring_dest *ptxd;
	unsigned long control;
	int ret = 0, timeout = 10, i;

	if (speed == aup->speed)
		return ret;

	/* disable PHY first */
	au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
	irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);

	/* disable RX/TX */
	irda_write(aup, IR_CONFIG_1,
	    irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE));
	msleep(20);
	while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) {
		msleep(20);
		if (!timeout--) {
			printk(KERN_ERR "%s: rx/tx disable timeout\n",
					dev->name);
			break;
		}
	}

	/* disable DMA */
	irda_write(aup, IR_CONFIG_1,
		   irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE);
	msleep(20);

	/* After we disable tx/rx. the index pointers go back to zero. */
	aup->tx_head = aup->tx_tail = aup->rx_head = 0;
	for (i = 0; i < NUM_IR_DESC; i++) {
		ptxd = aup->tx_ring[i];
		ptxd->flags = 0;
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
	}

	for (i = 0; i < NUM_IR_DESC; i++) {
		ptxd = aup->rx_ring[i];
		ptxd->count_0 = 0;
		ptxd->count_1 = 0;
		ptxd->flags = AU_OWN;
	}

	if (speed == 4000000)
		au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR);
	else
		au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);

	switch (speed) {
	case 9600:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 19200:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 38400:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(2) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 57600:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(1) | IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 115200:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_PW(12));
		irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
		break;
	case 4000000:
		irda_write(aup, IR_WRITE_PHY_CONFIG, IR_P(15));
		irda_write(aup, IR_CONFIG_1, IR_FIR | IR_DMA_ENABLE |
				IR_RX_ENABLE);
		break;
	default:
		printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
		ret = -EINVAL;
		break;
	}

	aup->speed = speed;
	irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) | IR_PHYEN);

	control = irda_read(aup, IR_STATUS);
	irda_write(aup, IR_RING_PROMPT, 0);

	if (control & (1 << 14)) {
		printk(KERN_ERR "%s: configuration error\n", dev->name);
	} else {
		if (control & (1 << 11))
			printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
		if (control & (1 << 12))
			printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
		if (control & (1 << 13))
			printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
		if (control & (1 << 10))
			printk(KERN_DEBUG "%s TX enabled\n", dev->name);
		if (control & (1 << 9))
			printk(KERN_DEBUG "%s RX enabled\n", dev->name);
	}

	return ret;
}