diff options
author | Michael Weiser <michael.weiser@gmx.de> | 2016-11-14 18:58:05 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-11-15 22:05:54 -0500 |
commit | f8be0d78be6e7f199116a5e644ee20ff0ce413f7 (patch) | |
tree | fa9e10e4e41ea2a86c6a165532452896997f277d /drivers/net/ethernet/stmicro/stmmac/descs_com.h | |
parent | 4780566784b3968ab9fd6cc94bab72421813f004 (diff) | |
download | linux-f8be0d78be6e7f199116a5e644ee20ff0ce413f7.tar.bz2 |
net: ethernet: stmmac: change dma descriptors to __le32
The stmmac driver does not take into account the processor may be big
endian when writing the DMA descriptors. This causes the ethernet
interface not to be initialised correctly when running a big-endian
kernel. Change the descriptors for DMA to use __le32 and ensure they are
suitably swapped before writing. Tested successfully on the
Cubieboard2.
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: netdev@vger.kernel.org
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/descs_com.h')
-rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/descs_com.h | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/descs_com.h b/drivers/net/ethernet/stmicro/stmmac/descs_com.h index 7635a464ce41..1d181e205d6e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/descs_com.h +++ b/drivers/net/ethernet/stmicro/stmmac/descs_com.h @@ -35,47 +35,50 @@ /* Enhanced descriptors */ static inline void ehn_desc_rx_set_on_ring(struct dma_desc *p, int end) { - p->des1 |= ((BUF_SIZE_8KiB - 1) << ERDES1_BUFFER2_SIZE_SHIFT) - & ERDES1_BUFFER2_SIZE_MASK; + p->des1 |= cpu_to_le32(((BUF_SIZE_8KiB - 1) + << ERDES1_BUFFER2_SIZE_SHIFT) + & ERDES1_BUFFER2_SIZE_MASK); if (end) - p->des1 |= ERDES1_END_RING; + p->des1 |= cpu_to_le32(ERDES1_END_RING); } static inline void enh_desc_end_tx_desc_on_ring(struct dma_desc *p, int end) { if (end) - p->des0 |= ETDES0_END_RING; + p->des0 |= cpu_to_le32(ETDES0_END_RING); else - p->des0 &= ~ETDES0_END_RING; + p->des0 &= cpu_to_le32(~ETDES0_END_RING); } static inline void enh_set_tx_desc_len_on_ring(struct dma_desc *p, int len) { if (unlikely(len > BUF_SIZE_4KiB)) { - p->des1 |= (((len - BUF_SIZE_4KiB) << ETDES1_BUFFER2_SIZE_SHIFT) + p->des1 |= cpu_to_le32((((len - BUF_SIZE_4KiB) + << ETDES1_BUFFER2_SIZE_SHIFT) & ETDES1_BUFFER2_SIZE_MASK) | (BUF_SIZE_4KiB - & ETDES1_BUFFER1_SIZE_MASK); + & ETDES1_BUFFER1_SIZE_MASK)); } else - p->des1 |= (len & ETDES1_BUFFER1_SIZE_MASK); + p->des1 |= cpu_to_le32((len & ETDES1_BUFFER1_SIZE_MASK)); } /* Normal descriptors */ static inline void ndesc_rx_set_on_ring(struct dma_desc *p, int end) { - p->des1 |= ((BUF_SIZE_2KiB - 1) << RDES1_BUFFER2_SIZE_SHIFT) - & RDES1_BUFFER2_SIZE_MASK; + p->des1 |= cpu_to_le32(((BUF_SIZE_2KiB - 1) + << RDES1_BUFFER2_SIZE_SHIFT) + & RDES1_BUFFER2_SIZE_MASK); if (end) - p->des1 |= RDES1_END_RING; + p->des1 |= cpu_to_le32(RDES1_END_RING); } static inline void ndesc_end_tx_desc_on_ring(struct dma_desc *p, int end) { if (end) - p->des1 |= TDES1_END_RING; + p->des1 |= cpu_to_le32(TDES1_END_RING); else - p->des1 &= ~TDES1_END_RING; + p->des1 &= cpu_to_le32(~TDES1_END_RING); } static inline void norm_set_tx_desc_len_on_ring(struct dma_desc *p, int len) @@ -83,10 +86,11 @@ static inline void norm_set_tx_desc_len_on_ring(struct dma_desc *p, int len) if (unlikely(len > BUF_SIZE_2KiB)) { unsigned int buffer1 = (BUF_SIZE_2KiB - 1) & TDES1_BUFFER1_SIZE_MASK; - p->des1 |= ((((len - buffer1) << TDES1_BUFFER2_SIZE_SHIFT) - & TDES1_BUFFER2_SIZE_MASK) | buffer1); + p->des1 |= cpu_to_le32((((len - buffer1) + << TDES1_BUFFER2_SIZE_SHIFT) + & TDES1_BUFFER2_SIZE_MASK) | buffer1); } else - p->des1 |= (len & TDES1_BUFFER1_SIZE_MASK); + p->des1 |= cpu_to_le32((len & TDES1_BUFFER1_SIZE_MASK)); } /* Specific functions used for Chain mode */ @@ -94,32 +98,32 @@ static inline void norm_set_tx_desc_len_on_ring(struct dma_desc *p, int len) /* Enhanced descriptors */ static inline void ehn_desc_rx_set_on_chain(struct dma_desc *p) { - p->des1 |= ERDES1_SECOND_ADDRESS_CHAINED; + p->des1 |= cpu_to_le32(ERDES1_SECOND_ADDRESS_CHAINED); } static inline void enh_desc_end_tx_desc_on_chain(struct dma_desc *p) { - p->des0 |= ETDES0_SECOND_ADDRESS_CHAINED; + p->des0 |= cpu_to_le32(ETDES0_SECOND_ADDRESS_CHAINED); } static inline void enh_set_tx_desc_len_on_chain(struct dma_desc *p, int len) { - p->des1 |= (len & ETDES1_BUFFER1_SIZE_MASK); + p->des1 |= cpu_to_le32(len & ETDES1_BUFFER1_SIZE_MASK); } /* Normal descriptors */ static inline void ndesc_rx_set_on_chain(struct dma_desc *p, int end) { - p->des1 |= RDES1_SECOND_ADDRESS_CHAINED; + p->des1 |= cpu_to_le32(RDES1_SECOND_ADDRESS_CHAINED); } static inline void ndesc_tx_set_on_chain(struct dma_desc *p) { - p->des1 |= TDES1_SECOND_ADDRESS_CHAINED; + p->des1 |= cpu_to_le32(TDES1_SECOND_ADDRESS_CHAINED); } static inline void norm_set_tx_desc_len_on_chain(struct dma_desc *p, int len) { - p->des1 |= len & TDES1_BUFFER1_SIZE_MASK; + p->des1 |= cpu_to_le32(len & TDES1_BUFFER1_SIZE_MASK); } #endif /* __DESC_COM_H__ */ |