diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 3dad7e884952..088136b37ebe 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -6605,6 +6605,9 @@ static inline void rtl8169_mark_to_asic(struct RxDesc *desc, u32 rx_buf_sz) | |||
6605 | { | 6605 | { |
6606 | u32 eor = le32_to_cpu(desc->opts1) & RingEnd; | 6606 | u32 eor = le32_to_cpu(desc->opts1) & RingEnd; |
6607 | 6607 | ||
6608 | /* Force memory writes to complete before releasing descriptor */ | ||
6609 | dma_wmb(); | ||
6610 | |||
6608 | desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz); | 6611 | desc->opts1 = cpu_to_le32(DescOwn | eor | rx_buf_sz); |
6609 | } | 6612 | } |
6610 | 6613 | ||
@@ -6612,7 +6615,6 @@ static inline void rtl8169_map_to_asic(struct RxDesc *desc, dma_addr_t mapping, | |||
6612 | u32 rx_buf_sz) | 6615 | u32 rx_buf_sz) |
6613 | { | 6616 | { |
6614 | desc->addr = cpu_to_le64(mapping); | 6617 | desc->addr = cpu_to_le64(mapping); |
6615 | wmb(); | ||
6616 | rtl8169_mark_to_asic(desc, rx_buf_sz); | 6618 | rtl8169_mark_to_asic(desc, rx_buf_sz); |
6617 | } | 6619 | } |
6618 | 6620 | ||
@@ -7073,16 +7075,18 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, | |||
7073 | 7075 | ||
7074 | skb_tx_timestamp(skb); | 7076 | skb_tx_timestamp(skb); |
7075 | 7077 | ||
7076 | wmb(); | 7078 | /* Force memory writes to complete before releasing descriptor */ |
7079 | dma_wmb(); | ||
7077 | 7080 | ||
7078 | /* Anti gcc 2.95.3 bugware (sic) */ | 7081 | /* Anti gcc 2.95.3 bugware (sic) */ |
7079 | status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); | 7082 | status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC)); |
7080 | txd->opts1 = cpu_to_le32(status); | 7083 | txd->opts1 = cpu_to_le32(status); |
7081 | 7084 | ||
7082 | tp->cur_tx += frags + 1; | 7085 | /* Force all memory writes to complete before notifying device */ |
7083 | |||
7084 | wmb(); | 7086 | wmb(); |
7085 | 7087 | ||
7088 | tp->cur_tx += frags + 1; | ||
7089 | |||
7086 | RTL_W8(TxPoll, NPQ); | 7090 | RTL_W8(TxPoll, NPQ); |
7087 | 7091 | ||
7088 | mmiowb(); | 7092 | mmiowb(); |
@@ -7181,11 +7185,16 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) | |||
7181 | struct ring_info *tx_skb = tp->tx_skb + entry; | 7185 | struct ring_info *tx_skb = tp->tx_skb + entry; |
7182 | u32 status; | 7186 | u32 status; |
7183 | 7187 | ||
7184 | rmb(); | ||
7185 | status = le32_to_cpu(tp->TxDescArray[entry].opts1); | 7188 | status = le32_to_cpu(tp->TxDescArray[entry].opts1); |
7186 | if (status & DescOwn) | 7189 | if (status & DescOwn) |
7187 | break; | 7190 | break; |
7188 | 7191 | ||
7192 | /* This barrier is needed to keep us from reading | ||
7193 | * any other fields out of the Tx descriptor until | ||
7194 | * we know the status of DescOwn | ||
7195 | */ | ||
7196 | dma_rmb(); | ||
7197 | |||
7189 | rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, | 7198 | rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb, |
7190 | tp->TxDescArray + entry); | 7199 | tp->TxDescArray + entry); |
7191 | if (status & LastFrag) { | 7200 | if (status & LastFrag) { |
@@ -7280,11 +7289,16 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget | |||
7280 | struct RxDesc *desc = tp->RxDescArray + entry; | 7289 | struct RxDesc *desc = tp->RxDescArray + entry; |
7281 | u32 status; | 7290 | u32 status; |
7282 | 7291 | ||
7283 | rmb(); | ||
7284 | status = le32_to_cpu(desc->opts1) & tp->opts1_mask; | 7292 | status = le32_to_cpu(desc->opts1) & tp->opts1_mask; |
7285 | |||
7286 | if (status & DescOwn) | 7293 | if (status & DescOwn) |
7287 | break; | 7294 | break; |
7295 | |||
7296 | /* This barrier is needed to keep us from reading | ||
7297 | * any other fields out of the Rx descriptor until | ||
7298 | * we know the status of DescOwn | ||
7299 | */ | ||
7300 | dma_rmb(); | ||
7301 | |||
7288 | if (unlikely(status & RxRES)) { | 7302 | if (unlikely(status & RxRES)) { |
7289 | netif_info(tp, rx_err, dev, "Rx ERROR. status = %08x\n", | 7303 | netif_info(tp, rx_err, dev, "Rx ERROR. status = %08x\n", |
7290 | status); | 7304 | status); |
@@ -7346,7 +7360,6 @@ process_pkt: | |||
7346 | } | 7360 | } |
7347 | release_descriptor: | 7361 | release_descriptor: |
7348 | desc->opts2 = 0; | 7362 | desc->opts2 = 0; |
7349 | wmb(); | ||
7350 | rtl8169_mark_to_asic(desc, rx_buf_sz); | 7363 | rtl8169_mark_to_asic(desc, rx_buf_sz); |
7351 | } | 7364 | } |
7352 | 7365 | ||