diff options
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 330879004ea1..4a0102218d39 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -818,6 +818,12 @@ static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb, | |||
818 | return skb; | 818 | return skb; |
819 | } | 819 | } |
820 | 820 | ||
821 | struct ixgbe_rsc_cb { | ||
822 | dma_addr_t dma; | ||
823 | }; | ||
824 | |||
825 | #define IXGBE_RSC_CB(skb) ((struct ixgbe_rsc_cb *)(skb)->cb) | ||
826 | |||
821 | static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | 827 | static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, |
822 | struct ixgbe_ring *rx_ring, | 828 | struct ixgbe_ring *rx_ring, |
823 | int *work_done, int work_to_do) | 829 | int *work_done, int work_to_do) |
@@ -867,9 +873,21 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
867 | rx_buffer_info->skb = NULL; | 873 | rx_buffer_info->skb = NULL; |
868 | 874 | ||
869 | if (rx_buffer_info->dma) { | 875 | if (rx_buffer_info->dma) { |
870 | pci_unmap_single(pdev, rx_buffer_info->dma, | 876 | if ((adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) && |
871 | rx_ring->rx_buf_len, | 877 | (!(staterr & IXGBE_RXD_STAT_EOP)) && |
872 | PCI_DMA_FROMDEVICE); | 878 | (!(skb->prev))) |
879 | /* | ||
880 | * When HWRSC is enabled, delay unmapping | ||
881 | * of the first packet. It carries the | ||
882 | * header information, HW may still | ||
883 | * access the header after the writeback. | ||
884 | * Only unmap it when EOP is reached | ||
885 | */ | ||
886 | IXGBE_RSC_CB(skb)->dma = rx_buffer_info->dma; | ||
887 | else | ||
888 | pci_unmap_single(pdev, rx_buffer_info->dma, | ||
889 | rx_ring->rx_buf_len, | ||
890 | PCI_DMA_FROMDEVICE); | ||
873 | rx_buffer_info->dma = 0; | 891 | rx_buffer_info->dma = 0; |
874 | skb_put(skb, len); | 892 | skb_put(skb, len); |
875 | } | 893 | } |
@@ -917,6 +935,10 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, | |||
917 | if (skb->prev) | 935 | if (skb->prev) |
918 | skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count)); | 936 | skb = ixgbe_transform_rsc_queue(skb, &(rx_ring->rsc_count)); |
919 | if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { | 937 | if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { |
938 | if (IXGBE_RSC_CB(skb)->dma) | ||
939 | pci_unmap_single(pdev, IXGBE_RSC_CB(skb)->dma, | ||
940 | rx_ring->rx_buf_len, | ||
941 | PCI_DMA_FROMDEVICE); | ||
920 | if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) | 942 | if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) |
921 | rx_ring->rsc_count += skb_shinfo(skb)->nr_frags; | 943 | rx_ring->rsc_count += skb_shinfo(skb)->nr_frags; |
922 | else | 944 | else |
@@ -3104,6 +3126,10 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, | |||
3104 | rx_buffer_info->skb = NULL; | 3126 | rx_buffer_info->skb = NULL; |
3105 | do { | 3127 | do { |
3106 | struct sk_buff *this = skb; | 3128 | struct sk_buff *this = skb; |
3129 | if (IXGBE_RSC_CB(this)->dma) | ||
3130 | pci_unmap_single(pdev, IXGBE_RSC_CB(this)->dma, | ||
3131 | rx_ring->rx_buf_len, | ||
3132 | PCI_DMA_FROMDEVICE); | ||
3107 | skb = skb->prev; | 3133 | skb = skb->prev; |
3108 | dev_kfree_skb(this); | 3134 | dev_kfree_skb(this); |
3109 | } while (skb); | 3135 | } while (skb); |