pcnet32: fix reallocation error
authorDon Fry <pcnet32@frontier.com>
Tue, 18 Feb 2014 04:57:46 +0000 (20:57 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 19 Feb 2014 19:58:26 +0000 (14:58 -0500)
pcnet32_realloc_rx_ring() only worked on the first log2 number of
entries in the receive ring instead of the all the entries.
Replaced "1 << size" with more descriptive variable.
This is my original bug from 2006.  Found while testing another problem.
Tested on 79C972 and 79C976.

Signed-off-by: Don Fry <pcnet32@frontier.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/amd/pcnet32.c

index 9339cccfe05a35977493a0fbaf766b91f49f8acb..25cd04a78eec4b325a64921a86600147d21b586d 100644 (file)
@@ -549,35 +549,36 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
        struct pcnet32_rx_head *new_rx_ring;
        struct sk_buff **new_skb_list;
        int new, overlap;
+       unsigned int entries = 1 << size;
 
        new_rx_ring = pci_alloc_consistent(lp->pci_dev,
                                           sizeof(struct pcnet32_rx_head) *
-                                          (1 << size),
+                                          entries,
                                           &new_ring_dma_addr);
        if (new_rx_ring == NULL) {
                netif_err(lp, drv, dev, "Consistent memory allocation failed\n");
                return;
        }
-       memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * (1 << size));
+       memset(new_rx_ring, 0, sizeof(struct pcnet32_rx_head) * entries);
 
-       new_dma_addr_list = kcalloc(1 << size, sizeof(dma_addr_t), GFP_ATOMIC);
+       new_dma_addr_list = kcalloc(entries, sizeof(dma_addr_t), GFP_ATOMIC);
        if (!new_dma_addr_list)
                goto free_new_rx_ring;
 
-       new_skb_list = kcalloc(1 << size, sizeof(struct sk_buff *),
+       new_skb_list = kcalloc(entries, sizeof(struct sk_buff *),
                               GFP_ATOMIC);
        if (!new_skb_list)
                goto free_new_lists;
 
        /* first copy the current receive buffers */
-       overlap = min(size, lp->rx_ring_size);
+       overlap = min(entries, lp->rx_ring_size);
        for (new = 0; new < overlap; new++) {
                new_rx_ring[new] = lp->rx_ring[new];
                new_dma_addr_list[new] = lp->rx_dma_addr[new];
                new_skb_list[new] = lp->rx_skbuff[new];
        }
        /* now allocate any new buffers needed */
-       for (; new < size; new++) {
+       for (; new < entries; new++) {
                struct sk_buff *rx_skbuff;
                new_skb_list[new] = netdev_alloc_skb(dev, PKT_BUF_SKB);
                rx_skbuff = new_skb_list[new];
@@ -612,7 +613,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
                            lp->rx_ring_size, lp->rx_ring,
                            lp->rx_ring_dma_addr);
 
-       lp->rx_ring_size = (1 << size);
+       lp->rx_ring_size = entries;
        lp->rx_mod_mask = lp->rx_ring_size - 1;
        lp->rx_len_bits = (size << 4);
        lp->rx_ring = new_rx_ring;
@@ -634,8 +635,7 @@ free_new_lists:
        kfree(new_dma_addr_list);
 free_new_rx_ring:
        pci_free_consistent(lp->pci_dev,
-                           sizeof(struct pcnet32_rx_head) *
-                           (1 << size),
+                           sizeof(struct pcnet32_rx_head) * entries,
                            new_rx_ring,
                            new_ring_dma_addr);
 }