[PATCH 0/3 v5] Fixes for running a big-endian kernel on Cubieboard2

2016-11-14 Thread Michael Weiser
the following patches are what remains to be fixed in order to allow running a
big-endian kernel on the Cubieboard2.

The first patch fixes up endianness problems with DMA descriptors in
the stmmac driver preventing it from working correctly when runnning a
big-endian kernel.

The second patch adds the ability to enable diagnostic messages in the
sun4i-emac driver which were instrumental in finding the problem fixed
by patch number three: Endianness confusion caused by dual-purpose I/O
register usage in sun4i-emac.

All of these have been tested successfully on a Cubieboard2 DualCard.

Changes since v4:
- Rebased to current master
- Removed already applied patches to sunxi-mmc and sunxi-Kconfig

Changes since v3:
- Rebased sunxi-mmc patch against Ulf's mmc.git/next
- Changed Kconfig change to enable big-endian support only for sun7i
  devices

Changes since v2:
- Fixed typo in stmmac patch causing a build failure
- Added sun4i-emac patches

Changes since v1:
- Fixed checkpatch niggles
- Added respective Cc:s

Regards,
Michael

Michael Weiser (3):
  net: ethernet: stmmac: change dma descriptors to __le32
  net: ethernet: sun4i-emac: Allow to enable netif messages
  net: ethernet: sun4i-emac: Read rxhdr in CPU byte-order

 drivers/net/ethernet/allwinner/sun4i-emac.c| 25 -
 drivers/net/ethernet/stmicro/stmmac/chain_mode.c   | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/descs.h| 20 
 drivers/net/ethernet/stmicro/stmmac/descs_com.h| 48 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 60 +++---
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 48 -
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c| 39 +++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 51 +-
 9 files changed, 218 insertions(+), 183 deletions(-)

-- 
2.9.3 (Apple Git-75)



[PATCH 3/3] net: ethernet: sun4i-emac: Read rxhdr in CPU byte-order

2016-11-14 Thread Michael Weiser
The EMAC EMAC_RX_IO_DATA_REG data register is dual-purpose: On one hand
it is used to move actual packet data off the wire. This will be in
wire-format and accepted as such by higher layers such as IP. Therefore
it is correctly read as-is (i.e. raw) using readsl.

On the other hand it provides metadata about incoming transfers to the
driver such as length and checksum validation status. This data is
little-endian, always and it is interpreted by the driver. Therefore it
needs to be swapped to CPU endianness to make sense to the driver. This
is already done for the "receive header" but not rxhdr.

Read rxhdr using readl in order for sun4i-emac to work correctly when
running a big-endian kernel.

Signed-off-by: Michael Weiser <michael.wei...@gmx.de>
Cc: Maxime Ripard <maxime.rip...@free-electrons.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index cd08885..87d0b87 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -592,8 +592,7 @@ static void emac_rx(struct net_device *dev)
/* A packet ready now  & Get status/length */
good_packet = true;
 
-   emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
-   , sizeof(rxhdr));
+   rxhdr = readl(db->membase + EMAC_RX_IO_DATA_REG);
 
if (netif_msg_rx_status(db))
dev_dbg(db->dev, "rxhdr: %x\n", *((int *)()));
-- 
2.9.3 (Apple Git-75)



[PATCH 1/3] net: ethernet: stmmac: change dma descriptors to __le32

2016-11-14 Thread Michael Weiser
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.wei...@gmx.de>
Cc: Giuseppe Cavallaro <peppe.cavall...@st.com>
Cc: Alexandre Torgue <alexandre.tor...@st.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/stmicro/stmmac/chain_mode.c   | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/descs.h| 20 
 drivers/net/ethernet/stmicro/stmmac/descs_com.h| 48 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 60 +++---
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 48 -
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c| 39 +++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 51 +-
 8 files changed, 195 insertions(+), 181 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c 
b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
index b3e669a..026e8e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
@@ -34,7 +34,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int 
csum)
unsigned int entry = priv->cur_tx;
struct dma_desc *desc = priv->dma_tx + entry;
unsigned int nopaged_len = skb_headlen(skb);
-   unsigned int bmax;
+   unsigned int bmax, des2;
unsigned int i = 1, len;
 
if (priv->plat->enh_desc)
@@ -44,11 +44,12 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
 
len = nopaged_len - bmax;
 
-   desc->des2 = dma_map_single(priv->device, skb->data,
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device, skb->data,
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
/* do not close the descriptor and do not set own bit */
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
@@ -60,12 +61,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
desc = priv->dma_tx + entry;
 
if (len > bmax) {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i),
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i),
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
STMMAC_CHAIN_MODE, 1,
@@ -73,12 +75,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
len -= bmax;
i++;
} else {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i), len,
-   DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i), len,
+ DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = len;

[PATCH 2/3] net: ethernet: sun4i-emac: Allow to enable netif messages

2016-11-14 Thread Michael Weiser
sun4i-emac has the ability to print a number of diagnostic messages using
dev_dbg depending on message level settings implemented using netif_msg_*
macros. But there's no way to actually enable them.

Add the ability to switch diagnostic messages on using either a module
parameter debug or ethtool -s  msglvl .

Signed-off-by: Michael Weiser <michael.wei...@gmx.de>
Cc: Maxime Ripard <maxime.rip...@free-electrons.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 6ffdff6..cd08885 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -37,6 +37,11 @@
 
 #define EMAC_MAX_FRAME_LEN 0x0600
 
+#define EMAC_DEFAULT_MSG_ENABLE 0x
+static int debug = -1; /* defaults above */;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "debug message flags");
+
 /* Transmit timeout, default 5 seconds. */
 static int watchdog = 5000;
 module_param(watchdog, int, 0400);
@@ -225,11 +230,27 @@ static void emac_get_drvinfo(struct net_device *dev,
strlcpy(info->bus_info, dev_name(>dev), sizeof(info->bus_info));
 }
 
+static u32 emac_get_msglevel(struct net_device *dev)
+{
+   struct emac_board_info *db = netdev_priv(dev);
+
+   return db->msg_enable;
+}
+
+static void emac_set_msglevel(struct net_device *dev, u32 value)
+{
+   struct emac_board_info *db = netdev_priv(dev);
+
+   db->msg_enable = value;
+}
+
 static const struct ethtool_ops emac_ethtool_ops = {
.get_drvinfo= emac_get_drvinfo,
.get_link   = ethtool_op_get_link,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
+   .get_msglevel   = emac_get_msglevel,
+   .set_msglevel   = emac_set_msglevel,
 };
 
 static unsigned int emac_setup(struct net_device *ndev)
@@ -805,6 +826,7 @@ static int emac_probe(struct platform_device *pdev)
db->dev = >dev;
db->ndev = ndev;
db->pdev = pdev;
+   db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE);
 
spin_lock_init(>lock);
 
-- 
2.9.3 (Apple Git-75)



[PATCH 1/5] net: ethernet: stmmac: change dma descriptors to __le32

2016-08-22 Thread Michael Weiser
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.wei...@gmx.de>
Cc: Giuseppe Cavallaro <peppe.cavall...@st.com>
Cc: Alexandre Torgue <alexandre.tor...@st.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/stmicro/stmmac/chain_mode.c   | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/descs.h| 20 
 drivers/net/ethernet/stmicro/stmmac/descs_com.h| 48 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 60 +++---
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 48 -
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c| 39 +++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 51 +-
 8 files changed, 195 insertions(+), 181 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c 
b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
index b3e669a..026e8e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
@@ -34,7 +34,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int 
csum)
unsigned int entry = priv->cur_tx;
struct dma_desc *desc = priv->dma_tx + entry;
unsigned int nopaged_len = skb_headlen(skb);
-   unsigned int bmax;
+   unsigned int bmax, des2;
unsigned int i = 1, len;
 
if (priv->plat->enh_desc)
@@ -44,11 +44,12 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
 
len = nopaged_len - bmax;
 
-   desc->des2 = dma_map_single(priv->device, skb->data,
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device, skb->data,
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
/* do not close the descriptor and do not set own bit */
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
@@ -60,12 +61,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
desc = priv->dma_tx + entry;
 
if (len > bmax) {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i),
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i),
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
STMMAC_CHAIN_MODE, 1,
@@ -73,12 +75,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
len -= bmax;
i++;
} else {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i), len,
-   DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i), len,
+ DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = len;

[PATCH 2/5] net: ethernet: sun4i-emac: Allow to enable netif messages

2016-08-22 Thread Michael Weiser
sun4i-emac has the ability to print a number of diagnostic messages using
dev_dbg depending on message level settings implemented using netif_msg_*
macros. But there's no way to actually enable them.

Add the ability to switch diagnostic messages on using either a module
parameter debug or ethtool -s  msglvl .

Signed-off-by: Michael Weiser <michael.wei...@gmx.de>
Cc: Maxime Ripard <maxime.rip...@free-electrons.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 6ffdff6..cd08885 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -37,6 +37,11 @@
 
 #define EMAC_MAX_FRAME_LEN 0x0600
 
+#define EMAC_DEFAULT_MSG_ENABLE 0x
+static int debug = -1; /* defaults above */;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "debug message flags");
+
 /* Transmit timeout, default 5 seconds. */
 static int watchdog = 5000;
 module_param(watchdog, int, 0400);
@@ -225,11 +230,27 @@ static void emac_get_drvinfo(struct net_device *dev,
strlcpy(info->bus_info, dev_name(>dev), sizeof(info->bus_info));
 }
 
+static u32 emac_get_msglevel(struct net_device *dev)
+{
+   struct emac_board_info *db = netdev_priv(dev);
+
+   return db->msg_enable;
+}
+
+static void emac_set_msglevel(struct net_device *dev, u32 value)
+{
+   struct emac_board_info *db = netdev_priv(dev);
+
+   db->msg_enable = value;
+}
+
 static const struct ethtool_ops emac_ethtool_ops = {
.get_drvinfo= emac_get_drvinfo,
.get_link   = ethtool_op_get_link,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
+   .get_msglevel   = emac_get_msglevel,
+   .set_msglevel   = emac_set_msglevel,
 };
 
 static unsigned int emac_setup(struct net_device *ndev)
@@ -805,6 +826,7 @@ static int emac_probe(struct platform_device *pdev)
db->dev = >dev;
db->ndev = ndev;
db->pdev = pdev;
+   db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE);
 
spin_lock_init(>lock);
 
-- 
2.9.2



[PATCH 3/5] net: ethernet: sun4i-emac: Read rxhdr in CPU byte-order

2016-08-22 Thread Michael Weiser
The EMAC EMAC_RX_IO_DATA_REG data register is dual-purpose: On one hand
it is used to move actual packet data off the wire. This will be in
wire-format and accepted as such by higher layers such as IP. Therefore
it is correctly read as-is (i.e. raw) using readsl.

On the other hand it provides metadata about incoming transfers to the
driver such as length and checksum validation status. This data is
little-endian, always and it is interpreted by the driver. Therefore it
needs to be swapped to CPU endianness to make sense to the driver. This
is already done for the "receive header" but not rxhdr.

Read rxhdr using readl in order for sun4i-emac to work correctly when
running a big-endian kernel.

Signed-off-by: Michael Weiser <michael.wei...@gmx.de>
Cc: Maxime Ripard <maxime.rip...@free-electrons.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index cd08885..87d0b87 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -592,8 +592,7 @@ static void emac_rx(struct net_device *dev)
/* A packet ready now  & Get status/length */
good_packet = true;
 
-   emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
-   , sizeof(rxhdr));
+   rxhdr = readl(db->membase + EMAC_RX_IO_DATA_REG);
 
if (netif_msg_rx_status(db))
dev_dbg(db->dev, "rxhdr: %x\n", *((int *)()));
-- 
2.9.2



[PATCH 2/5] net: ethernet: stmmac: change dma descriptors to __le32

2016-08-02 Thread Michael Weiser
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.wei...@gmx.de>
Cc: Giuseppe Cavallaro <peppe.cavall...@st.com>
Cc: Alexandre Torgue <alexandre.tor...@st.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/stmicro/stmmac/chain_mode.c   | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/descs.h| 20 
 drivers/net/ethernet/stmicro/stmmac/descs_com.h| 48 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 60 +++---
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 48 -
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c| 39 +++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 51 +-
 8 files changed, 195 insertions(+), 181 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c 
b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
index b3e669a..026e8e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
@@ -34,7 +34,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int 
csum)
unsigned int entry = priv->cur_tx;
struct dma_desc *desc = priv->dma_tx + entry;
unsigned int nopaged_len = skb_headlen(skb);
-   unsigned int bmax;
+   unsigned int bmax, des2;
unsigned int i = 1, len;
 
if (priv->plat->enh_desc)
@@ -44,11 +44,12 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
 
len = nopaged_len - bmax;
 
-   desc->des2 = dma_map_single(priv->device, skb->data,
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device, skb->data,
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
/* do not close the descriptor and do not set own bit */
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
@@ -60,12 +61,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
desc = priv->dma_tx + entry;
 
if (len > bmax) {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i),
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i),
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
STMMAC_CHAIN_MODE, 1,
@@ -73,12 +75,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
len -= bmax;
i++;
} else {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i), len,
-   DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i), len,
+ DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = len;

[PATCH 3/5] net: ethernet: sun4i-emac: Allow to enable netif messages

2016-08-02 Thread Michael Weiser
sun4i-emac has the ability to print a number of diagnostic messages using
dev_dbg depending on message level settings implemented using netif_msg_*
macros. But there's no way to actually enable them.

Add the ability to switch diagnostic messages on using either a module
parameter debug or ethtool -s  msglvl .

Signed-off-by: Michael Weiser <michael.wei...@gmx.de>
Cc: Maxime Ripard <maxime.rip...@free-electrons.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index 6ffdff6..cd08885 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -37,6 +37,11 @@
 
 #define EMAC_MAX_FRAME_LEN 0x0600
 
+#define EMAC_DEFAULT_MSG_ENABLE 0x
+static int debug = -1; /* defaults above */;
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "debug message flags");
+
 /* Transmit timeout, default 5 seconds. */
 static int watchdog = 5000;
 module_param(watchdog, int, 0400);
@@ -225,11 +230,27 @@ static void emac_get_drvinfo(struct net_device *dev,
strlcpy(info->bus_info, dev_name(>dev), sizeof(info->bus_info));
 }
 
+static u32 emac_get_msglevel(struct net_device *dev)
+{
+   struct emac_board_info *db = netdev_priv(dev);
+
+   return db->msg_enable;
+}
+
+static void emac_set_msglevel(struct net_device *dev, u32 value)
+{
+   struct emac_board_info *db = netdev_priv(dev);
+
+   db->msg_enable = value;
+}
+
 static const struct ethtool_ops emac_ethtool_ops = {
.get_drvinfo= emac_get_drvinfo,
.get_link   = ethtool_op_get_link,
.get_link_ksettings = phy_ethtool_get_link_ksettings,
.set_link_ksettings = phy_ethtool_set_link_ksettings,
+   .get_msglevel   = emac_get_msglevel,
+   .set_msglevel   = emac_set_msglevel,
 };
 
 static unsigned int emac_setup(struct net_device *ndev)
@@ -805,6 +826,7 @@ static int emac_probe(struct platform_device *pdev)
db->dev = >dev;
db->ndev = ndev;
db->pdev = pdev;
+   db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE);
 
spin_lock_init(>lock);
 
-- 
2.9.2



[PATCH 4/5] net: ethernet: sun4i-emac: Read rxhdr in CPU byte-order

2016-08-02 Thread Michael Weiser
The EMAC EMAC_RX_IO_DATA_REG data register is dual-purpose: On one hand
it is used to move actual packet data off the wire. This will be in
wire-format and accepted as such by higher layers such as IP. Therefore
it is correctly read as-is (i.e. raw) using readsl.

On the other hand it provides metadata about incoming transfers to the
driver such as length and checksum validation status. This data is
little-endian, always and it is interpreted by the driver. Therefore it
needs to be swapped to CPU endianness to make sense to the driver. This
is already done for the "receive header" but not rxhdr.

Read rxhdr using readl in order for sun4i-emac to work correctly when
running a big-endian kernel.

Signed-off-by: Michael Weiser <michael.wei...@gmx.de>
Cc: Maxime Ripard <maxime.rip...@free-electrons.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/allwinner/sun4i-emac.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c 
b/drivers/net/ethernet/allwinner/sun4i-emac.c
index cd08885..87d0b87 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -592,8 +592,7 @@ static void emac_rx(struct net_device *dev)
/* A packet ready now  & Get status/length */
good_packet = true;
 
-   emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
-   , sizeof(rxhdr));
+   rxhdr = readl(db->membase + EMAC_RX_IO_DATA_REG);
 
if (netif_msg_rx_status(db))
dev_dbg(db->dev, "rxhdr: %x\n", *((int *)()));
-- 
2.9.2



Re: [PATCH 2/3] stmmac: change dma descriptors to __le32

2016-07-29 Thread Michael Weiser
Hi Giuseppe,

On Tue, Jul 26, 2016 at 02:13:45PM +0200, Giuseppe CAVALLARO wrote:

> > -   ep++;
> > +   ep++);
> there is a build problem here.
> Pls fix it.

Thanks for your review. I've got it fixed locally. An updated patchset
will be forthcoming as soon as I've sorted a problem with sun4i-emac
which I've been asked to look into as well.
-- 
Thanks,
Michael


[PATCH 2/3] stmmac: change dma descriptors to __le32

2016-07-21 Thread Michael Weiser
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.wei...@gmx.de>
Cc: Giuseppe Cavallaro <peppe.cavall...@st.com>
Cc: Alexandre Torgue <alexandre.tor...@st.com>
Cc: netdev@vger.kernel.org
---
 drivers/net/ethernet/stmicro/stmmac/chain_mode.c   | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/descs.h| 20 
 drivers/net/ethernet/stmicro/stmmac/descs_com.h| 48 +
 drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c | 60 +++---
 drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 55 ++--
 drivers/net/ethernet/stmicro/stmmac/norm_desc.c| 48 -
 drivers/net/ethernet/stmicro/stmmac/ring_mode.c| 39 +++---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c  | 53 ++-
 8 files changed, 196 insertions(+), 182 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c 
b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
index b3e669a..026e8e9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
@@ -34,7 +34,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int 
csum)
unsigned int entry = priv->cur_tx;
struct dma_desc *desc = priv->dma_tx + entry;
unsigned int nopaged_len = skb_headlen(skb);
-   unsigned int bmax;
+   unsigned int bmax, des2;
unsigned int i = 1, len;
 
if (priv->plat->enh_desc)
@@ -44,11 +44,12 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
 
len = nopaged_len - bmax;
 
-   desc->des2 = dma_map_single(priv->device, skb->data,
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device, skb->data,
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
/* do not close the descriptor and do not set own bit */
priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
@@ -60,12 +61,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
desc = priv->dma_tx + entry;
 
if (len > bmax) {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i),
-   bmax, DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i),
+ bmax, DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = bmax;
priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
STMMAC_CHAIN_MODE, 1,
@@ -73,12 +75,13 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, 
int csum)
len -= bmax;
i++;
} else {
-   desc->des2 = dma_map_single(priv->device,
-   (skb->data + bmax * i), len,
-   DMA_TO_DEVICE);
-   if (dma_mapping_error(priv->device, desc->des2))
+   des2 = dma_map_single(priv->device,
+ (skb->data + bmax * i), len,
+ DMA_TO_DEVICE);
+   desc->des2 = cpu_to_le32(des2);
+   if (dma_mapping_error(priv->device, des2))
return -1;
-   priv->tx_skbuff_dma[entry].buf = desc->des2;
+   priv->tx_skbuff_dma[entry].buf = des2;
priv->tx_skbuff_dma[entry].len = len;