]> err.no Git - linux-2.6/commitdiff
pasemi_mac: Logic cleanup / rx performance improvements
authorOlof Johansson <olof@lixom.net>
Tue, 8 May 2007 05:47:45 +0000 (00:47 -0500)
committerJeff Garzik <jeff@garzik.org>
Tue, 8 May 2007 05:47:54 +0000 (01:47 -0400)
Logic cleanup and some performance enhancements to the RX path.

Signed-off-by: Olof Johansson <olof@lixom.net>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/net/pasemi_mac.c

index f18fd07973b18d523ef77d8fe1f4f37cb6205083..6b4e925aa7f1e7df0f82db350ca21e7059dc7cdf 100644 (file)
@@ -305,19 +305,20 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
        struct pasemi_mac *mac = netdev_priv(dev);
        unsigned int i;
        int start = mac->rx->next_to_fill;
-       unsigned int count;
+       unsigned int limit, count;
 
-       count = (mac->rx->next_to_clean + RX_RING_SIZE -
+       limit = (mac->rx->next_to_clean + RX_RING_SIZE -
                 mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
 
        /* Check to see if we're doing first-time setup */
        if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
-               count = RX_RING_SIZE;
+               limit = RX_RING_SIZE;
 
-       if (count <= 0)
+       if (limit <= 0)
                return;
 
-       for (i = start; i < start + count; i++) {
+       i = start;
+       for (count = limit; count; count--) {
                struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
                u64 *buff = &RX_BUFF(mac, i);
                struct sk_buff *skb;
@@ -335,27 +336,27 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
                dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
                                     PCI_DMA_FROMDEVICE);
 
-               if (dma_mapping_error(dma)) {
+               if (unlikely(dma_mapping_error(dma))) {
                        dev_kfree_skb_irq(info->skb);
-                       count = i - start;
                        break;
                }
 
                info->skb = skb;
                info->dma = dma;
                *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
+               i++;
        }
 
        wmb();
 
        pci_write_config_dword(mac->dma_pdev,
                               PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
-                              count);
+                              limit - count);
        pci_write_config_dword(mac->dma_pdev,
                               PAS_DMA_RXINT_INCR(mac->dma_if),
-                              count);
+                              limit - count);
 
-       mac->rx->next_to_fill += count;
+       mac->rx->next_to_fill += limit - count;
 }
 
 static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
@@ -393,32 +394,31 @@ static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
 }
 
 
-
 static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 {
-       unsigned int i;
-       int start, count;
+       unsigned int n;
+       int count;
+       struct pas_dma_xct_descr *dp;
+       struct pasemi_mac_buffer *info;
+       struct sk_buff *skb;
+       unsigned int i, len;
+       u64 macrx;
+       dma_addr_t dma;
 
        spin_lock(&mac->rx->lock);
 
-       start = mac->rx->next_to_clean;
-       count = 0;
+       n = mac->rx->next_to_clean;
 
-       for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) {
-               struct pas_dma_xct_descr *dp;
-               struct pasemi_mac_buffer *info;
-               struct sk_buff *skb;
-               unsigned int j, len;
-               dma_addr_t dma;
+       for (count = limit; count; count--) {
 
                rmb();
 
-               dp = &RX_DESC(mac, i);
+               dp = &RX_DESC(mac, n);
+               macrx = dp->macrx;
 
-               if (!(dp->macrx & XCT_MACRX_O))
+               if (!(macrx & XCT_MACRX_O))
                        break;
 
-               count++;
 
                info = NULL;
 
@@ -430,22 +430,20 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
                 */
 
                dma = (dp->ptr & XCT_PTR_ADDR_M);
-               for (j = start; j < (start + RX_RING_SIZE); j++) {
-                       info = &RX_DESC_INFO(mac, j);
+               for (i = n; i < (n + RX_RING_SIZE); i++) {
+                       info = &RX_DESC_INFO(mac, i);
                        if (info->dma == dma)
                                break;
                }
 
-               BUG_ON(!info);
-               BUG_ON(info->dma != dma);
                skb = info->skb;
+               info->dma = 0;
 
-               pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len,
+               pci_unmap_single(mac->dma_pdev, dma, skb->len,
                                 PCI_DMA_FROMDEVICE);
-               info->dma = 0;
 
+               len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
 
-               len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
                if (len < 256) {
                        struct sk_buff *new_skb =
                            netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
@@ -465,9 +463,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
                skb->protocol = eth_type_trans(skb, mac->netdev);
 
-               if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
+               if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
                        skb->ip_summed = CHECKSUM_COMPLETE;
-                       skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >>
+                       skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
                                           XCT_MACRX_CSUM_S;
                } else
                        skb->ip_summed = CHECKSUM_NONE;
@@ -477,13 +475,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
                netif_receive_skb(skb);
 
-               info->dma = 0;
-               info->skb = NULL;
                dp->ptr = 0;
                dp->macrx = 0;
+
+               n++;
        }
 
-       mac->rx->next_to_clean += count;
+       mac->rx->next_to_clean += limit - count;
        pasemi_mac_replenish_rx_ring(mac->netdev);
 
        spin_unlock(&mac->rx->lock);
@@ -899,6 +897,9 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
 
        pkts = pasemi_mac_clean_rx(mac, limit);
 
+       dev->quota -= pkts;
+       *budget -= pkts;
+
        if (pkts < limit) {
                /* all done, no more packets present */
                netif_rx_complete(dev);
@@ -907,8 +908,6 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
                return 0;
        } else {
                /* used up our quantum, so reschedule */
-               dev->quota -= pkts;
-               *budget -= pkts;
                return 1;
        }
 }