summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
diff options
context:
space:
mode:
authorMichael Weiser <michael.weiser@gmx.de>2016-11-14 18:58:05 +0100
committerDavid S. Miller <davem@davemloft.net>2016-11-15 22:05:54 -0500
commitf8be0d78be6e7f199116a5e644ee20ff0ce413f7 (patch)
treefa9e10e4e41ea2a86c6a165532452896997f277d /drivers/net/ethernet/stmicro/stmmac/norm_desc.c
parent4780566784b3968ab9fd6cc94bab72421813f004 (diff)
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/norm_desc.c')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/norm_desc.c48
1 files changed, 25 insertions, 23 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
index 2beacd0d3043..fd78406e2e9a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
@@ -30,8 +30,8 @@ static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
struct dma_desc *p, void __iomem *ioaddr)
{
struct net_device_stats *stats = (struct net_device_stats *)data;
- unsigned int tdes0 = p->des0;
- unsigned int tdes1 = p->des1;
+ unsigned int tdes0 = le32_to_cpu(p->des0);
+ unsigned int tdes1 = le32_to_cpu(p->des1);
int ret = tx_done;
/* Get tx owner first */
@@ -77,7 +77,7 @@ static int ndesc_get_tx_status(void *data, struct stmmac_extra_stats *x,
static int ndesc_get_tx_len(struct dma_desc *p)
{
- return (p->des1 & RDES1_BUFFER1_SIZE_MASK);
+ return (le32_to_cpu(p->des1) & RDES1_BUFFER1_SIZE_MASK);
}
/* This function verifies if each incoming frame has some errors
@@ -88,7 +88,7 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x,
struct dma_desc *p)
{
int ret = good_frame;
- unsigned int rdes0 = p->des0;
+ unsigned int rdes0 = le32_to_cpu(p->des0);
struct net_device_stats *stats = (struct net_device_stats *)data;
if (unlikely(rdes0 & RDES0_OWN))
@@ -141,8 +141,8 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x,
static void ndesc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, int mode,
int end)
{
- p->des0 |= RDES0_OWN;
- p->des1 |= (BUF_SIZE_2KiB - 1) & RDES1_BUFFER1_SIZE_MASK;
+ p->des0 |= cpu_to_le32(RDES0_OWN);
+ p->des1 |= cpu_to_le32((BUF_SIZE_2KiB - 1) & RDES1_BUFFER1_SIZE_MASK);
if (mode == STMMAC_CHAIN_MODE)
ndesc_rx_set_on_chain(p, end);
@@ -150,12 +150,12 @@ static void ndesc_init_rx_desc(struct dma_desc *p, int disable_rx_ic, int mode,
ndesc_rx_set_on_ring(p, end);
if (disable_rx_ic)
- p->des1 |= RDES1_DISABLE_IC;
+ p->des1 |= cpu_to_le32(RDES1_DISABLE_IC);
}
static void ndesc_init_tx_desc(struct dma_desc *p, int mode, int end)
{
- p->des0 &= ~TDES0_OWN;
+ p->des0 &= cpu_to_le32(~TDES0_OWN);
if (mode == STMMAC_CHAIN_MODE)
ndesc_tx_set_on_chain(p);
else
@@ -164,27 +164,27 @@ static void ndesc_init_tx_desc(struct dma_desc *p, int mode, int end)
static int ndesc_get_tx_owner(struct dma_desc *p)
{
- return (p->des0 & TDES0_OWN) >> 31;
+ return (le32_to_cpu(p->des0) & TDES0_OWN) >> 31;
}
static void ndesc_set_tx_owner(struct dma_desc *p)
{
- p->des0 |= TDES0_OWN;
+ p->des0 |= cpu_to_le32(TDES0_OWN);
}
static void ndesc_set_rx_owner(struct dma_desc *p)
{
- p->des0 |= RDES0_OWN;
+ p->des0 |= cpu_to_le32(RDES0_OWN);
}
static int ndesc_get_tx_ls(struct dma_desc *p)
{
- return (p->des1 & TDES1_LAST_SEGMENT) >> 30;
+ return (le32_to_cpu(p->des1) & TDES1_LAST_SEGMENT) >> 30;
}
static void ndesc_release_tx_desc(struct dma_desc *p, int mode)
{
- int ter = (p->des1 & TDES1_END_RING) >> 25;
+ int ter = (le32_to_cpu(p->des1) & TDES1_END_RING) >> 25;
memset(p, 0, offsetof(struct dma_desc, des2));
if (mode == STMMAC_CHAIN_MODE)
@@ -197,7 +197,7 @@ static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
bool csum_flag, int mode, bool tx_own,
bool ls)
{
- unsigned int tdes1 = p->des1;
+ unsigned int tdes1 = le32_to_cpu(p->des1);
if (is_fs)
tdes1 |= TDES1_FIRST_SEGMENT;
@@ -212,7 +212,7 @@ static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
if (ls)
tdes1 |= TDES1_LAST_SEGMENT;
- p->des1 = tdes1;
+ p->des1 = cpu_to_le32(tdes1);
if (mode == STMMAC_CHAIN_MODE)
norm_set_tx_desc_len_on_chain(p, len);
@@ -220,12 +220,12 @@ static void ndesc_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
norm_set_tx_desc_len_on_ring(p, len);
if (tx_own)
- p->des0 |= TDES0_OWN;
+ p->des0 |= cpu_to_le32(TDES0_OWN);
}
static void ndesc_set_tx_ic(struct dma_desc *p)
{
- p->des1 |= TDES1_INTERRUPT;
+ p->des1 |= cpu_to_le32(TDES1_INTERRUPT);
}
static int ndesc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
@@ -241,19 +241,20 @@ static int ndesc_get_rx_frame_len(struct dma_desc *p, int rx_coe_type)
if (rx_coe_type == STMMAC_RX_COE_TYPE1)
csum = 2;
- return (((p->des0 & RDES0_FRAME_LEN_MASK) >> RDES0_FRAME_LEN_SHIFT) -
+ return (((le32_to_cpu(p->des0) & RDES0_FRAME_LEN_MASK)
+ >> RDES0_FRAME_LEN_SHIFT) -
csum);
}
static void ndesc_enable_tx_timestamp(struct dma_desc *p)
{
- p->des1 |= TDES1_TIME_STAMP_ENABLE;
+ p->des1 |= cpu_to_le32(TDES1_TIME_STAMP_ENABLE);
}
static int ndesc_get_tx_timestamp_status(struct dma_desc *p)
{
- return (p->des0 & TDES0_TIME_STAMP_STATUS) >> 17;
+ return (le32_to_cpu(p->des0) & TDES0_TIME_STAMP_STATUS) >> 17;
}
static u64 ndesc_get_timestamp(void *desc, u32 ats)
@@ -261,9 +262,9 @@ static u64 ndesc_get_timestamp(void *desc, u32 ats)
struct dma_desc *p = (struct dma_desc *)desc;
u64 ns;
- ns = p->des2;
+ ns = le32_to_cpu(p->des2);
/* convert high/sec time stamp value to nanosecond */
- ns += p->des3 * 1000000000ULL;
+ ns += le32_to_cpu(p->des3) * 1000000000ULL;
return ns;
}
@@ -272,7 +273,8 @@ static int ndesc_get_rx_timestamp_status(void *desc, u32 ats)
{
struct dma_desc *p = (struct dma_desc *)desc;
- if ((p->des2 == 0xffffffff) && (p->des3 == 0xffffffff))
+ if ((le32_to_cpu(p->des2) == 0xffffffff) &&
+ (le32_to_cpu(p->des3) == 0xffffffff))
/* timestamp is corrupted, hence don't store it */
return 0;
else