Signed-off-by: Roman Yeryomin <ro...@advem.lv> --- drivers/net/ethernet/korina.c | 76 ++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index 7cecd9dbc111..84b2654e2d06 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -200,8 +200,7 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) { struct korina_private *lp = netdev_priv(dev); unsigned long flags; - u32 length; - u32 chain_prev, chain_next; + u32 chain_prev, chain_next, dmandptr; struct dma_desc *td; spin_lock_irqsave(&lp->lock, flags); @@ -211,10 +210,9 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) /* stop queue when full, drop pkts if queue already full */ if (lp->tx_count >= (KORINA_NUM_TDS - 2)) { lp->tx_full = 1; + netif_stop_queue(dev); - if (lp->tx_count == (KORINA_NUM_TDS - 2)) - netif_stop_queue(dev); - else { + if (lp->tx_count > (KORINA_NUM_TDS - 2)) { dev->stats.tx_dropped++; dev_kfree_skb_any(skb); spin_unlock_irqrestore(&lp->lock, flags); @@ -224,66 +222,40 @@ static int korina_send_packet(struct sk_buff *skb, struct net_device *dev) } lp->tx_count++; - lp->tx_skb[lp->tx_chain_tail] = skb; - length = skb->len; dma_cache_wback((u32)skb->data, skb->len); /* Setup the transmit descriptor. */ dma_cache_inv((u32) td, sizeof(*td)); + td->ca = CPHYSADDR(skb->data); chain_prev = (lp->tx_chain_tail - 1) & KORINA_TDS_MASK; chain_next = (lp->tx_chain_tail + 1) & KORINA_TDS_MASK; - if (readl(&(lp->tx_dma_regs->dmandptr)) == 0) { - if (lp->tx_chain_status == desc_empty) { - /* Update tail */ - td->control = DMA_COUNT(length) | - DMA_DESC_COF | DMA_DESC_IOF; - /* Move tail */ - lp->tx_chain_tail = chain_next; - /* Write to NDPTR */ - writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), + dmandptr = readl(&(lp->tx_dma_regs->dmandptr)); + /* Update tail */ + td->control = DMA_COUNT(skb->len) | DMA_DESC_COF | DMA_DESC_IOF; + /* Move tail */ + lp->tx_chain_tail = chain_next; + + if (lp->tx_chain_status != desc_empty) { + /* Link to prev */ + lp->td_ring[chain_prev].control &= ~DMA_DESC_COF; + lp->td_ring[chain_prev].link = CPHYSADDR(td); + } + + if (!dmandptr) { + /* Write to NDPTR */ + writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), &lp->tx_dma_regs->dmandptr); - /* Move head to tail */ - lp->tx_chain_head = lp->tx_chain_tail; - } else { - /* Update tail */ - td->control = DMA_COUNT(length) | - DMA_DESC_COF | DMA_DESC_IOF; - /* Link to prev */ - lp->td_ring[chain_prev].control &= - ~DMA_DESC_COF; - /* Link to prev */ - lp->td_ring[chain_prev].link = CPHYSADDR(td); - /* Move tail */ - lp->tx_chain_tail = chain_next; - /* Write to NDPTR */ - writel(CPHYSADDR(&lp->td_ring[lp->tx_chain_head]), - &(lp->tx_dma_regs->dmandptr)); - /* Move head to tail */ - lp->tx_chain_head = lp->tx_chain_tail; - lp->tx_chain_status = desc_empty; - } + /* Move head to tail */ + lp->tx_chain_head = lp->tx_chain_tail; + lp->tx_chain_status = desc_empty; } else { - if (lp->tx_chain_status == desc_empty) { - /* Update tail */ - td->control = DMA_COUNT(length) | - DMA_DESC_COF | DMA_DESC_IOF; - /* Move tail */ - lp->tx_chain_tail = chain_next; - lp->tx_chain_status = desc_filled; - } else { - /* Update tail */ - td->control = DMA_COUNT(length) | - DMA_DESC_COF | DMA_DESC_IOF; - lp->td_ring[chain_prev].control &= - ~DMA_DESC_COF; - lp->td_ring[chain_prev].link = CPHYSADDR(td); - lp->tx_chain_tail = chain_next; - } + lp->tx_chain_status = desc_filled; } + dma_cache_wback((u32) td, sizeof(*td)); netif_trans_update(dev); -- 2.11.0