Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d26db13 authored by Russell King's avatar Russell King
Browse files

NET: sa11x0-ir: split SIR and FIR tx functions



Split the SIR and FIR transmit functions, as they behave differently.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 0e888ee3
Loading
Loading
Loading
Loading
+66 −52
Original line number Original line Diff line number Diff line
@@ -68,6 +68,8 @@ struct sa1100_irda {


	iobuff_t		tx_buff;
	iobuff_t		tx_buff;
	iobuff_t		rx_buff;
	iobuff_t		rx_buff;

	int (*tx_start)(struct sk_buff *, struct net_device *, struct sa1100_irda *);
};
};


static int sa1100_irda_set_speed(struct sa1100_irda *, int);
static int sa1100_irda_set_speed(struct sa1100_irda *, int);
@@ -139,6 +141,63 @@ static void sa1100_irda_check_speed(struct sa1100_irda *si)
	}
	}
}
}


/*
 * HP-SIR format support.
 */
static int sa1100_irda_sir_tx_start(struct sk_buff *skb, struct net_device *dev,
	struct sa1100_irda *si)
{
	si->tx_buff.data = si->tx_buff.head;
	si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data,
					  si->tx_buff.truesize);

	/*
	 * Set the transmit interrupt enable.  This will fire off an
	 * interrupt immediately.  Note that we disable the receiver
	 * so we won't get spurious characters received.
	 */
	Ser2UTCR3 = UTCR3_TIE | UTCR3_TXE;

	dev_kfree_skb(skb);

	return NETDEV_TX_OK;
}

/*
 * FIR format support.
 */
static int sa1100_irda_fir_tx_start(struct sk_buff *skb, struct net_device *dev,
	struct sa1100_irda *si)
{
	int mtt = irda_get_mtt(skb);

	si->dma_tx.skb = skb;
	si->dma_tx.dma = dma_map_single(si->dev, skb->data, skb->len,
					DMA_TO_DEVICE);
	if (dma_mapping_error(si->dev, si->dma_tx.dma)) {
		si->dma_tx.skb = NULL;
		netif_wake_queue(dev);
		dev->stats.tx_dropped++;
		dev_kfree_skb(skb);
		return NETDEV_TX_OK;
	}

	sa1100_start_dma(si->dma_tx.regs, si->dma_tx.dma, skb->len);

	/*
	 * If we have a mean turn-around time, impose the specified
	 * specified delay.  We could shorten this by timing from
	 * the point we received the packet.
	 */
	if (mtt)
		udelay(mtt);

	Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;

	return NETDEV_TX_OK;
}


/*
/*
 * Set the IrDA communications speed.
 * Set the IrDA communications speed.
 */
 */
@@ -176,6 +235,7 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
			si->pdata->set_speed(si->dev, speed);
			si->pdata->set_speed(si->dev, speed);


		si->speed = speed;
		si->speed = speed;
		si->tx_start = sa1100_irda_sir_tx_start;


		local_irq_restore(flags);
		local_irq_restore(flags);
		ret = 0;
		ret = 0;
@@ -191,6 +251,7 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
		Ser2UTCR3 = 0;
		Ser2UTCR3 = 0;


		si->speed = speed;
		si->speed = speed;
		si->tx_start = sa1100_irda_fir_tx_start;


		if (si->pdata->set_speed)
		if (si->pdata->set_speed)
			si->pdata->set_speed(si->dev, speed);
			si->pdata->set_speed(si->dev, speed);
@@ -538,66 +599,19 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
	if (speed != si->speed && speed != -1)
	if (speed != si->speed && speed != -1)
		si->newspeed = speed;
		si->newspeed = speed;


	/*
	/* If this is an empty frame, we can bypass a lot. */
	 * If this is an empty frame, we can bypass a lot.
	 */
	if (skb->len == 0) {
	if (skb->len == 0) {
		sa1100_irda_check_speed(si);
		sa1100_irda_check_speed(si);
		dev_kfree_skb(skb);
		dev_kfree_skb(skb);
		return NETDEV_TX_OK;
		return NETDEV_TX_OK;
	}
	}


	if (!IS_FIR(si)) {
	netif_stop_queue(dev);
	netif_stop_queue(dev);


		si->tx_buff.data = si->tx_buff.head;
	/* We must not already have a skb to transmit... */
		si->tx_buff.len  = async_wrap_skb(skb, si->tx_buff.data,
						  si->tx_buff.truesize);

		/*
		 * Set the transmit interrupt enable.  This will fire
		 * off an interrupt immediately.  Note that we disable
		 * the receiver so we won't get spurious characteres
		 * received.
		 */
		Ser2UTCR3 = UTCR3_TIE | UTCR3_TXE;

		dev_kfree_skb(skb);
	} else {
		int mtt = irda_get_mtt(skb);

		/*
		 * We must not be transmitting...
		 */
	BUG_ON(si->dma_tx.skb);
	BUG_ON(si->dma_tx.skb);


		netif_stop_queue(dev);
	return si->tx_start(skb, dev, si);

		si->dma_tx.skb = skb;
		si->dma_tx.dma = dma_map_single(si->dev, skb->data,
					 skb->len, DMA_TO_DEVICE);
		if (dma_mapping_error(si->dev, si->dma_tx.dma)) {
			si->dma_tx.skb = NULL;
			netif_wake_queue(dev);
			dev->stats.tx_dropped++;
			dev_kfree_skb(skb);
			return NETDEV_TX_OK;
		}

		sa1100_start_dma(si->dma_tx.regs, si->dma_tx.dma, skb->len);

		/*
		 * If we have a mean turn-around time, impose the specified
		 * specified delay.  We could shorten this by timing from
		 * the point we received the packet.
		 */
		if (mtt)
			udelay(mtt);

		Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
	}

	return NETDEV_TX_OK;
}
}


static int
static int