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);
		}
	}
}
Esempio n. 2
0
/*
 * Au1000 transmit routine.
 */
static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct au1k_private *aup = (struct au1k_private *) dev->priv;
	int speed = irda_get_next_speed(skb);
	volatile ring_dest_t *ptxd;
	u32 len;

	u32 flags;
	db_dest_t *pDB;

	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 0;
	}

	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 (read_ir_reg(IR_RX_BYTE_CNT) != 0) {
		printk("tx warning: rx byte cnt %x\n", 
				read_ir_reg(IR_RX_BYTE_CNT));
	}
#endif
	
	if (aup->speed == 4000000) {
		/* FIR */
		memcpy((void *)pDB->vaddr, skb->data, skb->len);
		ptxd->count_0 = skb->len & 0xff;
		ptxd->count_1 = (skb->len >> 8) & 0xff;

	}
/*
 * 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 {
Esempio n. 4
0
static int au1k_init(struct net_device *dev)
{
	struct au1k_private *aup = (struct au1k_private *) dev->priv;
	int i;
	u32 control;
	u32 ring_address;

	/* bring the device out of reset */
	control = 0xe; /* coherent, clock enable, one half system clock */
			  
#ifndef CONFIG_CPU_LITTLE_ENDIAN
	control |= 1;
#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;
	}

	writel(control, IR_INTERFACE_CONFIG);
	au_sync_delay(10);

	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
	au_sync_delay(1);

	writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);

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

	writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);

	writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
	writel(0, IR_RING_ADDR_CMPR);

	au1k_irda_set_speed(dev, 9600);
	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;
}
Esempio n. 6
0
static void au1k_tx_ack(struct net_device *dev)
{
	struct au1k_private *aup = (struct au1k_private *) dev->priv;
	volatile ring_dest_t *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;
		au_sync();

		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 {
			writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE, 
					IR_CONFIG_1); 
			au_sync();
			writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE, 
					IR_CONFIG_1); 
			writel(0, IR_RING_PROMPT);
			au_sync();
		}
	}
}