Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 296322
b: refs/heads/master
c: 3d26db1
h: refs/heads/master
v: v3
  • Loading branch information
Russell King committed Feb 9, 2012
1 parent 5147fa7 commit ef871d0
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 53 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0e888ee31566c3f5071474ddd68457a7ad2ae5ac
refs/heads/master: 3d26db137ac3169623a132ea310d26af6a48bf88
118 changes: 66 additions & 52 deletions trunk/drivers/net/irda/sa1100_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ struct sa1100_irda {

iobuff_t tx_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);
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -176,6 +235,7 @@ static int sa1100_irda_set_speed(struct sa1100_irda *si, int speed)
si->pdata->set_speed(si->dev, speed);

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

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

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

if (si->pdata->set_speed)
si->pdata->set_speed(si->dev, speed);
Expand Down Expand Up @@ -538,66 +599,19 @@ static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
if (speed != si->speed && speed != -1)
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) {
sa1100_irda_check_speed(si);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}

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

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 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);

netif_stop_queue(dev);

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);
netif_stop_queue(dev);

Ser2HSCR0 = si->hscr0 | HSCR0_HSSP | HSCR0_TXE;
}
/* We must not already have a skb to transmit... */
BUG_ON(si->dma_tx.skb);

return NETDEV_TX_OK;
return si->tx_start(skb, dev, si);
}

static int
Expand Down

0 comments on commit ef871d0

Please sign in to comment.