From 499fa7f7a12864f7d9637b52dbc23c6cb572243e Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Sun, 15 Mar 2009 12:56:39 +0000 Subject: add 2.6.28 patches and kernel config SVN-Revision: 14884 --- .../010-korina_rework_korina_rx.patch | 138 +++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 target/linux/rb532/patches-2.6.28/010-korina_rework_korina_rx.patch (limited to 'target/linux/rb532/patches-2.6.28/010-korina_rework_korina_rx.patch') diff --git a/target/linux/rb532/patches-2.6.28/010-korina_rework_korina_rx.patch b/target/linux/rb532/patches-2.6.28/010-korina_rework_korina_rx.patch new file mode 100644 index 0000000..177678b --- /dev/null +++ b/target/linux/rb532/patches-2.6.28/010-korina_rework_korina_rx.patch @@ -0,0 +1,138 @@ +This function needs an early exit condition to function properly, or +else caller assumes napi workload wasn't enough to handle all received +packets and korina_rx is called again (and again and again and ...). + +Signed-off-by: Phil Sutter +--- +--- a/drivers/net/korina.c 2009-01-19 23:19:10.000000000 +0100 ++++ b/drivers/net/korina.c 2009-01-19 23:25:31.000000000 +0100 +@@ -353,15 +353,20 @@ + struct dma_desc *rd = &lp->rd_ring[lp->rx_next_done]; + struct sk_buff *skb, *skb_new; + u8 *pkt_buf; +- u32 devcs, pkt_len, dmas, rx_free_desc; ++ u32 devcs, pkt_len, dmas; + int count; + + dma_cache_inv((u32)rd, sizeof(*rd)); + + for (count = 0; count < limit; count++) { ++ skb = lp->rx_skb[lp->rx_next_done]; ++ skb_new = NULL; + + devcs = rd->devcs; + ++ if ((KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) == 0) ++ break; ++ + /* Update statistics counters */ + if (devcs & ETH_RX_CRC) + dev->stats.rx_crc_errors++; +@@ -384,64 +389,53 @@ + * in Rc32434 (errata ref #077) */ + dev->stats.rx_errors++; + dev->stats.rx_dropped++; +- } +- +- while ((rx_free_desc = KORINA_RBSIZE - (u32)DMA_COUNT(rd->control)) != 0) { +- /* init the var. used for the later +- * operations within the while loop */ +- skb_new = NULL; ++ } else if ((devcs & ETH_RX_ROK)) { + pkt_len = RCVPKT_LENGTH(devcs); +- skb = lp->rx_skb[lp->rx_next_done]; ++ /* must be the (first and) last ++ * descriptor then */ ++ pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data; ++ ++ /* invalidate the cache */ ++ dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4); ++ ++ /* Malloc up new buffer. */ ++ skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2); ++ ++ if (!skb_new) ++ break; ++ /* Do not count the CRC */ ++ skb_put(skb, pkt_len - 4); ++ skb->protocol = eth_type_trans(skb, dev); ++ ++ /* Pass the packet to upper layers */ ++ netif_receive_skb(skb); ++ dev->stats.rx_packets++; ++ dev->stats.rx_bytes += pkt_len; ++ ++ /* Update the mcast stats */ ++ if (devcs & ETH_RX_MP) ++ dev->stats.multicast++; + +- if ((devcs & ETH_RX_ROK)) { +- /* must be the (first and) last +- * descriptor then */ +- pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data; +- +- /* invalidate the cache */ +- dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4); +- +- /* Malloc up new buffer. */ +- skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2); +- +- if (!skb_new) +- break; +- /* Do not count the CRC */ +- skb_put(skb, pkt_len - 4); +- skb->protocol = eth_type_trans(skb, dev); +- +- /* Pass the packet to upper layers */ +- netif_receive_skb(skb); +- dev->last_rx = jiffies; +- dev->stats.rx_packets++; +- dev->stats.rx_bytes += pkt_len; +- +- /* Update the mcast stats */ +- if (devcs & ETH_RX_MP) +- dev->stats.multicast++; +- +- lp->rx_skb[lp->rx_next_done] = skb_new; +- } +- +- rd->devcs = 0; +- +- /* Restore descriptor's curr_addr */ +- if (skb_new) +- rd->ca = CPHYSADDR(skb_new->data); +- else +- rd->ca = CPHYSADDR(skb->data); ++ lp->rx_skb[lp->rx_next_done] = skb_new; ++ } ++ rd->devcs = 0; ++ ++ /* Restore descriptor's curr_addr */ ++ if (skb_new) ++ rd->ca = CPHYSADDR(skb_new->data); ++ else ++ rd->ca = CPHYSADDR(skb->data); + +- rd->control = DMA_COUNT(KORINA_RBSIZE) | ++ rd->control = DMA_COUNT(KORINA_RBSIZE) | + DMA_DESC_COD | DMA_DESC_IOD; +- lp->rd_ring[(lp->rx_next_done - 1) & +- KORINA_RDS_MASK].control &= +- ~DMA_DESC_COD; +- +- lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK; +- dma_cache_wback((u32)rd, sizeof(*rd)); +- rd = &lp->rd_ring[lp->rx_next_done]; +- writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas); +- } ++ lp->rd_ring[(lp->rx_next_done - 1) & ++ KORINA_RDS_MASK].control &= ++ ~DMA_DESC_COD; ++ ++ lp->rx_next_done = (lp->rx_next_done + 1) & KORINA_RDS_MASK; ++ dma_cache_wback((u32)rd, sizeof(*rd)); ++ rd = &lp->rd_ring[lp->rx_next_done]; ++ writel(~DMA_STAT_DONE, &lp->rx_dma_regs->dmas); + } + + dmas = readl(&lp->rx_dma_regs->dmas); -- cgit v1.1