diff options
| -rw-r--r-- | drivers/net/pasemi_mac.c | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 2bf13cf55358..216bb4a2c633 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c | |||
| @@ -279,8 +279,8 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev) | |||
| 279 | for (i = 0; i < RX_RING_SIZE; i++) { | 279 | for (i = 0; i < RX_RING_SIZE; i++) { |
| 280 | info = &RX_DESC_INFO(mac, i); | 280 | info = &RX_DESC_INFO(mac, i); |
| 281 | dp = &RX_DESC(mac, i); | 281 | dp = &RX_DESC(mac, i); |
| 282 | if (info->dma) { | 282 | if (info->skb) { |
| 283 | if (info->skb) { | 283 | if (info->dma) { |
| 284 | pci_unmap_single(mac->dma_pdev, | 284 | pci_unmap_single(mac->dma_pdev, |
| 285 | info->dma, | 285 | info->dma, |
| 286 | info->skb->len, | 286 | info->skb->len, |
| @@ -329,12 +329,14 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) | |||
| 329 | struct sk_buff *skb; | 329 | struct sk_buff *skb; |
| 330 | dma_addr_t dma; | 330 | dma_addr_t dma; |
| 331 | 331 | ||
| 332 | skb = dev_alloc_skb(BUF_SIZE); | 332 | /* skb might still be in there for recycle on short receives */ |
| 333 | if (info->skb) | ||
| 334 | skb = info->skb; | ||
| 335 | else | ||
| 336 | skb = dev_alloc_skb(BUF_SIZE); | ||
| 333 | 337 | ||
| 334 | if (!skb) { | 338 | if (unlikely(!skb)) |
| 335 | count = i - start; | ||
| 336 | break; | 339 | break; |
| 337 | } | ||
| 338 | 340 | ||
| 339 | dma = pci_map_single(mac->dma_pdev, skb->data, skb->len, | 341 | dma = pci_map_single(mac->dma_pdev, skb->data, skb->len, |
| 340 | PCI_DMA_FROMDEVICE); | 342 | PCI_DMA_FROMDEVICE); |
| @@ -442,13 +444,28 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) | |||
| 442 | 444 | ||
| 443 | BUG_ON(!info); | 445 | BUG_ON(!info); |
| 444 | BUG_ON(info->dma != dma); | 446 | BUG_ON(info->dma != dma); |
| 447 | skb = info->skb; | ||
| 445 | 448 | ||
| 446 | pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, | 449 | pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, |
| 447 | PCI_DMA_FROMDEVICE); | 450 | PCI_DMA_FROMDEVICE); |
| 451 | info->dma = 0; | ||
| 448 | 452 | ||
| 449 | skb = info->skb; | ||
| 450 | 453 | ||
| 451 | len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; | 454 | len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; |
| 455 | if (len < 256) { | ||
| 456 | struct sk_buff *new_skb = | ||
| 457 | netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN); | ||
| 458 | if (new_skb) { | ||
| 459 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
| 460 | memcpy(new_skb->data - NET_IP_ALIGN, | ||
| 461 | skb->data - NET_IP_ALIGN, | ||
| 462 | len + NET_IP_ALIGN); | ||
| 463 | /* save the skb in buffer_info as good */ | ||
| 464 | skb = new_skb; | ||
| 465 | } | ||
| 466 | /* else just continue with the old one */ | ||
| 467 | } else | ||
| 468 | info->skb = NULL; | ||
| 452 | 469 | ||
| 453 | skb_put(skb, len); | 470 | skb_put(skb, len); |
| 454 | 471 | ||
