diff options
| -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 | ||
