diff options
-rw-r--r-- | drivers/net/e1000/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 56 |
2 files changed, 41 insertions, 16 deletions
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index a5665287bd64..2a567df3ea71 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h | |||
@@ -167,6 +167,7 @@ struct e1000_buffer { | |||
167 | unsigned long time_stamp; | 167 | unsigned long time_stamp; |
168 | u16 length; | 168 | u16 length; |
169 | u16 next_to_watch; | 169 | u16 next_to_watch; |
170 | u16 mapped_as_page; | ||
170 | }; | 171 | }; |
171 | 172 | ||
172 | struct e1000_tx_ring { | 173 | struct e1000_tx_ring { |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index c938114a34ab..b9d86f8b3fdb 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -1839,10 +1839,17 @@ void e1000_free_all_tx_resources(struct e1000_adapter *adapter) | |||
1839 | static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, | 1839 | static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, |
1840 | struct e1000_buffer *buffer_info) | 1840 | struct e1000_buffer *buffer_info) |
1841 | { | 1841 | { |
1842 | buffer_info->dma = 0; | 1842 | if (buffer_info->dma) { |
1843 | if (buffer_info->mapped_as_page) | ||
1844 | pci_unmap_page(adapter->pdev, buffer_info->dma, | ||
1845 | buffer_info->length, PCI_DMA_TODEVICE); | ||
1846 | else | ||
1847 | pci_unmap_single(adapter->pdev, buffer_info->dma, | ||
1848 | buffer_info->length, | ||
1849 | PCI_DMA_TODEVICE); | ||
1850 | buffer_info->dma = 0; | ||
1851 | } | ||
1843 | if (buffer_info->skb) { | 1852 | if (buffer_info->skb) { |
1844 | skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb, | ||
1845 | DMA_TO_DEVICE); | ||
1846 | dev_kfree_skb_any(buffer_info->skb); | 1853 | dev_kfree_skb_any(buffer_info->skb); |
1847 | buffer_info->skb = NULL; | 1854 | buffer_info->skb = NULL; |
1848 | } | 1855 | } |
@@ -2683,22 +2690,14 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
2683 | unsigned int mss) | 2690 | unsigned int mss) |
2684 | { | 2691 | { |
2685 | struct e1000_hw *hw = &adapter->hw; | 2692 | struct e1000_hw *hw = &adapter->hw; |
2693 | struct pci_dev *pdev = adapter->pdev; | ||
2686 | struct e1000_buffer *buffer_info; | 2694 | struct e1000_buffer *buffer_info; |
2687 | unsigned int len = skb_headlen(skb); | 2695 | unsigned int len = skb_headlen(skb); |
2688 | unsigned int offset, size, count = 0, i; | 2696 | unsigned int offset = 0, size, count = 0, i; |
2689 | unsigned int f; | 2697 | unsigned int f; |
2690 | dma_addr_t *map; | ||
2691 | 2698 | ||
2692 | i = tx_ring->next_to_use; | 2699 | i = tx_ring->next_to_use; |
2693 | 2700 | ||
2694 | if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) { | ||
2695 | dev_err(&adapter->pdev->dev, "TX DMA map failed\n"); | ||
2696 | return 0; | ||
2697 | } | ||
2698 | |||
2699 | map = skb_shinfo(skb)->dma_maps; | ||
2700 | offset = 0; | ||
2701 | |||
2702 | while (len) { | 2701 | while (len) { |
2703 | buffer_info = &tx_ring->buffer_info[i]; | 2702 | buffer_info = &tx_ring->buffer_info[i]; |
2704 | size = min(len, max_per_txd); | 2703 | size = min(len, max_per_txd); |
@@ -2735,7 +2734,11 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
2735 | buffer_info->length = size; | 2734 | buffer_info->length = size; |
2736 | /* set time_stamp *before* dma to help avoid a possible race */ | 2735 | /* set time_stamp *before* dma to help avoid a possible race */ |
2737 | buffer_info->time_stamp = jiffies; | 2736 | buffer_info->time_stamp = jiffies; |
2738 | buffer_info->dma = skb_shinfo(skb)->dma_head + offset; | 2737 | buffer_info->mapped_as_page = false; |
2738 | buffer_info->dma = pci_map_single(pdev, skb->data + offset, | ||
2739 | size, PCI_DMA_TODEVICE); | ||
2740 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) | ||
2741 | goto dma_error; | ||
2739 | buffer_info->next_to_watch = i; | 2742 | buffer_info->next_to_watch = i; |
2740 | 2743 | ||
2741 | len -= size; | 2744 | len -= size; |
@@ -2753,7 +2756,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
2753 | 2756 | ||
2754 | frag = &skb_shinfo(skb)->frags[f]; | 2757 | frag = &skb_shinfo(skb)->frags[f]; |
2755 | len = frag->size; | 2758 | len = frag->size; |
2756 | offset = 0; | 2759 | offset = frag->page_offset; |
2757 | 2760 | ||
2758 | while (len) { | 2761 | while (len) { |
2759 | i++; | 2762 | i++; |
@@ -2777,7 +2780,12 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
2777 | 2780 | ||
2778 | buffer_info->length = size; | 2781 | buffer_info->length = size; |
2779 | buffer_info->time_stamp = jiffies; | 2782 | buffer_info->time_stamp = jiffies; |
2780 | buffer_info->dma = map[f] + offset; | 2783 | buffer_info->mapped_as_page = true; |
2784 | buffer_info->dma = pci_map_page(pdev, frag->page, | ||
2785 | offset, size, | ||
2786 | PCI_DMA_TODEVICE); | ||
2787 | if (pci_dma_mapping_error(pdev, buffer_info->dma)) | ||
2788 | goto dma_error; | ||
2781 | buffer_info->next_to_watch = i; | 2789 | buffer_info->next_to_watch = i; |
2782 | 2790 | ||
2783 | len -= size; | 2791 | len -= size; |
@@ -2790,6 +2798,22 @@ static int e1000_tx_map(struct e1000_adapter *adapter, | |||
2790 | tx_ring->buffer_info[first].next_to_watch = i; | 2798 | tx_ring->buffer_info[first].next_to_watch = i; |
2791 | 2799 | ||
2792 | return count; | 2800 | return count; |
2801 | |||
2802 | dma_error: | ||
2803 | dev_err(&pdev->dev, "TX DMA map failed\n"); | ||
2804 | buffer_info->dma = 0; | ||
2805 | count--; | ||
2806 | |||
2807 | while (count >= 0) { | ||
2808 | count--; | ||
2809 | i--; | ||
2810 | if (i < 0) | ||
2811 | i += tx_ring->count; | ||
2812 | buffer_info = &tx_ring->buffer_info[i]; | ||
2813 | e1000_unmap_and_free_tx_resource(adapter, buffer_info); | ||
2814 | } | ||
2815 | |||
2816 | return 0; | ||
2793 | } | 2817 | } |
2794 | 2818 | ||
2795 | static void e1000_tx_queue(struct e1000_adapter *adapter, | 2819 | static void e1000_tx_queue(struct e1000_adapter *adapter, |