---- linux-2.6.27.5/drivers/net/korina.c 2008-11-07 18:55:34.000000000 +0100
-+++ ../build_dir/linux-rb532/linux-2.6.27.5/drivers/net/korina.c 2008-11-16 00:38:19.000000000 +0100
-@@ -327,12 +327,11 @@
-
- dmas = readl(&lp->rx_dma_regs->dmas);
- if (dmas & (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR)) {
-- netif_rx_schedule_prep(dev, &lp->napi);
--
- dmasm = readl(&lp->rx_dma_regs->dmasm);
- writel(dmasm | (DMA_STAT_DONE |
- DMA_STAT_HALT | DMA_STAT_ERR),
- &lp->rx_dma_regs->dmasm);
-+ netif_rx_schedule(dev, &lp->napi);
-
- if (dmas & DMA_STAT_ERR)
- printk(KERN_ERR DRV_NAME "%s: DMA error\n", dev->name);
-@@ -350,14 +349,24 @@
- 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, pktuncrc_len;
- int count;
-
- dma_cache_inv((u32)rd, sizeof(*rd));
-
- for (count = 0; count < limit; count++) {
--
-+ skb_new = NULL;
- devcs = rd->devcs;
-+ pkt_len = RCVPKT_LENGTH(devcs);
-+ skb = lp->rx_skb[lp->rx_next_done];
-+
-+ if ((devcs & ETH_RX_LD) != ETH_RX_LD) {
-+ /* check that this is a whole packet
-+ * WARNING: DMA_FD bit incorrectly set
-+ * in Rc32434 (errata ref #077) */
-+ dev->stats.rx_errors++;
-+ dev->stats.rx_dropped++;
-+ }
-
- /* Update statistics counters */
- if (devcs & ETH_RX_CRC)
-@@ -375,75 +384,79 @@
- if (devcs & ETH_RX_MP)
- dev->stats.multicast++;
-
-- if ((devcs & ETH_RX_LD) != ETH_RX_LD) {
-- /* check that this is a whole packet
-- * WARNING: DMA_FD bit incorrectly set
-- * 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;
-- pkt_len = RCVPKT_LENGTH(devcs);
-- skb = lp->rx_skb[lp->rx_next_done];
--
-- if ((devcs & ETH_RX_ROK)) {
-- /* must be the (first and) last
-- * descriptor then */
-- pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data;
-+ else if ((devcs & ETH_RX_ROK)) {
-+ /* must be the (first and) last
-+ * descriptor then */
-+ pkt_buf = (u8 *)lp->rx_skb[lp->rx_next_done]->data;
-+ pktuncrc_len = pkt_len - 4;
-
-- /* invalidate the cache */
-- dma_cache_inv((unsigned long)pkt_buf, pkt_len - 4);
-+ /* invalidate the cache */
-+ dma_cache_inv((unsigned long)pkt_buf, pktuncrc_len);
-
-- /* Malloc up new buffer. */
-- skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2);
-+ /* Malloc up new buffer. */
-+ skb_new = netdev_alloc_skb(dev, KORINA_RBSIZE + 2);
-
-- if (!skb_new)
-- break;
-+ if (skb_new) {
- /* Do not count the CRC */
-- skb_put(skb, pkt_len - 4);
-+ skb_put(skb, pktuncrc_len);
- 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++;
--
-+ dev->stats.rx_bytes += pktuncrc_len;
-+
- lp->rx_skb[lp->rx_next_done] = skb_new;
-+ } else {
-+ dev->stats.rx_errors++;
-+ dev->stats.rx_dropped++;
- }
-+ } else {
-+ dev->stats.rx_errors++;
-+ dev->stats.rx_dropped++;
-+
-+ /* Update statistics counters */
-+ if (devcs & ETH_RX_CRC)
-+ dev->stats.rx_crc_errors++;
-+ else if (devcs & ETH_RX_LOR)
-+ dev->stats.rx_length_errors++;
-+ else if (devcs & ETH_RX_LE)
-+ dev->stats.rx_length_errors++;
-+ else if (devcs & ETH_RX_OVR)
-+ dev->stats.rx_over_errors++;
-+ else if (devcs & ETH_RX_CV)
-+ dev->stats.rx_frame_errors++;
-+ else if (devcs & ETH_RX_CES)
-+ dev->stats.rx_length_errors++;
-+ else if (devcs & ETH_RX_MP)
-+ dev->stats.multicast++;
-+ }
-
-- rd->devcs = 0;
-+ rd->devcs = 0;
-
-- /* Restore descriptor's curr_addr */
-- if (skb_new)
-- rd->ca = CPHYSADDR(skb_new->data);
-- else
-- rd->ca = CPHYSADDR(skb->data);
-+ /* 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);
-
- if (dmas & DMA_STAT_HALT) {
-+ /* Mask off halt and errors bits */
- writel(~(DMA_STAT_HALT | DMA_STAT_ERR),
- &lp->rx_dma_regs->dmas);
-
-@@ -469,8 +482,9 @@
- if (work_done < budget) {
- netif_rx_complete(dev, napi);
-
-+ /* Mask off interrupts */
- writel(readl(&lp->rx_dma_regs->dmasm) &
-- ~(DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
-+ (DMA_STAT_DONE | DMA_STAT_HALT | DMA_STAT_ERR),
- &lp->rx_dma_regs->dmasm);
- }
- return work_done;
-@@ -534,10 +548,11 @@
- {
- struct korina_private *lp = netdev_priv(dev);
- struct dma_desc *td = &lp->td_ring[lp->tx_next_done];
-+ unsigned long flags;
- u32 devcs;
- u32 dmas;
-
-- spin_lock(&lp->lock);
-+ spin_lock_irqsave(&lp->lock, flags);
-
- /* Process all desc that are done */
- while (IS_DMA_FINISHED(td->control)) {
-@@ -610,7 +625,7 @@
- ~(DMA_STAT_FINI | DMA_STAT_ERR),
- &lp->tx_dma_regs->dmasm);
-
-- spin_unlock(&lp->lock);
-+ spin_unlock_irqrestore(&lp->lock, flags);
- }
-
- static irqreturn_t
-@@ -624,11 +639,10 @@
- dmas = readl(&lp->tx_dma_regs->dmas);
-
- if (dmas & (DMA_STAT_FINI | DMA_STAT_ERR)) {
-- korina_tx(dev);
--
- dmasm = readl(&lp->tx_dma_regs->dmasm);
- writel(dmasm | (DMA_STAT_FINI | DMA_STAT_ERR),
- &lp->tx_dma_regs->dmasm);
-+ korina_tx(dev);
-
- if (lp->tx_chain_status == desc_filled &&
- (readl(&(lp->tx_dma_regs->dmandptr)) == 0)) {
-@@ -1078,11 +1092,18 @@
-
- static int korina_probe(struct platform_device *pdev)
- {
-- struct korina_device *bif = platform_get_drvdata(pdev);
-+ struct korina_device *bif;
- struct korina_private *lp;
- struct net_device *dev;
- struct resource *r;
- int rc;
-+ DECLARE_MAC_BUF(mac);
-+
-+ bif = (struct korina_device *)pdev->dev.platform_data;
-+ if (!bif) {
-+ printk(KERN_ERR DRV_NAME ": missing platform_data\n");
-+ return -ENODEV;
-+ }
-
- dev = alloc_etherdev(sizeof(struct korina_private));
- if (!dev) {
-@@ -1172,6 +1193,7 @@
- ": cannot register net device %d\n", rc);
- goto probe_err_register;
- }
-+ printk(KERN_INFO DRV_NAME ": registered %s, IRQ %d MAC %s\n", dev->name, dev->irq, print_mac(mac, dev->dev_addr));
- out:
- return rc;
-