aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/realtek/r8169.c29
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 }
7347release_descriptor: 7361release_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