From de354c54dd9647303a071d989ad79a495024e4bf Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:01 -0800 Subject: net/e1000: Don't use coherent memory for Rx buffer In order to avoid issues on AArch64, convert the driver to use regular memory and add appropriate DMA sync calls. Drop needless (uchar *) cast while at it. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/e1000.h | 1 + drivers/net/e1000/main.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 0a9e107c07..52ad3d4cdb 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -2182,6 +2182,7 @@ struct e1000_hw { struct e1000_tx_desc *tx_base; struct e1000_rx_desc *rx_base; unsigned char *packet; + dma_addr_t packet_dma; int tx_tail; int rx_tail, rx_last; diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 0ef8fd6231..7358763f9d 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3215,7 +3215,7 @@ static void fill_rx(struct e1000_hw *hw) for (i = 0; i < 4; i++) *bla++ = 0; - rd->buffer_addr = cpu_to_le64((unsigned long)hw->packet); + rd->buffer_addr = cpu_to_le64(hw->packet_dma); e1000_write_reg(hw, E1000_RDT, hw->rx_tail); } @@ -3406,9 +3406,11 @@ static int e1000_poll(struct eth_device *edev) len = le32_to_cpu(rd->length); - dma_sync_single_for_cpu((unsigned long)hw->packet, len, DMA_FROM_DEVICE); + dma_sync_single_for_cpu(hw->packet_dma, len, DMA_FROM_DEVICE); - net_receive(edev, (uchar *)hw->packet, len); + net_receive(edev, hw->packet, len); + + dma_sync_single_for_device(hw->packet_dma, len, DMA_FROM_DEVICE); fill_rx(hw); return 1; } @@ -3561,7 +3563,6 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) hw->tx_base = dma_alloc_coherent(16 * sizeof(*hw->tx_base), DMA_ADDRESS_BROKEN); hw->rx_base = dma_alloc_coherent(16 * sizeof(*hw->rx_base), DMA_ADDRESS_BROKEN); - hw->packet = dma_alloc_coherent(4096, DMA_ADDRESS_BROKEN); edev = &hw->edev; @@ -3570,6 +3571,15 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *id) pdev->dev.priv = hw; edev->priv = hw; + hw->packet = dma_alloc(PAGE_SIZE); + if (!hw->packet) + return -ENOMEM; + + hw->packet_dma = dma_map_single(hw->dev, hw->packet, PAGE_SIZE, + DMA_FROM_DEVICE); + if (dma_mapping_error(hw->dev, hw->packet_dma)) + return -EFAULT; + hw->hw_addr = pci_iomap(pdev, 0); /* MAC and Phy settings */ -- cgit v1.2.3 From b9f7cf6677fcfb9fe162e757d347ce2099ac01fa Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:02 -0800 Subject: net/e1000: Convert e1000_transmit to use dma_map_single() Convert e1000_transmit to use dma_map_single()/dma_unmap_single(), which is more apporpirate in this case, since it will account for phys/virtual address difference as well as allow us to check for DMA mapping failure. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 7358763f9d..5ab4eb3fd7 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -36,11 +36,6 @@ tested on both gig copper and gig fiber boards #include #include "e1000.h" -static u32 inline virt_to_bus(struct pci_dev *pdev, void *adr) -{ - return (u32)adr; -} - #define PCI_VENDOR_ID_INTEL 0x8086 @@ -3420,15 +3415,20 @@ static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) struct e1000_hw *hw = edev->priv; volatile struct e1000_tx_desc *txp; uint64_t to; + dma_addr_t dma; + int ret = 0; txp = hw->tx_base + hw->tx_tail; hw->tx_tail = (hw->tx_tail + 1) % 8; - txp->buffer_addr = cpu_to_le64(virt_to_bus(hw->pdev, txpacket)); txp->lower.data = cpu_to_le32(hw->txd_cmd | length); txp->upper.data = 0; - dma_sync_single_for_device((unsigned long)txpacket, length, DMA_TO_DEVICE); + dma = dma_map_single(hw->dev, txpacket, length, DMA_TO_DEVICE); + if (dma_mapping_error(hw->dev, dma)) + return -EFAULT; + + txp->buffer_addr = cpu_to_le64(dma); e1000_write_reg(hw, E1000_TDT, hw->tx_tail); @@ -3440,11 +3440,14 @@ static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) break; if (is_timeout(to, MSECOND)) { dev_dbg(hw->dev, "e1000: tx timeout\n"); - return -ETIMEDOUT; + ret = -ETIMEDOUT; + break; } } - return 0; + dma_unmap_single(hw->dev, dma, length, DMA_TO_DEVICE); + + return ret; } static void e1000_disable(struct eth_device *edev) -- cgit v1.2.3 From eeaf317545438286f8d6b044e672fcf320de44b5 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:03 -0800 Subject: net/e1000: Fix debug print warning Cast eeprom->word_size to int, so it would match its printf specifier to avoid getting errors when building on AArch64. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/eeprom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/eeprom.c b/drivers/net/e1000/eeprom.c index c0f2db552a..36d818b3f3 100644 --- a/drivers/net/e1000/eeprom.c +++ b/drivers/net/e1000/eeprom.c @@ -1000,7 +1000,8 @@ int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, (words > eeprom->word_size - offset) || (words == 0)) { dev_dbg(hw->dev, "\"words\" parameter out of bounds." - "Words = %d, size = %d\n", offset, eeprom->word_size); + "Words = %d, size = %d\n", offset, + (int)eeprom->word_size); return -E1000_ERR_EEPROM; } -- cgit v1.2.3 From 20aa1645a30da4e8c911e28ae21d520a35f07bf9 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:04 -0800 Subject: net/e1000: Fix incorrect "Rx ready" check Due to wrong placement of parenthesis in if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) return 0; instead of checking that E1000_RXD_STAT_DD is not set, the condition ends up checking that "status" is 0. Change the code to invert the condition tested and get rid of ! entirely. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 5ab4eb3fd7..e793785e60 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3396,18 +3396,21 @@ static int e1000_poll(struct eth_device *edev) rd = hw->rx_base + hw->rx_last; - if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD) - return 0; + if (le32_to_cpu(rd->status) & E1000_RXD_STAT_DD) { + len = le32_to_cpu(rd->length); - len = le32_to_cpu(rd->length); + dma_sync_single_for_cpu(hw->packet_dma, len, + DMA_FROM_DEVICE); - dma_sync_single_for_cpu(hw->packet_dma, len, DMA_FROM_DEVICE); + net_receive(edev, hw->packet, len); - net_receive(edev, hw->packet, len); + dma_sync_single_for_device(hw->packet_dma, len, + DMA_FROM_DEVICE); + fill_rx(hw); + return 1; + } - dma_sync_single_for_device(hw->packet_dma, len, DMA_FROM_DEVICE); - fill_rx(hw); - return 1; + return 0; } static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) -- cgit v1.2.3 From e487e808b682706cba6dcf1340769528d371fb6e Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:05 -0800 Subject: net/e1000: Get rid of pointer arithmetic in e1000_poll Instead of relying on reles of pointer arithmetic (implicit multiplication by the size of pointer type), change the code to retreive address of an array elemet to clarify the intent. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index e793785e60..f13b48e0c8 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3391,11 +3391,9 @@ static void e1000_configure_rx(struct e1000_hw *hw) static int e1000_poll(struct eth_device *edev) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_rx_desc *rd; + volatile struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_last]; uint32_t len; - rd = hw->rx_base + hw->rx_last; - if (le32_to_cpu(rd->status) & E1000_RXD_STAT_DD) { len = le32_to_cpu(rd->length); -- cgit v1.2.3 From eff0435d57634bc62c9fc05ad54a8829dfec3b96 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:06 -0800 Subject: net/e1000: Improve Rx descriptor handling in e1000_poll() Drop explicit volatile specifier as well as endianness conversion by changing the code to use appropriate read*() IO accessors. While at it if fix incorrect width used for "status" (8 vs 32) and "len" (16 vs 32). Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index f13b48e0c8..b8222c7ae2 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3391,11 +3391,10 @@ static void e1000_configure_rx(struct e1000_hw *hw) static int e1000_poll(struct eth_device *edev) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_last]; - uint32_t len; + struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_last]; - if (le32_to_cpu(rd->status) & E1000_RXD_STAT_DD) { - len = le32_to_cpu(rd->length); + if (readb(&rd->status) & E1000_RXD_STAT_DD) { + const uint16_t len = readw(&rd->length); dma_sync_single_for_cpu(hw->packet_dma, len, DMA_FROM_DEVICE); -- cgit v1.2.3 From 75fa85c5856cef4b9944f6bd7f1ccec38e20e000 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:07 -0800 Subject: net/e1000: Remove pointer arithmetic in e1000_transmit() Instead of relying on reles of pointer arithmetic (implicit multiplication by the size of pointer type), change the code to retreive address of an array elemet to clarify the intent. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index b8222c7ae2..f7e26a0e58 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3413,12 +3413,11 @@ static int e1000_poll(struct eth_device *edev) static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_tx_desc *txp; + volatile struct e1000_tx_desc *txp = &hw->tx_base[hw->tx_tail]; uint64_t to; dma_addr_t dma; int ret = 0; - txp = hw->tx_base + hw->tx_tail; hw->tx_tail = (hw->tx_tail + 1) % 8; txp->lower.data = cpu_to_le32(hw->txd_cmd | length); -- cgit v1.2.3 From 2b1a27247dde23539bef23559492054f2ae63cf8 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:08 -0800 Subject: net/e1000: Improve Tx descriptor handling in e1000_transmit Drop explicit "volatile" specifier for struct e1000_tx_desc as well as explicit endiannes fix, by using little endian IO accessors (readl, writel, etc.) Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index f7e26a0e58..866d8def3d 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -35,6 +35,7 @@ tested on both gig copper and gig fiber boards #include #include #include "e1000.h" +#include #define PCI_VENDOR_ID_INTEL 0x8086 @@ -3413,29 +3414,28 @@ static int e1000_poll(struct eth_device *edev) static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) { struct e1000_hw *hw = edev->priv; - volatile struct e1000_tx_desc *txp = &hw->tx_base[hw->tx_tail]; + struct e1000_tx_desc *txp = &hw->tx_base[hw->tx_tail]; uint64_t to; dma_addr_t dma; int ret = 0; hw->tx_tail = (hw->tx_tail + 1) % 8; - txp->lower.data = cpu_to_le32(hw->txd_cmd | length); - txp->upper.data = 0; + writel(hw->txd_cmd | length, &txp->lower.data); + writel(0, &txp->upper.data); dma = dma_map_single(hw->dev, txpacket, length, DMA_TO_DEVICE); if (dma_mapping_error(hw->dev, dma)) return -EFAULT; - txp->buffer_addr = cpu_to_le64(dma); - + writeq(dma, &txp->buffer_addr); e1000_write_reg(hw, E1000_TDT, hw->tx_tail); e1000_write_flush(hw); to = get_time_ns(); while (1) { - if (le32_to_cpu(txp->upper.data) & E1000_TXD_STAT_DD) + if (readl(&txp->upper.data) & E1000_TXD_STAT_DD) break; if (is_timeout(to, MSECOND)) { dev_dbg(hw->dev, "e1000: tx timeout\n"); -- cgit v1.2.3 From a794c02e9e4f68a0e33a867d5864d7615124d376 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:09 -0800 Subject: net/e1000: Make use of readl_poll_timeout() in e1000_transmit() Simplify code of e1000_transmit() with readl_poll_timeout(). Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 866d8def3d..425d478edc 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -33,6 +33,7 @@ tested on both gig copper and gig fiber boards #include #include #include +#include #include #include "e1000.h" #include @@ -3415,9 +3416,9 @@ static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) { struct e1000_hw *hw = edev->priv; struct e1000_tx_desc *txp = &hw->tx_base[hw->tx_tail]; - uint64_t to; dma_addr_t dma; - int ret = 0; + uint32_t stat; + int ret; hw->tx_tail = (hw->tx_tail + 1) % 8; @@ -3433,16 +3434,11 @@ static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) e1000_write_flush(hw); - to = get_time_ns(); - while (1) { - if (readl(&txp->upper.data) & E1000_TXD_STAT_DD) - break; - if (is_timeout(to, MSECOND)) { - dev_dbg(hw->dev, "e1000: tx timeout\n"); - ret = -ETIMEDOUT; - break; - } - } + ret = readl_poll_timeout(&txp->upper.data, + stat, stat & E1000_TXD_STAT_DD, + MSECOND / USECOND); + if (ret) + dev_dbg(hw->dev, "e1000: tx timeout\n"); dma_unmap_single(hw->dev, dma, length, DMA_TO_DEVICE); -- cgit v1.2.3 From 351c2bd7a8bdeda30a2ef8e6d85b9f8550006686 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:10 -0800 Subject: net/e1000: Rename fill_rx() to e1000_fill_rx() Rename fill_rx() to e1000_fill_rx() to match the naming convention of other functions in the file. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 425d478edc..b728add7f3 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3198,7 +3198,7 @@ static int e1000_sw_init(struct eth_device *edev) return E1000_SUCCESS; } -static void fill_rx(struct e1000_hw *hw) +static void e1000_fill_rx(struct e1000_hw *hw) { volatile struct e1000_rx_desc *rd; volatile u32 *bla; @@ -3387,7 +3387,7 @@ static void e1000_configure_rx(struct e1000_hw *hw) e1000_write_reg(hw, E1000_RCTL, rctl); - fill_rx(hw); + e1000_fill_rx(hw); } static int e1000_poll(struct eth_device *edev) @@ -3405,7 +3405,7 @@ static int e1000_poll(struct eth_device *edev) dma_sync_single_for_device(hw->packet_dma, len, DMA_FROM_DEVICE); - fill_rx(hw); + e1000_fill_rx(hw); return 1; } -- cgit v1.2.3 From 622743555ba9a87bfca493d607db32771408e240 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:11 -0800 Subject: net/e1000: Remove pointer arithmetic from e1000_fill_rx() Instead of relying on reles of pointer arithmetic (implicit multiplication by the size of pointer type), change the code to retreive address of an array elemet to clarify the intent. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index b728add7f3..90b6d6e436 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3200,12 +3200,11 @@ static int e1000_sw_init(struct eth_device *edev) static void e1000_fill_rx(struct e1000_hw *hw) { - volatile struct e1000_rx_desc *rd; + volatile struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_tail]; volatile u32 *bla; int i; hw->rx_last = hw->rx_tail; - rd = hw->rx_base + hw->rx_tail; hw->rx_tail = (hw->rx_tail + 1) % 8; bla = (void *)rd; -- cgit v1.2.3 From bf0c10d3b76e9ebfc787d5f4768e58f812fcdd00 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:12 -0800 Subject: net/e1000: Consolidate next index calculation code Consolidate next index calculation code into a helper function and convert the code to make use of it. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 90b6d6e436..01330f5a51 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3198,6 +3198,11 @@ static int e1000_sw_init(struct eth_device *edev) return E1000_SUCCESS; } +static int e1000_bd_next_index(int index) +{ + return (index + 1) % 8; +} + static void e1000_fill_rx(struct e1000_hw *hw) { volatile struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_tail]; @@ -3205,7 +3210,7 @@ static void e1000_fill_rx(struct e1000_hw *hw) int i; hw->rx_last = hw->rx_tail; - hw->rx_tail = (hw->rx_tail + 1) % 8; + hw->rx_tail = e1000_bd_next_index(hw->rx_tail); bla = (void *)rd; for (i = 0; i < 4; i++) @@ -3419,7 +3424,7 @@ static int e1000_transmit(struct eth_device *edev, void *txpacket, int length) uint32_t stat; int ret; - hw->tx_tail = (hw->tx_tail + 1) % 8; + hw->tx_tail = e1000_bd_next_index(hw->tx_tail); writel(hw->txd_cmd | length, &txp->lower.data); writel(0, &txp->upper.data); -- cgit v1.2.3 From deec75514d975265e5e18e3bc62a43a4a3fa4174 Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:13 -0800 Subject: net/e1000: Improve RX buffer handling in e1000_fill_rx() Drop explicit "volatile" specifier for struct e1000_rx_desc, "bla" variable as well as explicit endiannes fix, by using little endian IO accessors (readl, writel, etc.) Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index 01330f5a51..c6b6906ce3 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3205,18 +3205,17 @@ static int e1000_bd_next_index(int index) static void e1000_fill_rx(struct e1000_hw *hw) { - volatile struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_tail]; - volatile u32 *bla; - int i; + struct e1000_rx_desc *rd = &hw->rx_base[hw->rx_tail]; hw->rx_last = hw->rx_tail; hw->rx_tail = e1000_bd_next_index(hw->rx_tail); - bla = (void *)rd; - for (i = 0; i < 4; i++) - *bla++ = 0; - - rd->buffer_addr = cpu_to_le64(hw->packet_dma); + writeq(hw->packet_dma, &rd->buffer_addr); + writew(0, &rd->length); + writew(0, &rd->csum); + writeb(0, &rd->status); + writeb(0, &rd->errors); + writew(0, &rd->special); e1000_write_reg(hw, E1000_RDT, hw->rx_tail); } -- cgit v1.2.3 From f7aad7be4194293e961d2a70c34f53bf1f3d58bd Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Wed, 6 Feb 2019 17:22:14 -0800 Subject: net/e1000: Do not hardcode TDBAH and RDBAH to 0 While there currently no user of e1000 driver that places those rings beyond 4GiB boundary, there's also no real reason not to initialize those registers properly. Signed-off-by: Andrey Smirnov Signed-off-by: Sascha Hauer --- drivers/net/e1000/main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000/main.c b/drivers/net/e1000/main.c index c6b6906ce3..774e3d030f 100644 --- a/drivers/net/e1000/main.c +++ b/drivers/net/e1000/main.c @@ -3232,9 +3232,10 @@ static void e1000_configure_tx(struct e1000_hw *hw) unsigned long tctl; unsigned long tipg, tarc; uint32_t ipgr1, ipgr2; + const unsigned long tx_base = (unsigned long)hw->tx_base; - e1000_write_reg(hw, E1000_TDBAL, (unsigned long)hw->tx_base); - e1000_write_reg(hw, E1000_TDBAH, 0); + e1000_write_reg(hw, E1000_TDBAL, lower_32_bits(tx_base)); + e1000_write_reg(hw, E1000_TDBAH, upper_32_bits(tx_base)); e1000_write_reg(hw, E1000_TDLEN, 128); @@ -3350,6 +3351,7 @@ static void e1000_setup_rctl(struct e1000_hw *hw) static void e1000_configure_rx(struct e1000_hw *hw) { unsigned long rctl, ctrl_ext; + const unsigned long rx_base = (unsigned long)hw->rx_base; hw->rx_tail = 0; /* make sure receives are disabled while setting up the descriptors */ @@ -3371,8 +3373,8 @@ static void e1000_configure_rx(struct e1000_hw *hw) e1000_write_flush(hw); } /* Setup the Base and Length of the Rx Descriptor Ring */ - e1000_write_reg(hw, E1000_RDBAL, (unsigned long)hw->rx_base); - e1000_write_reg(hw, E1000_RDBAH, 0); + e1000_write_reg(hw, E1000_RDBAL, lower_32_bits(rx_base)); + e1000_write_reg(hw, E1000_RDBAH, upper_32_bits(rx_base)); e1000_write_reg(hw, E1000_RDLEN, 128); -- cgit v1.2.3