Re: [PATCH] net: nixge: Add support for 64-bit platforms

2018-08-18 Thread David Miller
From: Moritz Fischer 
Date: Thu, 16 Aug 2018 12:07:06 -0700

> Add support for 64-bit platforms to driver.
> 
> The hardware only supports 32-bit register accesses
> so the accesses need to be split up into two writes
> when setting the current and tail descriptor values.
> 
> Cc: Florian Fainelli 
> Signed-off-by: Moritz Fischer 

Please resubmit when the net-next tree opens back up.

Thank you.


[PATCH] net: nixge: Add support for 64-bit platforms

2018-08-16 Thread Moritz Fischer
Add support for 64-bit platforms to driver.

The hardware only supports 32-bit register accesses
so the accesses need to be split up into two writes
when setting the current and tail descriptor values.

Cc: Florian Fainelli 
Signed-off-by: Moritz Fischer 
---

Changes from RFC:
- Work around warning when building by casting dma_addr to (u64)
  when netdev_err() printing it
- Use nixge_hw_dma_bd_set_{offset,phys} to zero out descs
- change KConfig from depends on ARCH_ZYNQ to "depends on HAS_IOMEM &&
  HAS_DMA"

---
 drivers/net/ethernet/ni/Kconfig |   3 +-
 drivers/net/ethernet/ni/nixge.c | 168 ++--
 2 files changed, 116 insertions(+), 55 deletions(-)

diff --git a/drivers/net/ethernet/ni/Kconfig b/drivers/net/ethernet/ni/Kconfig
index aa41e5f6e437..04e315704f71 100644
--- a/drivers/net/ethernet/ni/Kconfig
+++ b/drivers/net/ethernet/ni/Kconfig
@@ -18,8 +18,9 @@ if NET_VENDOR_NI
 
 config NI_XGE_MANAGEMENT_ENET
tristate "National Instruments XGE management enet support"
-   depends on ARCH_ZYNQ
+   depends on HAS_IOMEM && HAS_DMA
select PHYLIB
+   select OF_MDIO
help
  Simple LAN device for debug or management purposes. Can
  support either 10G or 1G PHYs via SFP+ ports.
diff --git a/drivers/net/ethernet/ni/nixge.c b/drivers/net/ethernet/ni/nixge.c
index 76efed058f33..74cf52e3fb09 100644
--- a/drivers/net/ethernet/ni/nixge.c
+++ b/drivers/net/ethernet/ni/nixge.c
@@ -106,10 +106,10 @@
(NIXGE_JUMBO_MTU + NIXGE_HDR_SIZE + NIXGE_TRL_SIZE)
 
 struct nixge_hw_dma_bd {
-   u32 next;
-   u32 reserved1;
-   u32 phys;
-   u32 reserved2;
+   u32 next_lo;
+   u32 next_hi;
+   u32 phys_lo;
+   u32 phys_hi;
u32 reserved3;
u32 reserved4;
u32 cntrl;
@@ -119,11 +119,39 @@ struct nixge_hw_dma_bd {
u32 app2;
u32 app3;
u32 app4;
-   u32 sw_id_offset;
-   u32 reserved5;
+   u32 sw_id_offset_lo;
+   u32 sw_id_offset_hi;
u32 reserved6;
 };
 
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+#define nixge_hw_dma_bd_set_addr(bd, field, addr) \
+   do { \
+   (bd)->field##_lo = lower_32_bits(((u64)addr)); \
+   (bd)->field##_hi = upper_32_bits(((u64)addr)); \
+   } while (0)
+#else
+#define nixge_hw_dma_bd_set_addr(bd, field, addr) \
+   ((bd)->field##_lo = lower_32_bits((addr)))
+#endif
+
+#define nixge_hw_dma_bd_set_phys(bd, addr) \
+   nixge_hw_dma_bd_set_addr((bd), phys, (addr))
+
+#define nixge_hw_dma_bd_set_next(bd, addr) \
+   nixge_hw_dma_bd_set_addr((bd), next, (addr))
+
+#define nixge_hw_dma_bd_set_offset(bd, addr) \
+   nixge_hw_dma_bd_set_addr((bd), sw_id_offset, (addr))
+
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+#define nixge_hw_dma_bd_get_addr(bd, field) \
+   (dma_addr_t)u64)(bd)->field##_hi) << 32) | ((bd)->field##_lo))
+#else
+#define nixge_hw_dma_bd_get_addr(bd, field) \
+   (dma_addr_t)((bd)->field##_lo)
+#endif
+
 struct nixge_tx_skb {
struct sk_buff *skb;
dma_addr_t mapping;
@@ -176,6 +204,15 @@ static void nixge_dma_write_reg(struct nixge_priv *priv, 
off_t offset, u32 val)
writel(val, priv->dma_regs + offset);
 }
 
+static void nixge_dma_write_desc_reg(struct nixge_priv *priv, off_t offset,
+dma_addr_t addr)
+{
+   writel(lower_32_bits(addr), priv->dma_regs + offset);
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+   writel(upper_32_bits(addr), priv->dma_regs + offset + 4);
+#endif
+}
+
 static u32 nixge_dma_read_reg(const struct nixge_priv *priv, off_t offset)
 {
return readl(priv->dma_regs + offset);
@@ -202,13 +239,22 @@ static u32 nixge_ctrl_read_reg(struct nixge_priv *priv, 
off_t offset)
 static void nixge_hw_dma_bd_release(struct net_device *ndev)
 {
struct nixge_priv *priv = netdev_priv(ndev);
+   dma_addr_t phys_addr;
+   struct sk_buff *skb;
int i;
 
for (i = 0; i < RX_BD_NUM; i++) {
-   dma_unmap_single(ndev->dev.parent, priv->rx_bd_v[i].phys,
-NIXGE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE);
-   dev_kfree_skb((struct sk_buff *)
- (priv->rx_bd_v[i].sw_id_offset));
+   phys_addr = nixge_hw_dma_bd_get_addr(>rx_bd_v[i],
+phys);
+
+   dma_unmap_single(ndev->dev.parent, phys_addr,
+NIXGE_MAX_JUMBO_FRAME_SIZE,
+DMA_FROM_DEVICE);
+
+   skb = (struct sk_buff *)
+   nixge_hw_dma_bd_get_addr(>rx_bd_v[i],
+sw_id_offset);
+   dev_kfree_skb(skb);
}
 
if (priv->rx_bd_v)
@@ -231,6 +277,7 @@ static int nixge_hw_dma_bd_init(struct net_device *ndev)
 {
struct nixge_priv *priv = netdev_priv(ndev);
struct sk_buff *skb;
+   dma_addr_t phys;
u32 cr;